[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: c0ab803dfd -s ours am: 60ec6cf4ea -s ours
am skip reason: subject contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/25274510
Change-Id: I788f9d706af65df9f701fabf25c736723b187365
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index b68e1e5..e658949 100644
--- a/Android.bp
+++ b/Android.bp
@@ -173,7 +173,9 @@
static_libs: [
"Launcher3ResLib",
"launcher-testing-shared",
- "animationlib"
+ "animationlib",
+ "com_android_launcher3_flags_lib",
+ "com_android_wm_shell_flags_lib",
],
sdk_version: "current",
min_sdk_version: min_launcher3_sdk_version,
@@ -244,6 +246,7 @@
"Launcher3ResLib",
"lottie",
"SystemUISharedLib",
+ "SettingsLibSettingsTheme",
"SystemUI-statsd",
"animationlib",
],
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 14605d8..7e824ec 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -67,6 +67,7 @@
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
+ android:name="com.android.launcher3.LauncherApplication"
android:fullBackupOnly="true"
android:backupInForeground="true"
android:fullBackupContent="@xml/backupscheme"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index a77791f..3d15e77 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,4 +1,6 @@
[Hook Scripts]
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --config_xml tools/checkstyle.xml --sha ${PREUPLOAD_COMMIT}
-ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check ${PREUPLOAD_FILES}
\ No newline at end of file
+ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check ${PREUPLOAD_FILES}
+
+flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PATH}
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
new file mode 100644
index 0000000..dc30a35
--- /dev/null
+++ b/aconfig/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aconfig_declarations {
+ name: "com_android_launcher3_flags",
+ package: "com.android.launcher3",
+ srcs: ["**/*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "com_android_launcher3_flags_lib",
+ aconfig_declarations: "com_android_launcher3_flags",
+}
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
new file mode 100644
index 0000000..ace2210
--- /dev/null
+++ b/aconfig/launcher.aconfig
@@ -0,0 +1,57 @@
+package: "com.android.launcher3"
+
+flag {
+ name: "enable_expanding_pause_work_button"
+ namespace: "launcher"
+ description: "Expand and collapse pause work button while scrolling."
+ bug: "270390779"
+}
+
+flag {
+ name: "enable_twoline_allapps"
+ namespace: "launcher"
+ description: "Enables two line label inside all apps."
+ bug: "270390937"
+}
+
+flag {
+ name: "enable_grid_only_overview"
+ namespace: "launcher"
+ description: "Enable a grid-only overview without a focused task."
+ bug: "257950105"
+}
+
+flag {
+ name: "enable_cursor_hover_states"
+ namespace: "launcher"
+ description: "Enables cursor hover states for certain elements."
+ bug: "243191650"
+}
+
+flag {
+ name: "enable_responsive_workspace"
+ namespace: "launcher"
+ description: "Enables new workspace grid calculations method."
+ bug: "302189128"
+}
+
+flag {
+ name: "enable_overview_icon_menu"
+ namespace: "launcher"
+ description: "Enable updated overview icon and menu within task."
+ bug: "257950105"
+}
+
+flag {
+ name: "enable_taskbar_no_recreate"
+ namespace: "launcher"
+ description: "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext."
+ bug: "299193589"
+}
+
+flag {
+ name: "enable_home_transition_listener"
+ namespace: "launcher"
+ description: "Enables launcher to listen to all transitions that include home activity"
+ bug: "306053414"
+}
diff --git a/aconfig/launcher_search.aconfig b/aconfig/launcher_search.aconfig
new file mode 100644
index 0000000..87ccec5
--- /dev/null
+++ b/aconfig/launcher_search.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.launcher3"
+
+flag {
+ name: "enable_private_space"
+ namespace: "launcher_search"
+ description: "Enables all Launcher features associated with private space."
+ bug: "306187906"
+}
diff --git a/build.gradle b/build.gradle
index 090bafe..f4d7261 100644
--- a/build.gradle
+++ b/build.gradle
@@ -157,6 +157,8 @@
withoutQuickstepImplementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/libs", include: 'plugin_core.jar')
testImplementation 'junit:junit:4.12'
+ testImplementation libs.mockitoInlineExtended
+ androidTestImplementation libs.mockitoInlineExtended
androidTestImplementation "org.mockito:mockito-core:1.9.5"
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
diff --git a/go/quickstep/res/values-am/strings.xml b/go/quickstep/res/values-am/strings.xml
index ed34797..ffc59d9 100644
--- a/go/quickstep/res/values-am/strings.xml
+++ b/go/quickstep/res/values-am/strings.xml
@@ -9,12 +9,12 @@
<string name="dialog_cancel" msgid="6464336969134856366">"ይቅር"</string>
<string name="dialog_settings" msgid="6564397136021186148">"ቅንብሮች"</string>
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"በማያ ገጹ ላይ ጽሑፍን ይተረጉሙ ወይም ያዳምጡ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"እንደ በማያ ገጽዎ ላይ ያለ ጽሁፍ፣ የድር አድራሻዎች እና ቅጽበታዊ ገጽ እይታዎች ያሉ መረጃዎች ለGoogle ሊጋሩ ይችላሉ።\n\nምን መረጃ እንደሚያጋሩ ለመቀየር ወደ "<b>"ቅንብሮች > መተግበሪያዎች > ነባሪ መተግበሪያዎች > ዲጂታል ረዳት መተግበሪያ"</b>" ይሂዱ።"</string>
+ <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"እንደ በማያ ገፅዎ ላይ ያለ ጽሁፍ፣ የድር አድራሻዎች እና ቅጽበታዊ ገፅ እይታዎች ያሉ መረጃዎች ለGoogle ሊጋሩ ይችላሉ።\n\nምን መረጃ እንደሚያጋሩ ለመቀየር ወደ "<b>"ቅንብሮች > መተግበሪያዎች > ነባሪ መተግበሪያዎች > ዲጂታል ረዳት መተግበሪያ"</b>" ይሂዱ።"</string>
<string name="assistant_not_selected_title" msgid="5017072974603345228">"ይህንን ባህሪ ለመጠቀም ረዳት ይምረጡ"</string>
<string name="assistant_not_selected_text" msgid="3244613673884359276">"በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያን ይምረጡ"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"ይህንን ባህሪ ለመጠቀም ረዳትዎን ይቀይሩ"</string>
<string name="assistant_not_supported_text" msgid="1708031078549268884">"በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያዎን ይቀይሩ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"በዚህ ማያ ገጽ ላይ ጽሁፍ ለማዳመጥ እዚህ መታ ያድርጉ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"በዚህ ማያ ገጽ ላይ ጽሁፍ ለመተርጎም እዚህ መታ ያድርጉ"</string>
+ <string name="tooltip_listen" msgid="7634466447860989102">"በዚህ ማያ ገፅ ላይ ጽሁፍ ለማዳመጥ እዚህ መታ ያድርጉ"</string>
+ <string name="tooltip_translate" msgid="4184845868901542567">"በዚህ ማያ ገፅ ላይ ጽሁፍ ለመተርጎም እዚህ መታ ያድርጉ"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ይህ መተግበሪያ ሊጋራ አይችልም"</string>
</resources>
diff --git a/go/quickstep/res/values-el/strings.xml b/go/quickstep/res/values-el/strings.xml
index 9a67420..7038c11 100644
--- a/go/quickstep/res/values-el/strings.xml
+++ b/go/quickstep/res/values-el/strings.xml
@@ -14,7 +14,7 @@
<string name="assistant_not_selected_text" msgid="3244613673884359276">"Για να ακούσετε ή να μεταφράσετε κείμενο στην οθόνη σας, επιλέξτε μια εφαρμογή ψηφιακού βοηθού στις Ρυθμίσεις."</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"Αλλάξτε τον βοηθό σας για να χρησιμοποιήσετε αυτήν τη λειτουργία"</string>
<string name="assistant_not_supported_text" msgid="1708031078549268884">"Για να ακούσετε ή να μεταφράσετε κείμενο στην οθόνη σας, αλλάξτε την εφαρμογή ψηφιακού βοηθού στις Ρυθμίσεις."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Πατήστε εδώ για να ακούσετε το κείμενο σε αυτήν την οθόνη"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Πατήστε εδώ για να μεταφράσετε το κείμενο σε αυτήν την οθόνη"</string>
+ <string name="tooltip_listen" msgid="7634466447860989102">"Πατήστε εδώ για να ακούσετε το κείμενο σε αυτή την οθόνη"</string>
+ <string name="tooltip_translate" msgid="4184845868901542567">"Πατήστε εδώ για να μεταφράσετε το κείμενο σε αυτή την οθόνη"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Δεν είναι δυνατή η κοινή χρήση της εφαρμογής"</string>
</resources>
diff --git a/go/quickstep/res/values-ky/strings.xml b/go/quickstep/res/values-ky/strings.xml
index 55e70c8..dcc1e4e 100644
--- a/go/quickstep/res/values-ky/strings.xml
+++ b/go/quickstep/res/values-ky/strings.xml
@@ -11,9 +11,9 @@
<string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Экрандагы текстти которуу же угуу"</string>
<string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Экрандагы текст, веб-даректер жана скриншоттор сыяктуу маалымат Google менен бөлүшүлүшү мүмкүн.\n\nБөлүшүлгөн маалыматты өзгөртүү үчүн"<b>"Параметрлер > Колдонмолор > Демейки колдонмолор > Санариптик жардамчы колдонмосуна өтүңүз"</b>"."</string>
<string name="assistant_not_selected_title" msgid="5017072974603345228">"Бул функцияны колдонуу үчүн жардамчыны тандаңыз"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Экраныңыздагы текстти угуу же которуу үчүн Жөндөөлөрдөн санариптик жардамчы колдонмосун тандаңыз"</string>
+ <string name="assistant_not_selected_text" msgid="3244613673884359276">"Экраныңыздагы текстти угуу же которуу үчүн Параметрлерден санариптик жардамчы колдонмосун тандаңыз"</string>
<string name="assistant_not_supported_title" msgid="1675788067597484142">"Бул функцияны колдонуу үчүн жардамчыңызды өзгөртүңүз"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Экраныңыздагы текстти угуу же которуу үчүн Жөндөөлөрдөн санариптик жардамчы колдонмосун өзгөртүңүз"</string>
+ <string name="assistant_not_supported_text" msgid="1708031078549268884">"Экраныңыздагы текстти угуу же которуу үчүн Параметрлерден санариптик жардамчы колдонмосун өзгөртүңүз"</string>
<string name="tooltip_listen" msgid="7634466447860989102">"Бул экрандагы текстти угуу үчүн бул жерди басыңыз"</string>
<string name="tooltip_translate" msgid="4184845868901542567">"Бул экрандагы текстти которуу үчүн бул жерди басыңыз"</string>
<string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Бул колдонмону бөлүшүүгө болбойт"</string>
diff --git a/go/src/com/android/launcher3/model/LauncherBinder.java b/go/src/com/android/launcher3/model/LauncherBinder.java
index 437d8ca..7a0dce8 100644
--- a/go/src/com/android/launcher3/model/LauncherBinder.java
+++ b/go/src/com/android/launcher3/model/LauncherBinder.java
@@ -38,4 +38,8 @@
@Override
public void bindWidgets() {
}
+
+ @Override
+ public void bindSmartspaceWidget() {
+ }
}
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index f8b08f8..dde69e3 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -135,7 +135,7 @@
}
}
-// Next value 52
+// Next value 53
enum Attribute {
option allow_alias = true;
@@ -188,6 +188,7 @@
ALL_APPS_SEARCH_RESULT_EDUCARD = 43;
ALL_APPS_SEARCH_RESULT_LOCATION = 50;
ALL_APPS_SEARCH_RESULT_TEXT_HEADER = 51;
+ ALL_APPS_SEARCH_RESULT_NO_FULFILLMENT = 52;
// Result sources
DATA_SOURCE_APPSEARCH_APP_PREVIEW = 45;
diff --git a/quickstep/Android.bp b/quickstep/Android.bp
index 638ce27..ec4f6fc 100644
--- a/quickstep/Android.bp
+++ b/quickstep/Android.bp
@@ -41,6 +41,7 @@
"tests/src/com/android/quickstep/TaskbarModeSwitchRule.java",
"tests/src/com/android/quickstep/NavigationModeSwitchRule.java",
"tests/src/com/android/quickstep/AbstractQuickStepTest.java",
+ "tests/src/com/android/quickstep/TaplOverviewIconTest.java",
"tests/src/com/android/quickstep/TaplTestsQuickstep.java",
"tests/src/com/android/quickstep/TaplTestsSplitscreen.java",
]
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 7c0a5ae..82f8ebe 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -30,7 +30,9 @@
<uses-permission android:name="android.permission.REMOVE_TASKS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/>
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
<uses-permission android:name="android.permission.STATUS_BAR"/>
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE"/>
<uses-permission android:name="android.permission.STOP_APP_SWITCHES"/>
<uses-permission android:name="android.permission.SET_ORIENTATION"/>
<uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>
@@ -95,10 +97,11 @@
</provider>
<activity android:name="com.android.launcher3.proxy.ProxyActivityStarter"
- android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
- android:launchMode="singleTask"
- android:clearTaskOnLaunch="true"
- android:exported="false"/>
+ android:theme="@style/ProxyActivityStarterTheme"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:exported="false"
+ />
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
android:autoRemoveFromRecents="true"
diff --git a/quickstep/res/drawable/ic_chevron_down.xml b/quickstep/res/drawable/ic_chevron_down.xml
new file mode 100644
index 0000000..77a8295
--- /dev/null
+++ b/quickstep/res/drawable/ic_chevron_down.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <target android:name="scaleGroup">
+ <aapt:attr name="android:animation">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="scaleX"
+ android:valueFrom="1"
+ android:valueTo="-1" />
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="48dp"
+ android:height="48dp"
+ android:autoMirrored="true"
+ android:tint="?androidprv:attr/materialColorOnSurface"
+ android:viewportHeight="48"
+ android:viewportWidth="48">
+ <group
+ android:name="scaleGroup"
+ android:pivotX="24"
+ android:pivotY="24"
+ android:rotation="90">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.75,36 L16.6,33.85 26.5,23.95 16.6,14.05 18.75,11.9 30.8,23.95Z" />
+ </group>
+ </vector>
+ </aapt:attr>
+</animated-vector>
diff --git a/quickstep/res/layout/icon_app_chip_view.xml b/quickstep/res/layout/icon_app_chip_view.xml
new file mode 100644
index 0000000..87519a0
--- /dev/null
+++ b/quickstep/res/layout/icon_app_chip_view.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.quickstep.views.IconAppChipView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:focusable="false"
+ android:importantForAccessibility="no"
+ android:autoMirrored="true"
+ android:elevation="@dimen/task_thumbnail_icon_menu_elevation" >
+
+ <ImageView
+ android:id="@+id/icon_view_background"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/icon_menu_background"
+ android:importantForAccessibility="no" />
+
+ <com.android.quickstep.views.IconView
+ android:id="@+id/icon_view"
+ android:layout_width="@dimen/task_thumbnail_icon_size"
+ android:layout_height="@dimen/task_thumbnail_icon_size"
+ android:focusable="false"
+ android:importantForAccessibility="no" />
+
+ <TextView
+ android:id="@+id/icon_text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:maxLines="1"
+ android:textAlignment="viewStart"
+ android:textColor="?androidprv:attr/materialColorOnSurface"
+ android:textSize="16sp"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@+id/icon_arrow"
+ android:layout_width="@dimen/task_thumbnail_icon_menu_arrow_size"
+ android:layout_height="match_parent"
+ android:background="@drawable/icon_menu_arrow_background"
+ android:src="@drawable/ic_chevron_down"
+ android:importantForAccessibility="no" />
+</com.android.quickstep.views.IconAppChipView>
\ No newline at end of file
diff --git a/res/layout/popup_container_material_u.xml b/quickstep/res/layout/icon_view.xml
similarity index 60%
copy from res/layout/popup_container_material_u.xml
copy to quickstep/res/layout/icon_view.xml
index d34c500..a33066f 100644
--- a/res/layout/popup_container_material_u.xml
+++ b/quickstep/res/layout/icon_view.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
+<!--
+ Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,11 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.popup.PopupContainerWithArrow
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/popup_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical"/>
\ No newline at end of file
+<com.android.quickstep.views.IconView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/quickstep/res/layout/keyboard_quick_switch_view.xml b/quickstep/res/layout/keyboard_quick_switch_view.xml
index 16abdee..5af8d51 100644
--- a/quickstep/res/layout/keyboard_quick_switch_view.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_view.xml
@@ -17,6 +17,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/keyboard_quick_switch_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/keyboard_quick_switch_margin_top"
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 29c9992..823a86e 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -44,10 +44,9 @@
android:importantForAccessibility="no"
android:src="@drawable/ic_select_windows" />
- <com.android.quickstep.views.IconView
+ <ViewStub
android:id="@+id/icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no"/>
+ android:inflatedId="@id/icon"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
</com.android.quickstep.views.TaskView>
\ No newline at end of file
diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml
index 06f4d06..fe12bd3 100644
--- a/quickstep/res/layout/task_desktop.xml
+++ b/quickstep/res/layout/task_desktop.xml
@@ -45,11 +45,10 @@
android:layout_height="wrap_content"
android:visibility="gone" />
- <com.android.quickstep.views.IconView
+ <ViewStub
android:id="@+id/icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no" />
+ android:inflatedId="@id/icon"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
</com.android.quickstep.views.DesktopTaskView>
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
index 75ff626..d20afd3 100644
--- a/quickstep/res/layout/task_grouped.xml
+++ b/quickstep/res/layout/task_grouped.xml
@@ -66,17 +66,15 @@
android:importantForAccessibility="no"
android:src="@drawable/ic_select_windows" />
- <com.android.quickstep.views.IconView
+ <ViewStub
android:id="@+id/icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no"/>
+ android:inflatedId="@id/icon"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
- <com.android.quickstep.views.IconView
+ <ViewStub
android:id="@+id/bottomRight_icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no"/>
+ android:inflatedId="@id/bottomRight_icon"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content" />
</com.android.quickstep.views.GroupedTaskView>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 94388b4..72d7485 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -45,9 +45,6 @@
android:id="@+id/start_contextual_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingStart="@dimen/taskbar_contextual_button_padding"
- android:paddingEnd="@dimen/taskbar_contextual_button_padding"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
android:gravity="center_vertical"
android:layout_gravity="start"/>
@@ -63,7 +60,6 @@
android:id="@+id/end_contextual_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
android:gravity="center_vertical"
android:layout_gravity="end"/>
</FrameLayout>
diff --git a/quickstep/res/layout/taskbar_divider_popup_menu.xml b/quickstep/res/layout/taskbar_divider_popup_menu.xml
index 00e47c9..6fbb586 100644
--- a/quickstep/res/layout/taskbar_divider_popup_menu.xml
+++ b/quickstep/res/layout/taskbar_divider_popup_menu.xml
@@ -19,7 +19,7 @@
android:layout_width="@dimen/taskbar_pinning_popup_menu_width"
android:layout_height="wrap_content"
android:focusable="true"
- android:background="@drawable/popup_background_material_u"
+ android:background="@drawable/popup_background"
android:orientation="vertical">
<LinearLayout
@@ -38,6 +38,7 @@
android:theme="@style/PopupItem">
<View
+ android:id="@+id/taskbar_pinning_visibility_icon"
android:layout_margin="6dp"
android:layout_width="20dp"
android:layout_height="20dp"
@@ -45,13 +46,17 @@
android:backgroundTint="?android:attr/textColorPrimary" />
<Switch
- style="@style/BaseIcon"
+ style="@style/Switch.SettingsLib"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:id="@+id/taskbar_pinning_switch"
android:background="@null"
android:clickable="false"
android:gravity="start|center_vertical"
android:textAlignment="viewStart"
android:paddingStart="12dp"
+ android:layout_weight="1"
+ android:fontFamily="@*android:string/config_bodyFontFamilyMedium"
android:singleLine="true"
android:ellipsize="end"
android:textSize="14sp"
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index bca1e8c..b589e32 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Programvoorstelle is geaktiveer"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Programvoorstelle is gedeaktiveer"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde program: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Maak seker dat jy van die rand heel regs of heel links af swiep."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Maak seker dat jy van die regter- of linkerrand na die middel van die skerm swiep en laat los."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Jy het geleer hoe om van regs af te swiep om terug te gaan. Nou kan jy leer hoe om tussen programme te wissel."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Jy het die \"gaan terug\"-gebaar voltooi."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Maak seker dat jy nie te naby aan die onderkant van die skerm swiep nie."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Draai jou toestel"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Draai asseblief jou toestel om die tutoriaal oor gebaarnavigasie te voltooi"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Maak seker dat jy van die rand heel regs of heel links af swiep"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Maak seker dat jy van die regter- of linkerrand af na die middel van die skerm toe swiep en laat los"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Jy het geleer hoe om van regs af te swiep om terug te gaan. Nou kan jy leer hoe om tussen apps te wissel."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Jy het die Gaan Terug-gebaar voltooi"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Maak seker dat jy nie te naby aan die onderkant van die skerm swiep nie"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Gaan na Instellings om sensitiwiteit van teruggebaar te verander"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swiep om terug te gaan"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Swiep van die linker- of regterrand na die middel van die skerm om na die vorige skerm terug te gaan."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Swiep met 2 vingers van die linker- of regterkant van die skerm af na die middel toe om terug te keer na die vorige skerm."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Gaan terug"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Maak seker dat jy van die onderrand van die skerm af opswiep."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Maak seker jy onderbreek nie voordat jy laat los nie."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Maak seker jy swiep reguit op."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Jy het die \"gaan na tuisskerm\"-gebaar voltooi. Nou kan jy leer hoe om terug te gaan."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Jy het die \"gaan na tuisskerm\"-gebaar voltooi."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swiep van die linker- of regterrand af na die middel van die skerm toe"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Maak seker dat jy van die onderrand van die skerm af opswiep"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Maak seker jy hou nie stil voordat jy laat los nie"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Maak seker jy swiep reguit op"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Jy het die Gaan na Tuisskerm-gebaar voltooi. Nou kan jy leer hoe om terug te gaan."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Jy het die Gaan na Tuisskerm-gebaar voltooi"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swiep om na tuisskerm toe te gaan"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swiep op van die onderkant van jou skerm af. Hierdie gebaar neem jou altyd na die tuisskerm toe."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swiep met 2 vingers op van die onderkant van die skerm af. Dié gebaar neem jou altyd na die tuisskerm toe."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Gaan na tuisskerm"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Swiep enige tyd van die onderkant van jou skerm af op om na jou tuisskerm toe te gaan"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Maak seker dat jy van die onderrand van die skerm af opswiep."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Probeer om die venster langer te hou voordat jy laat los."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Maak seker dat jy reguit opswiep en dan onderbreek."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swiep van die onderkant van jou skerm af op"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Knap gedaan!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Maak seker dat jy van die onderrand van die skerm af opswiep"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Probeer om die venster langer te hou voordat jy laat los"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Maak seker dat jy reguit opswiep en dan stilhou"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jy het geleer hoe om gebare te gebruik. Gaan na Instellings om gebare af te skakel."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Jy het die \"wissel tussen programme\"-gebaar voltooi."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Jy het die Wissel Apps-gebaar voltooi"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swiep om tussen programme te wissel"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Swiep van die onderkant van jou skerm af op, hou en laat los dan om tussen programme te wissel."</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Swiep met 2 vingers op van die onderkant van jou skerm af, hou en laat los dan om tussen programme te wissel."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Swiep van die onderkant van jou skerm af op, hou en laat los dan om tussen apps te wissel."</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Swiep met 2 vingers op van die onderkant van jou skerm af, hou en laat los dan om tussen apps te wissel."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Wissel apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swiep van die onderkant van jou skerm af op, hou, en los dan"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Welgedaan!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gereed"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klaar"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Instellings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skermkiekie"</string>
<string name="action_split" msgid="2098009717623550676">"Verdeel"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tik op ’n ander app om verdeelde skerm te gebruik"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Verlaat verdeeldeskermkeuse"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Kies nog ’n app as jy verdeelde skerm wil gebruik"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Jou organisasie laat nie hierdie program toe nie"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Slaan navigasietutoriaal oor?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taakbalk word gewys"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taakbalk is versteek"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigasiebalk"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Wys Taakbalk altyd"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Verander navigasiemodus"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taakbalkverdeler"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Skuif na links bo"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Skuif na regs onder"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Wys nog # app.}other{Wys nog # apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> en <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Voeg nou app by werkskerm"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Kanselleer"</string>
</resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index a226a04..a678b3f 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -33,46 +33,52 @@
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"የእርስዎ የሚገመቱ መተግበሪያዎች"</string>
<string name="hotseat_edu_title_migrate" msgid="306578144424489980">"በመነሻ ገጽዎ ታችኛው ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ"</string>
<string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"በመነሻ ማያ ገጽዎ የተወዳጆች ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"በጣም ስራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ። በታችኛው ረድፍ ላይ ያሉ መተግበሪያዎች ወደ መነሻ ገጽዎ ይወሰዳሉ።"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመሥረት ይቀየራሉ። በተወዳጆች ረድፍ ውስጥ ያሉ መተግበሪያዎች ወደ የእርስዎ መነሻ ማያ ገጽ ይንቀሳቀሳሉ።"</string>
+ <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ። በታችኛው ረድፍ ላይ ያሉ መተግበሪያዎች ወደ መነሻ ገጽዎ ይወሰዳሉ።"</string>
+ <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመሥረት ይቀየራሉ። በተወዳጆች ረድፍ ውስጥ ያሉ መተግበሪያዎች ወደ የእርስዎ መነሻ ማያ ገፅ ይንቀሳቀሳሉ።"</string>
<string name="hotseat_edu_accept" msgid="1611544083278999837">"የመተግበሪያ አስተያየት ጥቆማዎችን አግኝ"</string>
<string name="hotseat_edu_dismiss" msgid="2781161822780201689">"አይ፣ አመሰግናለሁ"</string>
<string name="hotseat_prediction_settings" msgid="6246554993566070818">"ቅንብሮች"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"በብዛት ስራ ላይ የዋሉ መተግበሪያዎች እዚህ ይመጣሉ፣ እና በዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ"</string>
+ <string name="hotseat_auto_enrolled" msgid="522100018967146807">"በብዛት ሥራ ላይ የዋሉ መተግበሪያዎች እዚህ ይመጣሉ፣ እና በዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ"</string>
<string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"የመተግበሪያ ጥቆማዎችን ለማግኘት መተግበሪያዎችን ከታችኛው ረድፍ ይጎትቱ"</string>
<string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"የመተግበሪያ አስተያየት ጥቆማዎች ወደ ባዶ ቦታ ታክለዋል"</string>
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"የመተግበሪያ አስተያየት ጥቆማዎች ነቅቷል"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"የመተግበሪያ አስተያየቶች ቦዝነዋል"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"የተገመተው መተግበሪያ፦ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ከቀኝ ጠርዝ ወይም ከግራ ጠርዝ ጥግ ጀምሮ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ከቀኝ ወይም ከግራ ጠርዝ ወደ ማያ ገጹ መሃል ማንሸራተትዎን እና መልቀቅዎን ያረጋግጡ።"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"መሣሪያዎን ያሽከርክሩ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"የእጅ ምልክት ዳሰሳ አጋዥ ሥልጠናን ለማጠናቀቅ እባክዎ መሣሪያዎን ያሽከርክሩ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ከቀኝ ጥግ ወይም ከግራ ጥግ ጠርዝ ጀምሮ ማንሸራተትዎን ያረጋግጡ"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ከቀኝ ወይም ከግራ ጠርዝ ወደ ማያ ገጹ መሃል ማንሸራተትዎን እና መልቀቅዎን ያረጋግጡ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ወደ ኋላ ለመመለስ ከቀኝ ጀምሮ እንዴት ማንሸራተት እንደሚችሉ አውቀዋል። ቀጥለው መተግበሪያዎችን እንዴት መቀየር እንደሚችሉ ይወቁ።"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ወደኋላ የመመለስ ምልክትን አጠናቀዋል።"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ከማያ ገጹ ታችኛው ክፍል ጋር በጣም ጠጋ ብለው አለማንሸራተትዎን ያረጋግጡ።"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ወደኋላ የመመለስ ምልክትን አጠናቅቀዋል"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ከማያ ገጹ ታችኛው ክፍል ጋር በጣም ጠጋ ብለው አለማንሸራተትዎን ያረጋግጡ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ከኋላ ስሜት ሰጭነት ደረጃ ለመለወጥ ወደ ቅንብሮች ይመለሱ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ወደኋላ ለመመለስ ያንሸራትቱ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ወደ መጨረሻው ማያ ገጽ ለመመለስ ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።"</string>
- <string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ወደ መጨረሻው ማያ ገጽ ለመመለስ በ2 ጣቶች ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።"</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ወደ መጨረሻው ማያ ገፅ ለመመለስ ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።"</string>
+ <string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ወደ መጨረሻው ማያ ገፅ ለመመለስ በ2 ጣቶች ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ተመለስ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ከመልቀቅዎ በፊት ለአፍታ እንዳልቆሙ ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"የወደ መነሻ ሂድ ምልክትን አጠናቀዋል። ቀጥሎም ወደ ኋላ እንዴት መሄድ እንደሚችሉ ይወቁ።"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"የወደ መነሻ ሂድ ምልክትን አጠናቀዋል።"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መካከል ያንሸራትቱ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ከማያ ገጹ የታችኛው ጠርዝ ወደ ላይ ማንሸራተትዎን ያረጋግጡ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ከመልቀቅዎ በፊት ባሉበት እንዳልቆሙ ያረጋግጡ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ወደ መነሻ ሂድ ምልክትን አጠናቅቀዋል። ቀጥሎ ደግሞ እንዴት ወደ ኋላ መመለስ እንደሚቻል ይማሩ።"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ወደ መነሻ ሂድ ምልክትን አጠናቅቀዋል"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ወደ መነሻ ለመሄድ ያንሸራትቱ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ከእርስዎ ማያ ገጽ ግርጌ ላይ ወደ ላይ በጣት ጠረግ ያድርጉ። ይህ የእጅ ውዝዋዜ ሁልጊዜ ወደ መነሻ ማያ ገጽ ይወስድዎታል።"</string>
- <string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"በ2 ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ያንሸራትቱ። ይህ የእጅ ምልክት ሁልጊዜ ወደ መነሻ ማያ ገጽ ይወስደዎታል።"</string>
+ <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ከእርስዎ ማያ ገፅ ግርጌ ላይ ወደ ላይ በጣት ጠረግ ያድርጉ። ይህ የእጅ ውዝዋዜ ሁልጊዜ ወደ መነሻ ማያ ገፅ ይወስድዎታል።"</string>
+ <string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"በ2 ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ያንሸራትቱ። ይህ የእጅ ምልክት ሁልጊዜ ወደ መነሻ ማያ ገፅ ይወስደዎታል።"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ወደ መነሻ ይሂዱ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"በማንኛውም ጊዜ ወደ መነሻ ማያ ገጽዎ ለመሄድ ከማያ ገጽዎ የታችኛው ክፍል ወደ ላይ ያንሸራትቱ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ከመልቀቅዎ በፊት መስኮቱን ረዘም ላለ ጊዜ ለመያዝ ይሞክሩ።"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ፣ ከዚያ ለአፍታ ያቁሙ።"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ከማያ ገጽዎ የታችኛው ክፍል ወደ ላይ ያንሸራትቱ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ጥሩ ሠርተዋል!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ከማያ ገጹ የታችኛው ጠርዝ ወደ ላይ ማንሸራተትዎን ያረጋግጡ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ከመልቀቅዎ በፊት መስኮቱን ረዘም ላለ ጊዜ ለመያዝ ይሞክሩ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ፣ ከዚያ ባለበት ያቁሙ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"የእጅ ምልክቶችን እንዴት እንደሚጠቀሙ ተምረዋል። የእጅ ምልክቶችን ለማጥፋት ወደ ቅንብሮች ይሂዱ።"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"መተግበሪያዎችን የመቀያየር ምልክትን አጠናቀዋል።"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"መተግበሪያዎችን ቀይር ምልክትን አጠናቅቀዋል"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"መተግበሪያዎችን ለመቀየር ያንሸራትቱ"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"በመተግበሪያዎች መካከል ለመቀያየር ከማያ ገጽዎ ግርጌ ወደ ላይ ያንሸራትቱ፣ ይያዙ፣ ከዚያ ይለቀቁ።"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"በመተግበሪያዎች መካከል ለመቀያየር ከማያ ገጽዎ ግርጌ ላይ በ2 ጣቶች ያንሸራትቱ፣ ይያዙ፣ ከዚያ ይለቀቁ።"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"መተግበሪያዎችን ይቀያይሩ"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ከማያ ገጽዎ የታችኛው ክፍል ወደ ላይ ያንሸራትቱ፣ ይያዙ፣ ከዚያ ይልቀቁ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ጥሩ ሰርተዋል!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ሁሉም ዝግጁ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ተጠናቋል"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ቅንብሮች"</string>
@@ -86,9 +92,10 @@
<string name="default_device_name" msgid="6660656727127422487">"መሣሪያ"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"የስርዓት አሰሳ ቅንብሮች"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"አጋራ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ቅጽበታዊ ገጽ እይታ"</string>
+ <string name="action_screenshot" msgid="8171125848358142917">"ቅጽበታዊ ገፅ ዕይታ"</string>
<string name="action_split" msgid="2098009717623550676">"ክፈል"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"የተከፈለ ማያ ገጽን ለመጠቀም ሌላ መተግበሪያ መታ ያድርጉ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ከተከፈለ ማያ ገፅ ምርጫ ይውጡ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"የተከፈለ ማያ ገጽን ለመቀበል ሌላ መተግበሪያ ይምረጡ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ይህ ድርጊት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"የአሰሳ አጋዥ ሥልጠናን ይዝለሉ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"የተግባር አሞሌ ይታያል"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"የተግባር አሞሌ ተደብቋል"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"የአሰሳ አሞሌ"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ሁልጊዜ የተግባር አሞሌ ያሳዩ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"የአሰሳ ሁነታን ይለውጡ"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"የተግባር አሞሌ አካፋይ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ወደ ላይ/ግራ ይውሰዱ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ወደ ታች/ቀኝ ይውሰዱ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{ተጨማሪ # መተግበሪያ አሳይ።}one{ተጨማሪ # መተግበሪያ አሳይ።}other{ተጨማሪ # መተግበሪያዎች አሳይ።}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> እና <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"መተግበሪያን ወደ ዴስክቶፕ በማከል ላይ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ይቅር"</string>
</resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 560f1c2..6d7effc 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"تم تفعيل ميزة \"التطبيقات المقترحة\"."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ميزة \"التطبيقات المقترحة\" غير مفعّلة."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"التطبيق المتوقع: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"تأكّد من التمرير سريعًا من أقصى الحافة اليسرى أو اليمنى."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"تأكّد من التمرير سريعًا من الحافة اليسرى أو اليمنى إلى وسط الشاشة ثم ارفع إصبعك."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"يُرجى تدوير الجهاز"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"يُرجى تدوير جهازك لإكمال الدليل التوجيهي للتنقُّل بالإيماءات."</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"تأكَّد من التمرير سريعًا من أقصى الحافة اليسرى أو اليمنى."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"تأكَّد من التمرير سريعًا من الحافة اليسرى أو اليمنى إلى وسط الشاشة ثم ارفع إصبعك."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"لقد تعلمت كيفية التمرير سريعًا من اليسار للرجوع. تعرّف بعد ذلك على كيفية التبديل بين التطبيقات."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"لقد أكملت التدريب على إيماءة الرجوع."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"تأكّد من عدم التمرير بالقرب من أسفل الشاشة."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"لقد أكملت التدريب على إيماءة الرجوع."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"تأكَّد من عدم التمرير سريعًا بالقرب من أسفل الشاشة."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"لتغيير مستوى حساسية إيماءة الرجوع، انتقِل إلى \"الإعدادات\""</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"مرِّر سريعًا للرجوع."</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"للرجوع إلى الشاشة السابقة، مرِّر سريعًا من الحافة اليسرى أو الحافة اليمنى إلى وسط الشاشة."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"للرجوع إلى الشاشة السابقة، عليك التمرير سريعًا بإصبعين من الحافة اليسرى أو اليمنى نحو وسط الشاشة."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"الرجوع"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"تأكّد من التمرير سريعًا من الحافة السفلى للشاشة إلى أعلاها."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"تأكّد من عدم التوقّف قليلاً قبل رفع إصبعك."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"تأكّد من التمرير إلى الأعلى مباشرةً."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"لقد أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية. تعرّف بعد ذلك على كيفية الرجوع."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"مرِّر سريعًا من الحافة اليمنى أو اليسرى إلى منتصف الشاشة."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"تأكَّد من التمرير سريعًا من الحافة السفلية للشاشة إلى أعلاها."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"تأكَّد من عدم التوقّف مؤقتًا قبل رفع إصبعك."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"تأكَّد من التمرير للأعلى مباشرةً."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"لقد أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية. تعرَّف بعد ذلك على كيفية الرجوع."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"لقد أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"مرِّر سريعًا للانتقال إلى الشاشة الرئيسية"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"مرِّر سريعًا من أسفل الشاشة إلى أعلاها. تنقلك هذه الإيماءة دائمًا إلى الشاشة الرئيسية."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"مرِّر سريعًا بإصبعين من أسفل الشاشة إلى أعلاها. تنقلك هذه الإيماءة دائمًا إلى الشاشة الرئيسية."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"الانتقال إلى الشاشة الرئيسية"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"للانتقال إلى شاشتك الرئيسية في أي وقت، اسحب لأعلى الشاشة من أسفلها."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"تأكّد من التمرير سريعًا من الحافة السفلى للشاشة إلى أعلاها."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"حاوِل إبقاء إصبعك على النافذة لمدة أطول قبل رفعه."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"تأكّد من التمرير سريعًا للأعلى مباشرةً ثم التوقّف قليلاً."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"مرِّر سريعًا من أسفل الشاشة إلى أعلاها."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"أحسنت صنعًا."</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"تأكَّد من التمرير سريعًا من الحافة السفلية للشاشة إلى أعلاها."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"حاوِل إبقاء إصبعك على النافذة لمدة أطول قبل رفعه."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"تأكَّد من التمرير سريعًا للأعلى مباشرةً ثم التوقّف مؤقتًا."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"لقد تعرّفت على كيفية استخدام الإيماءات. لإيقاف الإيماءات، انتقِل إلى \"الإعدادات\"."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"أكملت التدريب على إيماءة التبديل بين التطبيقات."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"لقد أكملت التدريب على إيماءة التبديل بين التطبيقات."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"التمرير سريعًا للتبديل بين التطبيقات"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"للتبديل بين التطبيقات، مرِّر سريعًا من أسفل الشاشة لأعلاها مع تثبيت إصبعك ثم ارفعه."</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"للتبديل بين التطبيقات، مرِّر سريعًا من أسفل الشاشة إلى أعلاها بإصبعين مع تثبيتهما، ثم ارفعهما."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"للتبديل بين التطبيقات، مرِّر سريعًا من أسفل الشاشة إلى الأعلى ثمّ ثبِّت إصبعك قليلاً قبل رفعه."</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"للتبديل بين التطبيقات، مرِّر سريعًا من أسفل الشاشة إلى أعلاها بإصبعين، ثمّ ثبّتهما قليلاً قبل رفعهما."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"تبديل التطبيقات"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"مرِّر سريعًا من أسفل الشاشة إلى أعلاها، وأبقِ إصبعك على الشاشة قليلاً ثم ارفعه."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"أحسنت."</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"اكتمل التدريب على الإيماءة"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"تم"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"الإعدادات"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"لقطة شاشة"</string>
<string name="action_split" msgid="2098009717623550676">"تقسيم"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"انقر على تطبيق آخر لاستخدام وضع تقسيم الشاشة."</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"الخروج من وضع تقسيم الشاشة"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"اختَر تطبيقًا آخر لاستخدام وضع تقسيم الشاشة."</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"هل تريد تخطي الدليل التوجيهي للتنقّل؟"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"تم إظهار شريط التطبيقات"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"تم إخفاء شريط التطبيقات"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"شريط التنقل"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"إظهار شريط التطبيقات دائمًا"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"تغيير وضع التنقل"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"مقسِّم شريط التطبيقات"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"الانتقال إلى يمين الشاشة أو أعلاها"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"الانتقال إلى يسار الشاشة أو أسفلها"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{إظهار تطبيق واحد آخر}zero{إظهار # تطبيق آخر}two{إظهار تطبيقَين آخرَين}few{إظهار # تطبيقات أخرى}many{إظهار # تطبيقًا آخر}other{إظهار # تطبيق آخر}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"\"<xliff:g id="APP_NAME_1">%1$s</xliff:g>\" و\"<xliff:g id="APP_NAME_2">%2$s</xliff:g>\""</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"إضافة تطبيق إلى سطح المكتب"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"إلغاء"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 825a396..a68aee5 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"এপৰ পৰামৰ্শসমূহ সক্ষম কৰা আছে"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"এপৰ পৰামৰ্শসমূহ অক্ষম কৰা আছে"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"পূৰ্বানুমান কৰা এপ্: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"আপুনি সোঁ অথবা বাওঁ প্ৰান্তৰৰ একেবাৰে সীমাৰ পৰা ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"আপুনি স্ক্ৰীনৰ সোঁ অথবা বাওঁ প্ৰান্তৰৰ পৰা মধ্যভাগলৈকে ছোৱাইপ কৰি এৰি দিয়াটো নিশ্চিত কৰক।"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"আঙুলিৰ স্পৰ্শৰ নিৰ্দেশেৰে কৰা নেভিগেশ্বনৰ টিউট’ৰিয়েল শেষ কৰিবলৈ অনুগ্ৰহ কৰি আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"আপুনি সোঁ অথবা বাওঁ কাষৰ একেবাৰে সীমাৰ পৰা ছোৱাইপ কৰাটো নিশ্চিত কৰক"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"আপুনি স্ক্ৰীনৰ সোঁ অথবা বাওঁ কাষৰ পৰা মধ্যভাগলৈকে ছোৱাইপ কৰি এৰি দিয়াটো নিশ্চিত কৰক"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"সোঁফালৰ পৰা ছোৱাইপ কৰি কেনেকৈ উভতি যাব লাগে, সেইটো আপুনি জানিলে। ইয়াৰ পাছত, এপ্ কেনেকৈ সলনি কৰিব সেয়া জানক।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"আপুনি উভতি যাওক নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"আপুনি স্ক্ৰীনৰ তলৰ অংশৰ বেছি ওচৰলৈ ছোৱাইপ নকৰাটো নিশ্চিত কৰক।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"আপুনি উভতি যাওক নিৰ্দেশটো সম্পূৰ্ণ কৰিলে"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"আপুনি স্ক্ৰীনৰ তলৰ অংশৰ বেছি ওচৰলৈ ছোৱাইপ নকৰাটো নিশ্চিত কৰক"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"উভতি যোৱাৰ নির্দেশটোৰ সংবেদনশীলতা সলনি কৰিবলৈ ছেটিঙলৈ যাওক"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"উভতি যাবলৈ ছোৱাইপ কৰক"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"অন্তিম স্ক্ৰীনখনলৈ উভতি যাবলৈ বাওঁ অথবা সোঁ প্ৰান্তৰৰ পৰা মাজলৈ ছোৱাইপ কৰক।"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"অন্তিম স্ক্ৰীনখনলৈ উভতি যাবলৈ ২ টা আঙুলিৰে স্ক্ৰীনখনৰ বাওঁ অথবা সোঁ প্ৰান্তৰৰ পৰা মাজলৈ ছোৱাইপ কৰক।"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"উভতি যাওক"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"আপুনি এৰি দিয়াৰ পূৰ্বে অলপো নোৰোৱাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"আপুনি পোনকৈ ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে। ইয়াৰ পাছত, গৃহ স্ক্ৰীনলৈ কেনেকৈ যাব সেয়া জানক।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"স্ক্ৰীনখনৰ বাওঁ অথবা সোঁ প্ৰান্তৰৰ পৰা মধ্যভাগলৈ ছোৱাইপ কৰক"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"আপুনি এৰি দিয়াৰ পূৰ্বে অলপো নোৰোৱাটো নিশ্চিত কৰক"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"আপুনি পোনকৈ ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে। ইয়াৰ পাছত, কেনেকৈ উভতি যাব সেয়া জানক।"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"গৃহ স্ক্ৰীনলৈ যাবলৈ ছোৱাইপ কৰক"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"আপোনাৰ স্ক্ৰীনৰ তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰক। এই নিৰ্দেশটোৱে আপোনাক সদায় গৃহ স্ক্ৰীনলৈ লৈ যায়।"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ২ টা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰক। এই নিৰ্দেশটোৱে আপোনাক সদায় গৃহ স্ক্ৰীনলৈ লৈ যায়।"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"গৃহ পৃষ্ঠালৈ যাওক"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"আপোনাৰ গৃহ স্ক্ৰীনলৈ যিকোনো সময়তে যাবলৈ, আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ছোৱাইপ কৰক"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"এৰি দিয়াৰ পূৰ্বে ৱিণ্ডখন দীৰ্ঘ সময়ৰ বাবে ধৰি ৰাখিবলৈ চেষ্টা কৰক।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"আপুনি স্ক্ৰীনৰ ওপৰলৈ পোনকৈ ছোৱাইপ কৰি তাৰ পাছত ৰোৱাটো নিশ্চিত কৰক।"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"আপোনাৰ স্ক্ৰীনৰ একেবাৰে তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰক"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"বঢ়িয়া!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"এৰি দিয়াৰ পূৰ্বে ৱিণ্ডখন দীৰ্ঘ সময়ৰ বাবে ধৰি ৰাখিবলৈ চেষ্টা কৰক"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"আপুনি স্ক্ৰীনৰ ওপৰলৈ পোনকৈ ছোৱাইপ কৰি তাৰ পাছত ৰোৱাটো নিশ্চিত কৰক"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"আপুনি নিৰ্দেশসমূহ কেনেকৈ ব্যৱহাৰ কৰিব লাগে সেয়া জানিলে। নিৰ্দেশসমূহ অফ কৰিবলৈ, ছেটিঙলৈ যাওক।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"আপুনি এপ্ সলনি কৰাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"আপুনি এপ্ সলনি কৰাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"এপ্ সলনি কৰিবলৈ ছোৱাইপ কৰক"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"এপ্সমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ আপোনাৰ স্ক্ৰীনৰ একেবাৰে তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক আৰু তাৰ পাছত এৰি দিয়ক।"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"এপ্সমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ ২ টা আঙুলিৰে আপোনাৰ স্ক্ৰীনৰ একেবাৰে তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক আৰু তাৰ পাছত এৰি দিয়ক।"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"এপ্ সলনি কৰক"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"আপোনাৰ স্ক্ৰীনৰ তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰক, ধৰি ৰাখক, তাৰ পাছত এৰি দিয়ক"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"বঢ়িয়া!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"সম্পূৰ্ণ সাজু"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"হ’ল"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ছেটিং"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"স্ক্ৰীনশ্বট"</string>
<string name="action_split" msgid="2098009717623550676">"বিভাজন কৰক"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপত টিপক"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"বিভাজিত স্ক্ৰীনৰ বাছনিৰ পৰা বাহিৰ হওক"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপ্ বাছক"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"এপ্টোৱে অথবা আপোনাৰ প্ৰতিষ্ঠানে এই কাৰ্যটোৰ অনুমতি নিদিয়ে"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"নেভিগেশ্বনৰ টিউট’ৰিয়েল এৰিব বিচাৰে নেকি?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"টাস্কবাৰ দেখুওৱা হৈছে"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"টাস্কবাৰ লুকুৱাই থোৱা হৈছে"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"নেভিগেশ্বনৰ দণ্ড"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"টাস্কবাৰ সদায় দেখুৱাওক"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"নেভিগেশ্বন ম’ড সলনি কৰক"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"টাস্কবাৰ বিভাজক"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ওপৰৰ বাঁওফাললৈ নিয়ক"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"তলৰ সোঁফাললৈ নিয়ক"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{আৰু # টা এপ্ দেখুৱাওক।}one{আৰু # টা এপ্ দেখুৱাওক।}other{আৰু # টা এপ্ দেখুৱাওক।}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> আৰু <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ডেস্কটপত এপ্ যোগ দি থকা হৈছে"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"বাতিল কৰক"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 0962991..9fff2d8 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Tətbiq təklifləri aktivdir"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tətbiq təklifləri deaktivdir"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Proqnozlaşdırılan tətbiq: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ekranın ən sağ və ya sol kənarından sürüşdürün."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranın sağ və ya sol kənarından ortasına sürüşdürüb buraxın."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Cihazı fırladın"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Jest naviqasiyası təlimatını tamamlamaq üçün cihazı fırladın"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ən sağ və ya sol kənardan sürüşdürün"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Sağ və ya sol kənardan ekranın ortasına sürüşdürüb, buraxın"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Geri qayıtmaq üçün sağdan sürüşdürmək qaydasını öyrəndiniz. Sonra tətbiqləri keçirməyi öyrənin."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Geri getmə jestini tamamladınız."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ekranın altına çox yaxın sürüşdürmədiyinizə əmin olun."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Geri qayıtma jestini tamamladınız"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Barmağınızı ekranın aşağı kənarına çox yaxınlaşdırmayın"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Geri qayıtma jestinin həssaslığını dəyişmək üçün Ayarlara keçin"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Geri qayıtmaq üçün sürüşdürün"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Sonuncu ekrana qayıtmaq üçün ekranın sol, yaxud sağ kənarından mərkəzinə doğru sürüşdürün."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Sonuncu ekrana qayıtmaq üçün 2 barmaqla ekranın sol, yaxud sağ kənarından mərkəzinə doğru sürüşdürün."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Geri qayıdın"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ekranın ən kənar aşağısından yuxarı sürüşdürün."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Buraxmazdan əvvəl durdurmadığınıza əmin olun."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Birbaşa yuxarı sürüşdürün."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Əsas səhifəyə keçmə jestini tamamladınız. Sonra geri qayıtmağı öyrənin."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Əsas səhifəyə keçmə jestini tamamladınız."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Sol və ya sağ kənardan ekranın ortasına sürüşdürün"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Ekranın aşağı kənarından yuxarı sürüşdürün"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Buraxmazdan əvvəl durdurmayın"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Düz yuxarı sürüşdürün"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Əsas ekrana keçid jestini tamamladınız. Geri qayıtmağı öyrənin."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Əsas ekrana keçid jestini tamamladınız"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Əsas səhifəyə keçmək üçün sürüşdürün"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranın aşağısından yuxarısına sürüşdürün. Bu jest həmişə Əsas səhifəyə aparır."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 barmaqla ekranın aşağısından yuxarısına sürüşdürün. Bu jest həmişə Əsas səhifəyə aparır."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Əsas səhifəyə qayıdın"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"İstənilən vaxt əsas ekranınıza getmək üçün ekranın aşağısından yuxarı sürüşdürün"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ekranın ən kənar aşağısından yuxarı sürüşdürün."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Barmağı buraxmadan öncə displeydə bir müddət saxlayın."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sürüşdürüb ekranın yuxarı kənarında saxlayın."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Ekranın aşağısından yuxarı sürüşdürün"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Əla!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Ekranın aşağı kənarından yuxarı sürüşdürün"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Buraxmazdan öncə pəncərəni bir müddət saxlayın"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Düz yuxarı sürüşdürüb, durdurun"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jestlərdən istifadə qaydasını öyrəndiniz. Jestləri deaktiv etmək üçün Ayarlara keçin."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Tətbiqləri keçirmə jestini tamamladınız."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Tətbiqlər arasında keçid jestini tamamladınız"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Tətbiqi keçirmək üçün sürüşdürün"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Tətbiqlər arasında keçid üçün ekranın aşağısından yuxarı doğru sürüşdürüb saxlayın, sonra buraxın."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Tətbiqlər arasında keçid üçün 2 barmaqla ekranın aşağısından yuxarı doğru sürüşdürüb saxlayın, sonra buraxın."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Tətbiqləri dəyişin"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Ekranın aşağısından yuxarı sürüşdürüb saxlayın, sonra buraxın"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Afərin!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tam hazır"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Oldu"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ayarlar"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skrinşot"</string>
<string name="action_split" msgid="2098009717623550676">"Ayırın"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Bölünmüş ekran üçün başqa tətbiqə toxunun"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Bölünmüş ekran seçimindən çıxın"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Bölünmüş ekrandan istifadə üçün başqa tətbiq seçin"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Bu əməliyyata tətbiq və ya təşkilatınız tərəfindən icazə verilmir"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Naviqasiya dərsliyi ötürülsün?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"İşləmə paneli göstərilir"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"İşləmə paneli gizlədilib"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Naviqasiya paneli"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"İşləmə paneli həmişə görünsün"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Naviqasiya rejimini dəyişin"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"İşləmə paneli ayırıcısı"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Yuxarı/sola köçürün"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Aşağı/sağa köçürün"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Daha # tətbiqi göstərin.}other{Daha # tətbiqi göstərin.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> və <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Tətbiqin masaüstünə əlavə edilməsi"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Ləğv edin"</string>
</resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 23dd072..9a7aa4b 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlozi aplikacija su omogućeni"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlozi aplikacija su onemogućeni"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđamo aplikaciju: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Obavezno prevucite od same desne ili leve ivice."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Obavezno prevucite od desne ili leve ivice do sredine ekrana i otpustite."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotirajte uređaj"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotirajte uređaj da biste dovršili vodič za navigaciju pomoću pokreta"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Obavezno prevucite od same desne ili leve ivice"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Obavezno prevucite od desne ili leve ivice do sredine ekrana i otpustite"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako da prevlačite zdesna da biste se vratili unazad. Sada naučite da zamenite aplikacije."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dovršili ste pokret za povratak."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nikako ne prevlačite previše blizu dna ekrana."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Dovršili ste pokret za povratak"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Nikako ne prevlačite previše blizu dna ekrana"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Osetljivost pok. za nazad možete da promenite u Podešavanjima"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Prevucite da biste se vratili unazad"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da biste se vratili na poslednji ekran, prevucite od leve ili desne ivice do sredine ekrana."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Da biste se vratili na poslednji ekran, prevucite pomoću dva prsta od leve ili desne ivice do sredine ekrana."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Nazad"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Obavezno prevucite nagore od donje ivice ekrana."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nikako ne stajte pre otpuštanja."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Obavezno prevucite pravo nagore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dovršili ste pokret za povratak na početnu stranicu. Sada saznajte kako da se vratite."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dovršili ste pokret za povratak na početnu stranicu."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Prevucite od leve ili desne ivice do sredine ekrana"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Obavezno prevucite nagore od donje ivice ekrana"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Nikako ne stajte pre otpuštanja"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Obavezno prevucite pravo nagore"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Dovršili ste pokret za povratak na početnu stranicu. Sada saznajte kako da se vratite."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Dovršili ste pokret za povratak na početnu stranicu."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Prevucite da biste otišli na početnu stranicu"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prevucite nagore od dna ekrana. Ovaj pokret vas uvek vodi na početni ekran."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Prevucite pomoću dva prsta nagore od dna ekrana. Ovim pokretom uvek otvarate početni ekran."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Idite na početni ekran"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Da biste otišli na početni ekran u bilo kom trenutku, prevucite nagore od dna ekrana."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Obavezno prevucite nagore od donje ivice ekrana."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Probajte da držite prozor duže pre otpuštanja."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Obavezno prevucite pravo nagore, pa zastanite."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Prevucite nagore sa donjeg dela ekrana"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Odlično!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Obavezno prevucite nagore od donje ivice ekrana"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Probajte da držite prozor duže pre otpuštanja"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Obavezno prevucite pravo nagore, pa zastanite"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste kako da koristite pokrete. Da biste isključili pokrete, idite na podešavanja."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dovršili ste pokret za promenu aplikacija."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Dovršili ste pokret za promenu aplikacija"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prevucite da biste zamenili aplikacije"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za prelazak sa jedne aplikacije na drugu prevucite nagore od dna ekrana, zadržite, pa pustite."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Za prelazak između aplikacija prevucite pomoću dva prsta nagore od dna ekrana, zadržite, pa pustite."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Pređite na drugu aplikaciju"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Prevucite nagore od dna ekrana, zadržite, pa pustite"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Odlično!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"To je to"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Podešavanja"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
<string name="action_split" msgid="2098009717623550676">"Podeli"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Dodirnite drugu aplikaciju za podeljeni ekran"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Izlazak iz biranja podeljenog ekrana"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Odaberite drugu aplikaciju za podeljeni ekran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili organizacija ne dozvoljavaju ovu radnju"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite da preskočite vodič za kretanje?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotirajte ekran"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Uputstva na traci zadataka"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Prevucite na stranu da biste koristili 2 aplikacije odjednom"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Nakratko prevucite nagore da biste prikazali traku zadataka"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Sporo prevucite nagore da biste prikazali traku zadataka"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dobijajte predloge aplikacija na osnovu rutine"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Uključite navigaciju pomoću pokreta u Podešavanjima radi automatskog skrivanja trake zadataka"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Uradite više pomoću trake zadataka"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Traka zadataka je prikazana"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Traka zadataka je skrivena"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Traka za navigaciju"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Uvek prikazuj traku zadataka"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Promeni režim navigacije"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Razdelnik trake zadataka"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premesti gore levo"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premesti dole desno"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Prikaži još # aplikaciju.}one{Prikaži još # aplikaciju.}few{Prikaži još # aplikacije.}other{Prikaži još # aplikacija.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> i <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Dodaje se aplikacija na radnu povrršinu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Otkaži"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index a5c218b..ca62108 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Прапановы праграм уключаны"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Прапановы праграм выключаны"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Праграма з падказкі: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Пераканайцеся, што вы праводзіце пальцам ад самага вугла (правага ці левага) экрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Пераканайцеся, што праводзіце пальцам з правага ці левага вугла ў цэнтр экрана, а потым адпускаеце."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Павярніце прыладу"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Каб пачаць азнаямленне з дапаможнікам па навігацыі жэстамі, павярніце прыладу"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Правядзіце пальцам справа налева ці злева направа ад самага краю экрана"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Правядзіце пальцам ад правага або левага краю экрана ў цэнтр і адпусціце палец"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Вы даведаліся, як гартаць справа для вяртання. Цяпер даведайцеся, як пераключацца паміж праграмамі."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Вы навучыліся рабіць жэст вяртання."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Пераканайцеся, што вы не праводзіце пальцам занадта блізка да ніжняга краю экрана."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Вы навучыліся рабіць жэст для пераходу назад"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Не праводзьце пальцам занадта блізка да ніжняга краю экрана"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Каб змяніць адчувальнасць жэста вяртання, адкрыйце налады"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Правядзіце пальцам, каб вярнуцца"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Каб вярнуцца на папярэдні экран, правядзіце пальцам ад левага ці правага краю да цэнтра экрана."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Каб вярнуцца на папярэдні экран, правядзіце двума пальцамі ад левага ці правага краю ў цэнтр экрана."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Назад"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Пераканайцеся, што праводзіце пальцам па экране знізу ўверх."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Пераканайцеся, што не затрымліваецеся перад адпусканнем."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Пераканайцеся, што праводзіце пальцам вертыкальна."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Вы навучыліся рабіць жэст пераходу на галоўны экран. А зараз даведайцеся, як вярнуцца назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Вы навучыліся рабіць жэст пераходу на галоўны экран."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Правядзіце пальцам па экране злева направа ці справа налева ў цэнтр экрана"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Правядзіце пальцам знізу ўверх з ніжняга краю экрана"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Перш чым адпусціць палец, не затрымлівайце яго на адным месцы"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Правядзіце пальцам па экране роўна ўверх"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Вы навучыліся рабіць жэст для пераходу на галоўны экран. Зараз вы даведаецеся, як пераходзіць назад."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Вы навучыліся рабіць жэст для пераходу на галоўны экран"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Правядзіце пальцам для пераходу на галоўны экран"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Правядзіце пальцам па экране знізу ўверх. Гэты жэст дазваляе вярнуцца на Галоўны экран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Правядзіце двума пальцамі па экране знізу ўверх. Гэты жэст дазваляе вярнуцца на Галоўны экран."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Перайсці на галоўны экран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Каб у любы час адкрыць галоўны экран, правядзіце пальцам па экране знізу ўверх"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Пераканайцеся, што праводзіце пальцам па экране знізу ўверх."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Перш чым адпусціць палец, паспрабуйце даўжэй утрымліваць акно націснутым."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Пераканайцеся, што праводзіце пальцам вертыкальна, а потым затрымліваеце яго."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Пераход на галоўны экран"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Правядзіце пальцам па экране знізу ўверх"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"У вас добра атрымліваецца!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Правядзіце пальцам знізу ўверх з ніжняга краю экрана"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Перш чым адпусціць палец, паспрабуйце даўжэй утрымліваць акно націснутым"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Правядзіце пальцам па экране роўна ўверх, а потым затрымайце палец"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Вы навучыліся выкарыстоўваць жэсты. Каб выключыць жэсты, адкрыйце Налады."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Вы навучыліся рабіць жэст пераключэння паміж праграмамі."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Вы навучыліся рабіць жэст для пераключэння паміж праграмамі"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Правядзіце пальцам для пераключэння паміж праграмамі"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Каб пераключыцца на іншую праграму, правядзіце па экране знізу ўверх, патрымайце палец і адпусціце."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Каб пераключыцца на іншую праграму, правядзіце двума пальцамі знізу ўверх, патрымайце і адпусціце."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Пераключэнне праграм"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Правядзіце пальцам уверх ад ніжняга краю экрана, затрымайце палец, а потым адпусціце"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Выдатна!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Гатова"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Гатова"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Налады"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Здымак экрана"</string>
<string name="action_split" msgid="2098009717623550676">"Падзелены экран"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Каб падзяліць экран, націсніце на іншую праграму"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Выйсці з рэжыму падзеленага экрана"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Каб падзяліць экран, выберыце іншую праграму"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Гэта дзеянне не дазволена праграмай ці вашай арганізацыяй"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Прапусціць дапаможнік па навігацыі?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Панэль задач паказана"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Панэль задач схавана"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Панэль навігацыі"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Заўсёды паказваць панэль задач"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Змяніць рэжым навігацыі"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Раздзяляльнік панэлі задач"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перамясціць уверх/улева"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перамясціць уніз/управа"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Паказаць ячшэ # праграму.}one{Паказаць ячшэ # праграму.}few{Паказаць ячшэ # праграмы.}many{Паказаць ячшэ # праграм.}other{Паказаць ячшэ # праграмы.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> і <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Дадаванне праграмы на камп\'ютар"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Скасаваць"</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 1222afa..72e731a 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предложенията за приложения са активирани"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функцията „Предложения за приложения“ е деактивирана"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидено приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Трябва да прекарате пръст от най-дясната или най-лявата част на екрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Трябва да прекарате пръст от десния или левия край на екрана до средата, след което да освободите."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Завъртете устройството си"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Моля, завъртете устройството си, за да завършите урока за навигиране с жестове"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Трябва да плъзнете пръст от най-дясната или най-лявата част на екрана"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Трябва да плъзнете пръст от десния или левия край до средата на екрана, след което да го отпуснете"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научихте жеста за връщане с плъзгане от дясно. Сега научете как се превключва между приложения."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Изпълнихте жеста за връщане назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не прекарвайте пръст твърде близо до долната част на екрана."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Изпълнихте жеста за връщане назад"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Не плъзвайте пръста си твърде близо до долната част на екрана"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Променете чувств. на жеста за връщане назад от настройките"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Жест за връщане назад"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"За да се върнете на предишния екран, прекарайте пръст от левия или десния край на екрана до средата."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"За да се върнете на предишния екран, плъзнете пръст от левия или десния край на екрана до средата."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"За да се върнете към последния екран, прекарайте два пръста от левия или десния край на екрана до средата."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Връщане назад"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Трябва да прекарате пръст нагоре от долния край на екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не задържайте, преди да вдигнете пръста си."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Трябва да прекарате пръст право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Изпълнихте жеста за преминаване към началния екран. В следващия урок ще научите как да се върнете назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Изпълнихте жеста за преминаване към началния екран."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Плъзнете пръст от левия или десния край до средата на екрана"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Трябва да плъзнете пръст нагоре от долния край на екрана"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Не задържайте, преди да вдигнете пръста си"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Трябва да плъзнете пръст право нагоре"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Изпълнихте жеста за преминаване към началния екран. В следващия урок ще научите как се връща назад."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Изпълнихте жеста за преминаване към началния екран"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Жест за преминаване към началния екран"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Прекарайте пръст нагоре от долната част на екрана. Този жест винаги ще ви отвежда до началния екран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Прекарайте два пръста нагоре от долната част на екрана. Този жест винаги води до началния екран."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Отваряне на началния екран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"За да отворите началния си екран по всяко време, прекарайте пръст нагоре от долната част на екрана"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Трябва да прекарате пръст нагоре от долния край на екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Задръжте прозореца по-дълго, преди да вдигнете пръста си."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Прекарайте пръст право нагоре, след което задръжте."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Плъзнете пръст нагоре от долната част на екрана"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Отлично!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Трябва да плъзнете пръст нагоре от долния край на екрана"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Задръжте прозореца по-дълго, преди да вдигнете пръста си"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Плъзнете пръст право нагоре, след което задръжте"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Научихте как да използвате жестовете. За да ги изключите, отворете настройките."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Изпълнихте жеста за превключване между приложения."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Изпълнихте жеста за превключване между приложения"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Жест за превключване между приложенията"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За превключване прекарайте пръст нагоре от долната част на екрана, задръжте и освободете"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За превключване плъзнете пръст нагоре от долната част на екрана, задръжте и освободете."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"За превключване на прил. плъзнете 2 пръста нагоре от долната част на екрана, задръжте и освободете."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Превключване на приложенията"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Плъзнете пръст нагоре от долната част на екрана, задръжте и след това го вдигнете"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Браво!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Настройки"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудесно!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Урок <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="459504134589971527">"Прекарайте пръст нагоре, за да отворите началния екран"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Плъзнете пръст нагоре, за да отворите началния екран"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Докоснете бутона „Начало“, за да преминете към началния екран"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Можете да започнете да използвате <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"устройството"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Екранна снимка"</string>
<string name="action_split" msgid="2098009717623550676">"Разделяне на екрана"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Докоснете друго прил., за да ползвате разд. екран"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Изход от избора на разделен екран"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"За разделен екран изберете още едно приложение"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Това действие не е разрешено от приложението или организацията ви"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропускане на урока за навигиране?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Лентата на задачите се показва"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Лентата на задачите е скрита"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Лента за навигация"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Лентата на задачите винаги да се показва"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Промяна на режима на навигация"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Разделител на лентата на задачите"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Преместване горе/вляво"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Преместване долу/вдясно"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Показване на още # приложение.}other{Показване на още # приложения.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> и <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Приложението се добавя на настолния компютър"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Отказ"</string>
</resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 8f9fbee..0973a50 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"অ্যাপ সাজেশন চালু করা আছে"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"অ্যাপ সাজেশন বন্ধ করা আছে"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"স্ক্রিনের একেবারে ডান বা বাঁদিকের প্রান্ত থেকে সোয়াইপ করেছেন কিনা তা দেখে নিন।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"স্ক্রিনের ডান বা বাঁদিকের প্রান্ত থেকে মাঝখান পর্যন্ত সোয়াইপ করে আঙুল তুলে নিয়েছেন কিনা তা দেখে নিন।"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"আপনার ডিভাইস ঘোরান"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"জেসচার নেভিগেশন টিউটোরিয়াল সম্পূর্ণ করতে আপনার ডিভাইসটি ঘোরান"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"স্ক্রিনের একেবারে ডান বা বাঁদিকের প্রান্ত থেকে সোয়াইপ করেছেন কিনা তা দেখে নিন"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"স্ক্রিনের ডান বা বাঁদিকের প্রান্ত থেকে মাঝখান পর্যন্ত সোয়াইপ করেছেন কিনা দেখে নিয়ে আঙুল তুলে নিন"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ফিরে যেতে, কীভাবে ডানদিক থেকে সোয়াইপ করতে হয় তা আপনি শিখেছেন। এরপর, একটি অ্যাপ থেকে অন্য অ্যাপে কীভাবে যাবেন জেনে নিন।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"আপনি ফিরে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"স্ক্রিনের নিচের প্রান্তের খুব কাছে পর্যন্ত যাতে সোয়াইপ না করেন সেটি ভাল করে দেখে নিন।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"আপনি জেনেছেন হাতের জেসচার ব্যবহার করে আগের স্ক্রিনে কীভাবে ফিরে যাওয়া যায়"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"স্ক্রিনের নিচের প্রান্তের খুব কাছে পর্যন্ত যাতে সোয়াইপ না করেন সেটি ভাল করে দেখে নিন"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ফিরে যাওয়ার জেসচারের সেন্সিটিভিটি পরিবর্তন করতে, সেটিংসে যান"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ফিরে যেতে সোয়াইপ করুন"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"শেষের স্ক্রিনে ফিরে যেতে, ডান বা বাঁ প্রান্ত থেকে স্ক্রিনের মাঝখান পর্যন্ত সোয়াইপ করুন।"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"শেষ স্ক্রিনে ফিরতে, বাম বা ডান প্রান্ত থেকে স্ক্রিনের মাঝামাঝি পর্যন্ত ২টি আঙুল দিয়ে সোয়াইপ করুন।"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ফিরে যান"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"আঙুল তুলে নেওয়ার আগে আপনি যাতে পজ না করেন সেটি ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"আপনি হোম স্ক্রিনে যাওয়ার জেসচার সম্পর্কে জেনেছেন। এরপর, ফিরে কীভাবে যাবেন তা জেনে নিন।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"আপনি হোম স্ক্রিনে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"স্ক্রিনের বাঁদিক বা ডানদিক থেকে মাঝখানে সোয়াইপ করুন"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"আঙুল তুলে নেওয়ার আগে আপনি যাতে পজ না করেন সেটি ভাল করে দেখে নিন"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"আপনি জেনেছেন হাতের জেসচার ব্যবহার করে হোম স্ক্রিনে কীভাবে যাওয়া যায়। এরপর, ফিরে কীভাবে যাবেন তা জেনে নিন।"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"আপনি জেনেছেন হাতের জেসচার ব্যবহার করে হোম স্ক্রিনে কীভাবে যাওয়া যায়"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"হোম স্ক্রিনে যেতে সোয়াইপ করুন"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"স্ক্রিনের নিচের প্রান্ত থেকে উপরের দিকে সোয়াইপ করুন। এটি করলে, আপনি সবসময় হোম স্ক্রিনে যেতে পারবেন।"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"স্ক্রিনের নিচ থেকে ২টি আঙুল দিয়ে উপরে সোয়াইপ করুন। এই জেসচার সবসময় আপনাকে হোম স্ক্রিনে নিয়ে যায়।"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"হোমে যান"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"যেকোনও সময় আপনার হোম স্ক্রিনে যেতে, স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করুন"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"চেষ্টা করুন যাতে আঙুল সরিয়ে নেওয়ার আগে উইন্ডো কিছুক্ষণ প্রেস করে রাখা যায়।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিয়ে তারপর পজ করুন।"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"হোম স্ক্রিনে যান"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"আপনার স্ক্রিনের একেবারে নিচ থেকে সোয়াইপ করুন"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"অসাধারণ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"চেষ্টা করুন যাতে আঙুল সরিয়ে নেওয়ার আগে উইন্ডো বেশ কিছুক্ষণ প্রেস করে রাখা যায়"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিয়ে তারপর পজ করুন"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"জেসচার কীভাবে ব্যবহার করতে হয় আপনি তা শিখে ফেলেছেন। জেসচার বন্ধ করতে, সেটিংসে যান।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"আপনি একটি অ্যাপ থেকে অন্য অ্যাপে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"আপনি জেনেছেন যে হাতের জেসচার ব্যবহার করে একটি অ্যাপ থেকে অন্য অ্যাপে কীভাবে যাওয়া যায়"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"একটি অ্যাপ থেকে অন্য অ্যাপে যেতে সোয়াইপ করুন"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"একটি অ্যাপ থেকে অন্যটিতে পাল্টাতে, স্ক্রিনের নিচ থেকে উপরে সোয়াইপ করে ধরে রাখুন, তারপরে ছেড়ে দিন।"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"একটি থেকে অন্য অ্যাপে পাল্টাতে, ২টি আঙুল দিয়ে স্ক্রিনের নিচ থেকে উপরে সোয়াইপ করে ধরে রেখে ছেড়ে দিন।"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"অ্যাপ পরিবর্তন করুন"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"স্ক্রিনের নিচের থেকে উপরের দিকে সোয়াইপ করে ধরে থাকুন, তারপরে ছেড়ে দিন"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"শাবাশ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"সব প্রস্তুত"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"সম্পূর্ণ হয়েছে"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"সেটিংস"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"স্ক্রিনশট নিন"</string>
<string name="action_split" msgid="2098009717623550676">"স্প্লিট"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"স্প্লিট স্ক্রিন ব্যবহারের জন্য অ্যাপে ট্যাপ করুন"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"স্প্লিট স্ক্রিন বেছে নেওয়ার বিকল্প থেকে বেরিয়ে আসুন"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"স্প্লিট স্ক্রিন ব্যবহার করতে অন্য অ্যাপ বেছে নিন"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"এই অ্যাপ বা আপনার প্রতিষ্ঠান এই অ্যাকশনটি পারফর্ম করার অনুমতি দেয়নি"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"নেভিগেশন টিউটোরিয়াল এড়িয়ে যেতে চান?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"\'টাস্কবার\' দেখানো হয়েছে"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"\'টাস্কবার\' লুকানো রয়েছে"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"নেভিগেশন বার"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"সবসময় টাস্কবার দেখুন"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"\'নেভিগেশন\' মোড পরিবর্তন করুন"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"টাস্কবার ডিভাইডার"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"উপরে/বাঁদিকে সরান"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"নিচে/ডানদিকে সরান"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{আরও #টি অ্যাপ দেখুন।}one{আরও #টি অ্যাপ দেখুন।}other{আরও #টি অ্যাপ দেখুন।}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ও <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ডেস্কটপে অ্যাপ যোগ করা হচ্ছে"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"বাতিল করুন"</string>
</resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 691c720..a2e4e33 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Prijedlozi aplikacija su omogućeni"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Prijedlozi aplikacija su onemogućeni"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Vodite računa da prevučete s krajnjeg desnog ili krajnjeg lijevog ruba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Vodite računa da prevučete s desnog ili lijevog ruba prema sredini ekrana i pustite."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotirajte uređaj"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotirajte uređaj da završite vodič za navigaciju pokretima"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Prevucite s krajnjeg desnog ili krajnjeg lijevog ruba"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Prevucite s desnog ili lijevog ruba prema sredini ekrana i pustite"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako prevući zdesna da se vratite. Sljedeće naučite kako prebacivati između aplikacija."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Savladali ste pokret za vraćanje."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Obratite pažnju da ne prevučete preblizu donjem dijelu ekrana."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Savladali ste pokret za vraćanje"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pazite da ne prevučete preblizu donjem dijelu ekrana"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Promijenite osjetljivost pokreta za povratak u Postavkama"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Prevucite da se vratite"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da se vratite na posljednji ekran, prevucite s lijevog ili desnog ruba prema sredini ekrana."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da se vratite na prethodni ekran, prevucite s lijevog ili desnog ruba prema sredini ekrana."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Da se vratite na posljednji ekran, prevucite s 2 prsta od lijevog ili desnog ruba do sredine ekrana."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Nazad"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Trebate prevući prema gore s donjeg ruba ekrana."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Obratite pažnju da ne zastanete prije puštanja."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Trebate prevući ravno prema gore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Savladali ste pokret za otvaranje početnog ekrana. Sljedeće naučite kako se vratiti."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Savladali ste pokret za otvaranje početnog ekrana."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Vratite se nazad"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Prevucite s lijevog ili desnog ruba prema sredini ekrana"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Prevucite prema gore s donjeg ruba ekrana"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pazite da ne zastanete prije puštanja"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Prevucite ravno nagore"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Savladali ste pokret za otvaranje početnog ekrana. Sljedeće naučite kako se vratiti."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Savladali ste pokret za otvaranje početnog ekrana"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Prevucite da odete na početni ekran"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prevucite s dna ekrana prema gore. Tim pokretom uvijek idete na početni ekran."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Prevucite s 2 prsta od dna ekrana. Tim pokretom uvijek idete na početni ekran"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Odlazak na početni ekran"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Idite na početni ekran u bilo kojem trenutku, prevucite s donjeg dijela ekrana nagore"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Trebate prevući prema gore s donjeg ruba ekrana."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pokušajte zadržati prozor duže prije puštanja."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Trebate prevući ravno prema gore, a zatim zastati."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Idite na početni ekran"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Prevucite s dna ekrana prema gore"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Sjajno!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Vodite računa da prevučete s donjeg ruba ekrana prema gore"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Pokušajte zadržati prozor duže prije puštanja"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Prevucite ravno nagore, a zatim zastanite"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste kako koristiti pokrete. Idite u Postavke da isključite pokrete."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Savladali ste pokret za prebacivanje između aplikacija."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Savladali ste pokret za prebacivanje između aplikacija"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prevucite da prebacujete između aplikacija"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Da prebacujete između aplikacija, prevucite s dna ekrana prema gore, zadržite, a zatim pustite."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Da se prebacujete između aplikacija, prevucite s dna ekrana nagore, zadržite, a zatim pustite."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Da se prebacujete između aplikacija, prevucite s 2 prsta od dna ekrana, zadržite, a zatim pustite."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Prebacujte se između aplikacija"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Prevucite s dna ekrana prema gore, zadržite, a zatim pustite"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Odlično!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Sve je spremno"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Postavke"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Sve je spremno!"</string>
<string name="allset_hint" msgid="459504134589971527">"Prevucite prema gore da odete na početni ekran"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Dodirnite dugme za početni ekran da odete napočetni ekran"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Sve je spremno da počnete koristiti uređaj <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Spremni ste da počnete koristiti <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"uređaj"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Postavke navigiranja sistemom"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Dijeli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
<string name="action_split" msgid="2098009717623550676">"Podijeli"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Dodirnite drugu apl. da koristite podijeljeni ekran"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Izlaz iz odabira podijeljenog ekrana"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Odaberite drugu apl. da koristite podijeljeni ekran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ovu radnju ne dozvoljava aplikacija ili vaša organizacija"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Preskočiti vodič za navigiranje?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Traka zadataka je prikazana"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Traka zadataka je sakrivena"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigaciona traka"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Uvijek prikaži traku zadataka"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Promijeni način navigacije"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Razdjelnik trake zadataka"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premjesti gore lijevo"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premjesti dolje desno"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Prikaži još # aplikaciju.}one{Prikaži još # aplikaciju.}few{Prikaži još # aplikacije.}other{Prikaži još # aplikacija.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> i <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Dodavanje aplikacije na radnu površinu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Otkaži"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 919712a..0cfe820 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Els suggeriments d\'aplicacions estan activats"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Els suggeriments d\'aplicacions estan desactivats"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicció d\'aplicació: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assegura\'t de lliscar des de l\'extrem dret o esquerre de la pantalla."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Assegura\'t de lliscar des de la vora dreta o esquerra cap al centre de la pantalla i deixar anar."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Has après com pots lliscar des de la dreta per tornar enrere. Ara, descobreix com pots canviar d\'app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Has completat el gest per tornar enrere."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assegura\'t de no lliscar massa a prop de la part inferior de la pantalla."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gira el dispositiu"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gira el dispositiu per completar el tutorial de navegació amb gestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assegura\'t de lliscar des de l\'extrem dret o esquerre de la pantalla."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Assegura\'t de lliscar des de la vora dreta o esquerra cap al centre de la pantalla i deixar anar"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Has après a lliscar des de la dreta per tornar enrere. Ara, descobreix com pots canviar d\'aplicació."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Has completat el gest per tornar enrere"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Assegura\'t de no lliscar massa a prop de la part inferior de la pantalla."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Per canviar la sensibilitat del gest, ves a Configuració"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Llisca per anar enrere"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Per tornar a la darrera pantalla, llisca des de la vora esquerra o dreta cap al centre de la pantalla."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Per tornar a la pantalla anterior, llisca amb dos dits des de l\'extrem esquerre o dret cap al centre de la pantalla."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Torna"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assegura\'t de lliscar des de la vora inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assegura\'t de no aturar-te abans de deixar anar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assegura\'t de lliscar directament cap amunt."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Has completat el gest per anar a la pantalla d\'inici. Ara, descobreix com pots tornar enrere."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Has completat el gest per anar a la pantalla d\'inici."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Torna enrere"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Llisca des de la vora esquerra o dreta cap al centre de la pantalla."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Assegura\'t de lliscar cap amunt des de la part inferior de la pantalla"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Assegura\'t de no aturar-te abans de deixar anar."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Assegura\'t de lliscar recte cap amunt."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Has completat el gest per anar a la pantalla d\'inici. Ara, descobreix com pots tornar enrere."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Has completat el gest per anar a la pantalla d\'inici"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Llisca per anar a la pantalla d\'inici"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Llisca cap amunt des de la part inferior de la pantalla. Aquest gest et porta a la pantalla d\'inici."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Llisca amb dos dits cap amunt des de la part inferior. Aquest gest sempre porta a la pantalla d\'inici."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ves a la pàgina d\'inici"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Per anar a la pantalla d\'inici en qualsevol moment, llisca cap amunt des la part inferior"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assegura\'t de lliscar des de la vora inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prova de mantenir premuda la finestra durant més temps abans de deixar-la anar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assegura\'t de lliscar directament cap amunt i després aturar-te."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Llisca cap amunt des de la part inferior de la pantalla."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Ben fet!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Assegura\'t de lliscar cap amunt des de la part inferior de la pantalla."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prova de mantenir premuda la finestra durant més temps abans de deixar-la anar"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Assegura\'t de lliscar directament cap amunt i després aturar-te"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Has après a utilitzar els gestos. Per desactivar-los, ves a Configuració."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Has completat el gest per canviar d\'aplicació."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Has completat el gest per canviar d\'aplicació"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Llisca per canviar d\'aplicació"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Per canviar entre aplicacions, llisca cap amunt des de la part inferior, mantén premut i deixa anar."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Per canviar entre apps, llisca amb dos dits cap amunt des de la part inferior, mantén i deixa anar."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Canvia d\'aplicació"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Llisca cap amunt des de la part inferior de la pantalla, mantén premut i, a continuació, deixa anar."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Ben fet!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tot a punt"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fet"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuració"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Tot a punt!"</string>
<string name="allset_hint" msgid="459504134589971527">"Llisca cap amunt per anar a la pàgina d\'inici"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Toca el botó d\'inici per anar a la pantalla d\'inici"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Ja pots començar a utilitzar <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Ja pots començar a utilitzar el <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"dispositiu"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Configuració de navegació del sistema"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Comparteix"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
<string name="action_split" msgid="2098009717623550676">"Divideix"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Toca una altra app per utilitzar pantalla dividida"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Surt de la selecció de pantalla dividida"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Tria una altra app per utilitzar pantalla dividida"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"L\'aplicació o la teva organització no permeten aquesta acció"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vols ometre el tutorial de navegació?"</string>
@@ -97,11 +104,11 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omet"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Gira la pantalla"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informació sobre Barra de tasques"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arrossega una app al costat per utilitzar 2 apps alhora"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arrossega una aplicació al costat per utilitzar-ne dues alhora"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Llisca lentament cap amunt per mostrar la Barra de tasques"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Obtén suggeriments d\'aplicacions basats en la teva rutina"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"A Configuració, activa la navegació amb gestos per amagar la Barra de tasques automàticament"</string>
- <string name="taskbar_edu_features" msgid="3320337287472848162">"Fes més coses amb la Barra de tasques"</string>
+ <string name="taskbar_edu_features" msgid="3320337287472848162">"Treu més partit de la Barra de tasques"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Fet"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Inici"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Es mostra la Barra de tasques"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"S\'ha amagat la Barra de tasques"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegació"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Mostra sempre Barra de tasques"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Canvia el mode de navegació"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Separador de la Barra de tasques"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mou a la part superior o a l\'esquerra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mou a la part inferior o a la dreta"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostra # aplicació més.}other{Mostra # aplicacions més.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> i <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"S\'està afegint l\'aplicació a l\'ordinador"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel·la"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 5ac7e7e..3582005 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -44,51 +44,58 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikací jsou povoleny"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikací jsou zakázány"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Předpokládaná aplikace: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Přejeďte prstem z úplného pravého nebo levého okraje obrazovky."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Přejeďte prstem z pravého nebo levého okraje doprostřed obrazovky a zdvihněte prst."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili jste se, jak se vrátit zpět přejetím prstem zprava. Teď se naučíte přepínat aplikace."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dokončili jste gesto pro přechod zpět."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Dejte pozor, abyste prstem nepřejížděli moc blízko ke spodnímu okraji obrazovky."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Otočte zařízení"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pokud chcete dokončit výukový program navigace gesty, otočte zařízení"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Přejeďte prstem z úplného pravého nebo levého okraje obrazovky"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Přejeďte prstem z pravého nebo levého okraje doprostřed obrazovky a zdvihněte prst"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili jste se, jak se vrátit zpět přejetím prstem zprava. Teď se naučíte přepínat mezi aplikacemi."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Dokončili jste gesto pro přechod zpět"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Dejte pozor, abyste prstem nepřejížděli moc blízko ke spodnímu okraji obrazovky"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Citlivost gesta pro přechod zpět můžete změnit v Nastavení"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Přejetím prstem se vrátíte zpět"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"K návratu na poslední obrazovku přejeďte prstem z levého nebo pravého okraje obrazovky doprostřed."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Na předchozí obrazovku se vrátíte tak, že přejedete prstem z levého nebo pravého okraje obrazovky doprostřed."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Pokud se chcete vrátit na poslední obrazovku, přejeďte dvěma prsty z levého nebo pravého okraje doprostřed obrazovky."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Zpět"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Přejeďte prstem nahoru z dolního okraje obrazovky."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Před zdvihnutím prstu nedělejte pauzu."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Přejeďte prstem přímo nahoru."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dokončili jste gesto pro přechod na plochu. Teď se naučíte vrátit se zpět."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dokončili jste gesto pro přechod na plochu."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Návrat zpět"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Přejeďte prstem z levého nebo pravého okraje do středu obrazovky"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Přejeďte prstem nahoru z dolního okraje obrazovky"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Před zdvihnutím prstu nedělejte pauzu"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Přejeďte prstem přímo nahoru"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Dokončili jste gesto pro přechod na plochu. Teď se naučíte vrátit se zpět."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Dokončili jste gesto pro přechod na plochu"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Přechod na plochu přejetím prstem"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Přejeďte prstem ze spodní části obrazovky nahoru. Tímto gestem se vždy dostanete na plochu."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Přejeďte dvěma prsty z dolního okraje obrazovky nahoru. Tímto gestem se vždy dostanete na plochu."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Přejít na plochu"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Na plochu kdykoli přejdete přejetím prstem ze spodní části obrazovky nahoru"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Přejeďte prstem nahoru z dolního okraje obrazovky."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Zkuste podržet okno delší dobu, než ho uvolníte."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Přejeďte prstem přímo nahoru a pak udělejte pauzu."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili jste se používat gesta. Gesta můžete vypnout v nastavení."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dokončili jste gesto pro přepínání aplikací."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Přechod na plochu"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Přejeďte prstem ze spodní části obrazovky nahoru"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Výborně!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Přejeďte prstem nahoru z dolního okraje obrazovky"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Zkuste podržet okno delší dobu, než ho uvolníte"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Přejeďte prstem přímo nahoru a pak udělejte pauzu"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili jste se používat gesta. Vypnout je můžete v nastavení."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Dokončili jste gesto pro přepínání aplikací"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Přepínání aplikací přejetím prstem"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Přepínání mezi aplikacemi: Přejeďte nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Přejeďte nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Přepínání mezi aplikacemi: Přejeďte dvěma prsty nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Přepnout aplikace"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Přepínání aplikací"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Přejeďte prstem nahoru z dolního okraje obrazovky, podržte obrazovku a potom prst uvolněte"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Výborně!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Vše je nastaveno"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hotovo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavení"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zkusit znovu"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zkuste to znovu"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Skvělé!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Výukový program <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Hotovo!"</string>
<string name="allset_hint" msgid="459504134589971527">"Přejetím nahoru se vrátíte na plochu"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Klepnutím na tlačítko plochy se vrátíte na plochu"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Jste připraveni začít používat <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"<xliff:g id="DEVICE">%1$s</xliff:g> můžete začít používat"</string>
<string name="default_device_name" msgid="6660656727127422487">"zařízení"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Nastavení navigace v systému"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Sdílet"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snímek obrazovky"</string>
<string name="action_split" msgid="2098009717623550676">"Rozdělit"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Klepnutím na jinou aplikaci rozdělíte obrazovku"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Obrazovku rozdělíte klepnutím na jinou aplikaci"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Výběr opuštění rozdělené obrazovky"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Vyberte podporovanou aplikaci"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikace nebo organizace zakazuje tuto akci"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Přeskočit výukový program k navigaci?"</string>
@@ -99,9 +106,9 @@
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informace o panelu aplikací"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Přetáhněte aplikaci na stranu a používejte tak dvě najednou"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Panel aplikací zobrazíte pomalým přejetím prstem nahoru"</string>
- <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Získejte návrhy aplikací na základě vašeho používání"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dostávejte návrhy aplikací podle toho, jaké používáte"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Pokud chcete panel aplikací automaticky skrýt, zapněte v Nastavení navigaci gesty"</string>
- <string name="taskbar_edu_features" msgid="3320337287472848162">"Pomocí panelu aplikací můžete dělat více věcí"</string>
+ <string name="taskbar_edu_features" msgid="3320337287472848162">"Více možností s panelem aplikací"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Domů"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Panel aplikací je zobrazen"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Panel aplikací je skrytý"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigační panel"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Vždy zobrazovat panel aplikací"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Změnit režim navigace"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Rozdělovač panelu aplikací"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Přesunout doleva nahoru"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Přesunout doprava dolů"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Zobrazit # další aplikaci.}few{Zobrazit # další aplikace.}many{Zobrazit # další aplikace.}other{Zobrazit # dalších aplikací.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> a <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Přidání aplikace na plochu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Zrušit"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index d0cea4c..1603fac 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -44,41 +44,47 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er aktiveret"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er deaktiveret"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App, du forventes at skulle bruge: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Stryg fra kanten yderst til højre eller venstre."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Stryg fra højre eller venstre kant mod midten af skærmen, og løft fingeren."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotér din enhed"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotér enheden for at gennemgå vejledningen i navigation med bevægelser"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Stryg fra kanten yderst til højre eller venstre"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Stryg fra højre eller venstre kant mod midten af skærmen, og løft fingeren"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du har lært, hvordan du stryger fra højre for at gå tilbage. Nu skal du se, hvordan du skifter app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du har fuldført bevægelsen for Gå tilbage."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Undgå at stryge for tæt på bunden af skærmen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du har fuldført bevægelsen for Gå tilbage"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Undgå at stryge for tæt på bunden af skærmen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Juster følsomheden for bevægelsen Gå tilbage i Indstillinger"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Stryg for at gå tilbage"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Stryg mod midten af skærmen fra venstre eller højre kant for at gå tilbage til den seneste skærm."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Du kan gå tilbage til forrige skærm ved at stryge fra venstre eller højre kant mod midten af skærmen med 2 fingre."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Gå tilbage"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Stryg opad fra bunden af skærmen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Undlad at holde fingeren stille, indtil du løfter fingeren."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Stryg lige opad."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du har fuldført bevægelsen for Gå til startskærmen. Som det næste kan du se, hvordan du går tilbage."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du har fuldført bevægelsen for Gå til startskærmen."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Stryg fra venstre eller højre kant til midten af skærmen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Stryg opad fra bunden af skærmen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Undlad at holde fingeren stille, indtil du løfter fingeren"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Stryg lige opad"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du har fuldført bevægelsen for Gå til startskærmen. Som det næste kan du se, hvordan du går tilbage."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du har fuldført bevægelsen for Gå til startskærmen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Stryg for at gå til startskærmen"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Stryg opad fra bunden af skærmen. Denne bevægelse åbner altid startskærmen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Stryg opad med 2 fingre fra bunden af skærmen. Denne bevægelse åbner altid startskærmen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Gå til startskærmen"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Du kan altid gå til startskærmen ved at stryge opad fra bunden af skærmen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Stryg opad fra bunden af skærmen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prøv at holde fingeren nede på vinduet i længere tid, inden du løfter den."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Stryg lige opad, og hold derefter fingeren stille."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Stryg opad fra bunden af skærmen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Flot!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Stryg opad fra bunden af skærmen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prøv at holde fingeren nede på vinduet i længere tid, inden du løfter den"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Stryg lige opad, og hold derefter fingeren stille"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lært, hvordan du bruger bevægelser. Du kan aktivere bevægelser i Indstillinger."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du har fuldført bevægelsen for Skift app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du har fuldført bevægelsen for at skifte mellem apps"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Stryg for at skifte app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Skift mellem apps ved at stryge opad fra bunden af skærmen, holde fingeren stille og løfte den."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Skift mellem apps ved at stryge opad fra bunden af skærmen med 2 fingre, holde dem nede og slippe."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Skift mellem apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Stryg opad fra bunden af skærmen, hold fingeren nede, og slip"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Flot!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Så er du klar"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Luk"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Indstillinger"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Prøv igen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Sådan!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Selvstudie <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="gesture_tutorial_step" msgid="1279786122817620968">"Vejledning <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Alt er parat!"</string>
<string name="allset_hint" msgid="459504134589971527">"Stryg opad for at gå til startsiden"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Tryk på knappen Hjem for at gå til din startskærm"</string>
@@ -89,9 +95,10 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Opdel"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tryk på en anden app for at bruge opdelt skærm"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Luk valg af opdelt skærm"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Vælg en anden app for at bruge opdelt skærm"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller din organisation tillader ikke denne handling"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vil du springe selvstudiet for navigation over?"</string>
+ <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vil du springe vejledningen for navigation over?"</string>
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finde dette senere i appen <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuller"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Spring over"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Proceslinjen vises"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Proceslinjen er skjult"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigationslinje"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Vis altid proceslinjen"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Skift navigationstilstand"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Opdeling af proceslinjen"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flyt til toppen eller venstre side"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flyt til bunden eller højre side"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Vis # app mere.}one{Vis # app mere.}other{Vis # apps mere.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> og <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Appen føjes til computeren"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annuller"</string>
</resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index d906ab8..828b85f 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Funktion „App-Vorschläge“ aktiviert"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Funktion \"App-Vorschläge\" deaktiviert"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Vorgeschlagene App: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Wische vom äußersten rechten oder linken Displayrand."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Wische vom rechten oder linken Displayrand zur Displaymitte und lass los."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gerät drehen"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Bitte drehe dein Gerät, um die Anleitung für die Bedienung über Gesten abzuschließen"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Wische vom äußersten rechten oder linken Displayrand"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Wische vom rechten oder linken Displayrand zur Displaymitte und lass los"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du hast jetzt gelernt, vom rechten Displayrand aus zu wischen, um zurückzugehen. Gleich erfährst du, wie man zwischen Apps wechselt."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du hast die „Zurück“-Touch-Geste abgeschlossen."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Wische nicht zu nah am unteren Displayrand."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du hast den Schritt für die „Zurück“-Touch-Geste abgeschlossen"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Wische nicht zu nah an den unteren Displayrand"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Du kannst die Empfindlichkeit von „Zurück“ in den Einstellungen ändern"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Zum Zurückgehen wischen"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Wenn du zum letzten Bildschirm zurückgehen möchtest, wische vom linken oder rechten Rand zur Mitte."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Wenn du zum letzten Bildschirm zurückgehen möchtest, wische mit zwei Fingern vom linken oder rechten Displayrand zur Mitte."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Zurück"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Wische vom unteren Displayrand nach oben."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Achte darauf, nicht innezuhalten, bevor du loslässt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Wische gerade nach oben."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du hast die Touch-Geste zum Aufrufen des Startbildschirms abgeschlossen. Gleich erfährst du, wie du zurückgelangst."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du hast die Touch-Geste zum Aufrufen des Startbildschirms abgeschlossen."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Wische vom linken oder rechten Displayrand bis zur Mitte des Displays"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Wische vom unteren Displayrand nach oben"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Achte darauf, nicht innezuhalten, bevor du loslässt"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Wische gerade nach oben"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du hast den Schritt für die „Zum Startbildschirm“-Geste abgeschlossen. Jetzt lernst du, wie du zurückgehst."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du hast den Schritt für die „Startbildschirm“-Touch-Geste abgeschlossen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Den Startbildschirm aufrufen"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Wenn du zum Startbildschirm gehen möchtest, wische einfach vom unteren Displayrand nach oben."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Wische mit zwei Fingern vom unteren Displayrand nach oben. So gelangst du immer zum Startbildschirm."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Zum Startbildschirm"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Du kannst jederzeit zum Startbildschirm gehen, indem du vom unteren Displayrand nach oben wischst"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Wische vom unteren Displayrand nach oben."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Versuche, das Fenster länger festzuhalten, bevor du es loslässt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Wische gerade nach oben und halte dann inne."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Zum StartU+00ADbildschirm"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Wische vom unteren Displayrand nach oben"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Gut gemacht!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Wische vom unteren Displayrand nach oben"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Halte das Fenster länger gedrückt, bevor du es loslässt"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Wische gerade nach oben und halte dann inne"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Nun weißt du, wie Touch-Gesten funktionieren. Du kannst sie in den Einstellungen deaktivieren."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du hast die „Apps wechseln“-Touch-Geste abgeschlossen."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du hast den Schritt für die „Apps wechseln“-Touch-Geste abgeschlossen"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Zwischen Apps wechseln"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Wische auf dem Display von unten nach oben, halte den Finger gedrückt und lass dann los, um zwischen Apps zu wechseln."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Wische zum App-Wechseln mit zwei Fingern vom unteren Displayrand nach oben, halte und lass dann los."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Apps wechseln"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Wische auf dem Display von unten nach oben, halte es gedrückt und lass es dann los"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Perfekt!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Fertig"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fertig"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Einstellungen"</string>
@@ -88,8 +94,9 @@
<string name="action_share" msgid="2648470652637092375">"Teilen"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Teilen"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Für „Geteilter Bildschirm“ auf weitere App tippen"</string>
- <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Für geteilten Bildschirm andere App auswählen"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Für Splitscreen auf weitere App tippen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Splitscreen-Auswahl beenden"</string>
+ <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Für Splitscreen andere App auswählen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Die App oder deine Organisation lässt diese Aktion nicht zu"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Tutorial zur Bedienung überspringen?"</string>
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du findest es später auch in der <xliff:g id="NAME">%1$s</xliff:g> App"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskleiste eingeblendet"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskleiste ausgeblendet"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigationsleiste"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Taskleiste immer anzeigen"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Navigationsmodus ändern"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskleisten-Teiler"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Nach oben / Nach links verschieben"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Nach unten / Nach rechts verschieben"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# weitere App anzeigen.}other{# weitere Apps anzeigen.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> und <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Hinzufügen einer App zum Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Abbrechen"</string>
</resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 0fa67fe..ab9fe6d 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Οι προτεινόμενες εφαρμογές ενεργοποιήθηκαν"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Οι προτεινόμενες εφαρμογές είναι απενεργοποιημένες"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Εφαρμογή από πρόβλεψη: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Φροντίστε να σύρετε από το άκρο της δεξιάς ή της αριστερής πλευράς."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Σύρετε από το δεξί ή αριστερό άκρο προς το μέσο της οθόνης και απομακρύνετε το δάχτυλό σας."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Μάθατε πώς να σύρετε από τα δεξιά για επιστροφή. Στη συνέχεια, μάθετε πώς να κάνετε εναλλαγή εφαρμ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ολοκληρώσατε την κίνηση επιστροφής."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Φροντίστε να μην σύρετε υπερβολικά κοντά στο κάτω μέρος της οθόνης."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Περιστρέψτε τη συσκευή σας"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Περιστρέψτε τη συσκευή σας για να ολοκληρώσετε τον οδηγό πλοήγησης με κινήσεις"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Φροντίστε να σύρετε από το άκρο της δεξιάς ή της αριστερής πλευράς."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Σύρετε από το δεξί ή το αριστερό άκρο προς το κέντρο της οθόνης και απομακρύνετε το δάχτυλό σας"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Μάθατε πώς να σύρετε από τα δεξιά για επιστροφή. Τώρα, μάθετε πώς να κάνετε εναλλαγή εφαρμογών."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ολοκληρώσατε την κίνηση επιστροφής"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Φροντίστε να μην σύρετε υπερβολικά κοντά στο κάτω μέρος της οθόνης"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Μεταβείτε στις Ρυθμίσεις για αλλαγή ευαισθ. κίνησης επιστρ."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Σύρετε για επιστροφή"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Για να επιστρέψετε στην τελευτ. οθόνη, σύρετε από το αριστ. ή το δεξί άκρο προς το μέσο της οθόνης."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Για να επιστρέψετε στην τελευταία οθόνη, σύρετε από το αριστερό ή το δεξί άκρο προς το μέσο της οθόνης."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Για να επιστρέψετε στην προηγούμενη οθόνη, σύρετε με 2 δάχτυλα από την αριστερή ή δεξιά άκρη προς τη μέση της οθόνης."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Επιστροφή"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Φροντίστε να μην κάνετε παύση προτού απομακρύνετε τα δάχτυλά σας."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Φροντίστε να σύρετε απευθείας προς τα επάνω."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη. Στη συνέχεια, μάθετε πώς να κάνετε επιστροφή."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Σύρετε από το αριστερό ή το δεξί άκρο προς το κέντρο της οθόνης"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Φροντίστε να μην διακόψετε την κίνηση προτού απομακρύνετε τα δάχτυλά σας"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Φροντίστε να σύρετε ευθεία προς τα επάνω"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη Στη συνέχεια, μάθετε την κίνηση επιστροφής."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Σύρετε για μετάβαση στην αρχική οθόνη"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Σύρετε προς τα πάνω από το κάτω μέρος της οθόνης. Αυτή η κίνηση σάς μεταφέρει πάντα στην αρχ. οθόνη."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Σύρετε από το κάτω άκρο προς τα πάνω με 2 δάχτ. Αυτή η κίνηση σάς μεταφέρει πάντα στην αρχική οθόνη."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Αρχική"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Για μετάβαση στην αρχική οθόνη ανά πάσα στιγμή, σύρετε προς τα επάνω από το κάτω μέρος της οθόνης"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Δοκιμάστε να κρατήσετε περισσότερο το παράθυρο προτού απελευθερώσετε."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Φροντίστε να σύρετε απευθείας προς τα επάνω και έπειτα κάντε παύση."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Σύρετε προς τα επάνω από το κάτω μέρος της οθόνης"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Μπράβο!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Δοκιμάστε να κρατήσετε περισσότερο το παράθυρο προτού το αφήσετε."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Φροντίστε να σύρετε ευθεία προς τα επάνω και έπειτα σταματήστε την κίνηση"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Μάθατε πώς να χρησιμοποιείτε κινήσεις. Μεταβείτε στις Ρυθμίσεις για απενεργοποίηση των κινήσεων."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ολοκληρώσατε την κίνηση εναλλαγής εφαρμογών."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ολοκληρώσατε την κίνηση εναλλαγής εφαρμογών"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Σύρετε για εναλλαγή εφαρμογών"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Για εναλλαγή εφαρμογών, σύρετε προς τα πάνω από το κάτω μέρος της οθόνης, πατήστε παρατεταμένα και μετά αφήστε."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Για εναλλαγή μεταξύ εφαρμογών, σύρετε από κάτω προς τα πάνω με 2 δάχτ., κρατήστε και έπειτα αφήστε."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Εναλλαγή μεταξύ εφαρμογών"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Σύρετε προς τα πάνω από το κάτω μέρος της οθόνης, κρατήστε τα δάχτυλα επάνω στην οθόνη και μετά απομακρύνετέ τα"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Μπράβο!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Όλα είναι έτοιμα"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Τέλος"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ρυθμίσεις"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Στιγμιότυπο οθόνης"</string>
<string name="action_split" msgid="2098009717623550676">"Διαχωρισμός"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Πατήστε άλλη εφαρμογή για διαχωρισμό οθόνης"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Έξοδος από την επιλογή διαχωρισμού οθόνης"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Επιλέξτε άλλη εφαρμογή για διαχωρισμό οθόνης"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Αυτή η ενέργεια δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Παράβλεψη οδηγού πλοήγησης;"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Η γραμμή εργαλείων εμφανίζεται"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Η γραμμή εργαλείων είναι κρυφή"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Γραμμή πλοήγησης"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Εμφ. πάντα σε Γραμμή εργαλείων"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Αλλαγή τρόπου πλοήγησης"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Διαχωριστικό Γραμμής εργαλείων"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Μετακίνηση επάνω/αριστερά"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Μετακίνηση κάτω/δεξιά"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Εμφάνιση # ακόμα εφαρμογής.}other{Εμφάνιση # ακόμα εφαρμογών.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> και <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Γίνεται προσθήκη εφαρμογής στον υπολογιστή"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Ακύρωση"</string>
</resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index ec90faf..878c062 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Make sure you swipe from the right or left edge to the middle of the screen and let go"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You\'ve learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"You completed the go back gesture"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Make sure you don\'t swipe too close to the bottom of the screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"To go back to the last screen, swipe with two fingers from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Go back"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You\'ve completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe from the left or right edge to the middle of the screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Make sure you don\'t pause before letting go"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Make sure you swipe straight up"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"You completed the go home gesture. Next up, learn how to go back."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"You completed the go home gesture"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe up with two fingers from the bottom of the screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Go home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"To go to your home screen at any time, swipe up from the bottom of your screen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe up from the bottom of your screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Great work!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Try holding the window for longer before releasing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Make sure that you swipe straight up, then pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You\'ve learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"You completed the switch apps gesture"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"To switch between apps, swipe up with two fingers from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Switch apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe up from the bottom of your screen, hold, then release"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Well done!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tap another app to use split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Exit split screen selection"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choose another app to use split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar shown"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar hidden"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Always show Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Change navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskbar divider"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Show # more app.}other{Show # more apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> and <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adding app to desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel"</string>
</resources>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 01599c4..eed32b3 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure you swipe from the right or left edge to the middle of the screen and let go."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Make sure you swipe from the right or left edge to the middle of the screen and let go"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next up, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure you don\'t swipe too close to the bottom of the screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"You completed the go back gesture"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Make sure you don\'t swipe too close to the bottom of the screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change the sensitivity of the back gesture, go to Settings"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Go back"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go Home gesture. Next up, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go Home gesture."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe from the left or right edge to the middle of the screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Make sure you don\'t pause before letting go"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Make sure you swipe straight up"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"You completed the go home gesture. Next up, learn how to go back."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"You completed the go home gesture"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the Home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Go home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"To go to your home screen at any time, swipe up from the bottom of your screen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure you swipe straight up, then pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe up from the bottom of your screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Great job!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Try holding the window for longer before releasing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Make sure you swipe straight up, then pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"You completed the switch apps gesture"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Switch apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe up from the bottom of your screen, hold, then release"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Well done!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tap another app to use split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Exit split screen selection"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choose another app to use split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organization"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar shown"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar hidden"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Always show Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Change navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskbar Divider"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Show # more app.}other{Show # more apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> and <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adding app to Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel"</string>
</resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index ec90faf..878c062 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Make sure you swipe from the right or left edge to the middle of the screen and let go"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You\'ve learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"You completed the go back gesture"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Make sure you don\'t swipe too close to the bottom of the screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"To go back to the last screen, swipe with two fingers from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Go back"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You\'ve completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe from the left or right edge to the middle of the screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Make sure you don\'t pause before letting go"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Make sure you swipe straight up"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"You completed the go home gesture. Next up, learn how to go back."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"You completed the go home gesture"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe up with two fingers from the bottom of the screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Go home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"To go to your home screen at any time, swipe up from the bottom of your screen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe up from the bottom of your screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Great work!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Try holding the window for longer before releasing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Make sure that you swipe straight up, then pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You\'ve learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"You completed the switch apps gesture"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"To switch between apps, swipe up with two fingers from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Switch apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe up from the bottom of your screen, hold, then release"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Well done!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tap another app to use split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Exit split screen selection"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choose another app to use split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar shown"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar hidden"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Always show Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Change navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskbar divider"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Show # more app.}other{Show # more apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> and <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adding app to desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel"</string>
</resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index ec90faf..878c062 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Make sure you swipe from the right or left edge to the middle of the screen and let go"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You\'ve learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"You completed the go back gesture"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Make sure you don\'t swipe too close to the bottom of the screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"To go back to the last screen, swipe with two fingers from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Go back"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You\'ve completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe from the left or right edge to the middle of the screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Make sure you don\'t pause before letting go"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Make sure you swipe straight up"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"You completed the go home gesture. Next up, learn how to go back."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"You completed the go home gesture"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe up with two fingers from the bottom of the screen. This gesture always takes you to the home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Go home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"To go to your home screen at any time, swipe up from the bottom of your screen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe up from the bottom of your screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Great work!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Try holding the window for longer before releasing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Make sure that you swipe straight up, then pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You\'ve learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"You completed the switch apps gesture"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"To switch between apps, swipe up with two fingers from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Switch apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe up from the bottom of your screen, hold, then release"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Well done!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tap another app to use split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Exit split screen selection"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choose another app to use split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar shown"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar hidden"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Always show Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Change navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskbar divider"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Show # more app.}other{Show # more apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> and <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adding app to desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel"</string>
</resources>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index c8f344e..ae825c1 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure you swipe from the right or left edge to the middle of the screen and let go."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotate your device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Please rotate your device to complete the gesture navigation tutorial"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Make sure you swipe from the far-right or far-left edge"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Make sure you swipe from the right or left edge to the middle of the screen and let go"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next up, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure you don\'t swipe too close to the bottom of the screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"You completed the go back gesture"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Make sure you don\'t swipe too close to the bottom of the screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change the sensitivity of the back gesture, go to Settings"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Go back"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go Home gesture. Next up, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go Home gesture."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe from the left or right edge to the middle of the screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Make sure you don\'t pause before letting go"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Make sure you swipe straight up"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"You completed the go home gesture. Next up, learn how to go back."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"You completed the go home gesture"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the Home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Go home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"To go to your home screen at any time, swipe up from the bottom of your screen"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure you swipe straight up, then pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe up from the bottom of your screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Great job!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Make sure you swipe up from the bottom edge of the screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Try holding the window for longer before releasing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Make sure you swipe straight up, then pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"You completed the switch apps gesture"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Switch apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe up from the bottom of your screen, hold, then release"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Well done!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tap another app to use split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Exit split screen selection"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choose another app to use split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organization"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar shown"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar hidden"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Always show Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Change navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Taskbar Divider"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Show # more app.}other{Show # more apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> and <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adding app to Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancel"</string>
</resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index eb2a296..cf5d6e9 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -23,7 +23,7 @@
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración de uso de la app"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"Cerrar todo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recientes"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Se cerró la tarea"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
@@ -44,39 +44,45 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de apps habilitadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicción de app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Asegúrate de deslizar desde el extremo derecho o izquierdo."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Asegúrate de deslizar desde borde izquierdo o derecho hacia centro de la pantalla y, luego, soltar."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rota el dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rota el dispositivo para completar el instructivo de la navegación por gestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de deslizar desde el extremo derecho o izquierdo"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Recuerda deslizar desde el borde izquierdo o derecho hacia el centro de la pantalla y, luego, soltar"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ya sabes deslizar el dedo desde la derecha para ir atrás. Ahora, descubre cómo cambiar de app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Completaste el gesto \"Atrás\"."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Asegúrate de no hacerlo muy cerca de la parte inferior de la pantalla."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Completaste el gesto para ir atrás"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Asegúrate de no deslizar muy cerca de la parte inferior de la pantalla"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Cambia sensibilidad de gesto \"Atrás\" en Configuración"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Desliza para ir atrás"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Desliza el dedo desde el borde derecho o izquierdo hasta el centro para volver a la última pantalla."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para volver la pantalla anterior, desliza 2 dedos desde el borde izquierdo o derecho hacia el centro de la pantalla."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Atrás"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Asegúrate de no detenerte antes de soltarlo."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Desliza el dedo directamente hacia arriba."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Completaste el gesto para ir a la página principal. Ahora, descubre cómo ir hacia atrás."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Completaste el gesto para ir a la página principal."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Volver atrás"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Desliza desde el borde izquierdo o derecho hacia el centro de la pantalla"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Asegúrate de deslizar hacia arriba desde el borde inferior de la pantalla"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Asegúrate de no detenerte antes de soltar"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Asegúrate de deslizar el dedo directamente hacia arriba"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Completaste el gesto para ir a la página principal. A continuación, obtén información para volver."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Completaste el gesto para ir a la página principal"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Desliza para ir a la página principal"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Desliza hacia arriba desde la parte inferior de la pantalla. Este gesto te llevará a la pantalla principal."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Desliza hacia arriba desde la parte inferior. Este gesto te llevará siempre a la pantalla principal."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ir a la pantalla principal"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para ir a la pantalla principal en cualquier momento, desliza desde la parte inferior de la pantalla"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prueba mantener presionada la ventana más tiempo antes de soltarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Desliza el dedo directamente hacia arriba y luego detente."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ve a la pantalla principal"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Desliza hacia arriba desde la parte inferior de la pantalla"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"¡Bien hecho!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Asegúrate de deslizar hacia arriba desde el borde inferior de la pantalla"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Intenta mantener presionada la ventana más tiempo antes de soltarla"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Asegúrate de deslizar directamente hacia arriba y detenerte"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ya sabes cómo usar los gestos. Para desactivarlos, ve a Configuración."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Completaste el gesto para cambiar de app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Completaste el gesto para cambiar de app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Desliza para cambiar de app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Desliza el dedo hacia arriba desde la parte inferior, mantenlo presionado y suéltalo."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para alternar entre apps, desliza el dedo hacia arriba, mantén presionado y, luego, suelta."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Cambiar de app"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Cambia de app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Desliza hacia arriba desde la parte inferior de la pantalla, mantenla presionada y, luego, suelta"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"¡Bien hecho!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Listo"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Listo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuración"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reintentar"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Vuelve a intentarlo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"¡Genial!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Instructivo <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Todo listo"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
<string name="action_split" msgid="2098009717623550676">"Pantalla dividida"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Presiona otra app para usar la pantalla dividida"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Salir de la selección de pantalla dividida"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Elige otra app para usar la pantalla dividida"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"La app o tu organización no permiten realizar esta acción"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"¿Omitir el instructivo de navegación?"</string>
@@ -101,7 +108,7 @@
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Desliza despacio hacia arriba para ver la Barra de tareas"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Recibe sugerencias de aplicaciones basadas en tu rutina"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Activa la navegación por gestos en la Configuración y la Barra de tareas se ocultará sola"</string>
- <string name="taskbar_edu_features" msgid="3320337287472848162">"Haz más con la Barra de tareas"</string>
+ <string name="taskbar_edu_features" msgid="3320337287472848162">"Aprovecha mejor la Barra de tareas"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Botón de inicio"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tareas visible"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tareas oculta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegación"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Ver siempre la Barra de tareas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Cambiar el modo de navegación"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor de la Barra de tareas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover a la parte superior o izquierda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover a la parte inferior o derecha"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostrar # app más.}other{Mostrar # apps más.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> y <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Agregando app al escritorio"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancelar"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index d8beb80..d40780c 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de aplicaciones habilitadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación sugerida: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Asegúrate de deslizar el dedo desde el borde derecho o izquierdo de la pantalla."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Asegúrate de deslizar el dedo desde el borde derecho o izquierdo de la pantalla hasta el centro y luego levántalo."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gira el dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gira el dispositivo para completar el tutorial de navegación por gestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de deslizar desde el borde derecho o izquierdo de la pantalla"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Asegúrate de deslizar desde el borde derecho o izquierdo de la pantalla hasta el centro y soltar"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ya sabes deslizar el dedo desde la derecha para ir atrás. Descubre ahora cómo cambiar de aplicación."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Has completado el gesto para volver."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"No deslices el dedo demasiado cerca de la parte inferior de la pantalla."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Has completado el gesto para volver"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"No deslices demasiado cerca de la parte inferior de la pantalla"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Para cambiar la sensibilidad del gesto, ve a Ajustes"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Desliza para ir atrás"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para volver a la última pantalla, desliza el dedo desde un lateral de la pantalla hasta el centro."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para volver a la pantalla anterior, desliza dos dedos desde el borde izquierdo o derecho hacia el centro de la pantalla."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Volver"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Asegúrate de deslizar el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"No hagas ninguna pausa antes de levantar el dedo."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Asegúrate de deslizar el dedo hacia arriba."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Has completado el gesto para ir a la pantalla de inicio. Ahora, descubre cómo ir hacia atrás."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Has completado el gesto para ir a la pantalla de inicio."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Desliza desde el borde izquierdo o derecho de la pantalla hasta el centro"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Asegúrate de deslizar hacia arriba desde el borde inferior de la pantalla"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Asegúrate de no hacer ninguna pausa antes de soltar"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Asegúrate de deslizar hacia arriba"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Has completado el gesto para ir a la pantalla de inicio. Ahora, descubre cómo volver."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Has completado el gesto para ir a la pantalla de inicio"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Desliza para ir a la pantalla de inicio"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Desliza hacia arriba desde la parte inferior de la pantalla. Este gesto siempre te lleva a la pantalla de inicio."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Desliza dos dedos hacia arriba desde la parte inferior de la pantalla. Si haces este gesto, siempre irás a la pantalla de inicio."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ir a Inicio"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para ir a la pantalla de inicio, desliza el dedo hacia arriba desde la parte inferior de la pantalla"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Asegúrate de deslizar el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prueba a mantener pulsada la ventana durante más tiempo antes de soltarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Asegúrate de deslizar el dedo directamente hacia arriba y luego mantenlo pulsado."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ir a inicio"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Desliza hacia arriba desde la parte inferior de la pantalla"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"¡Bien hecho!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Asegúrate de deslizar hacia arriba desde el borde inferior de la pantalla"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prueba a mantener pulsada la ventana durante más tiempo antes de soltarla"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Asegúrate de deslizar directamente hacia arriba y luego detenerte"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ya sabes cómo utilizar gestos. Para desactivarlos, ve a Ajustes."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Has completado el gesto para cambiar de aplicación."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Has completado el gesto para cambiar de aplicación"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Desliza el dedo para cambiar de aplicación"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de aplicación, desliza el dedo hacia arriba desde el borde inferior, mantenlo pulsado y suéltalo"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de aplicación, desliza el dedo hacia arriba desde el borde inferior, mantenlo pulsado y suéltalo."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para cambiar de app, desliza dos dedos hacia arriba desde el borde inferior, mantén pulsada la pantalla y, luego, suelta."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Cambiar de aplicación"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Desliza hacia arriba desde la parte inferior de la pantalla, mantenla pulsada y suelta el dedo."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"¡Muy bien!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Todo listo"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hecho"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ajustes"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"Compartir"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Hacer captura"</string>
<string name="action_split" msgid="2098009717623550676">"Dividir"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Toca otra app para usar la pantalla dividida"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Toca otra aplicación para usar la pantalla dividida"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Salir de la selección de pantalla dividida"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Elige otra app para usar la pantalla dividida"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"No puedes hacerlo porque la aplicación o tu organización no lo permiten"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"¿Saltar tutorial de navegación?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tareas visible"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tareas oculta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegación"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Ver siempre Barra de Tareas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Cambiar el modo de navegación"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor de Barra de Tareas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover arriba/a la izquierda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover abajo/a la derecha"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostrar # aplicación más.}other{Mostrar # aplicaciones más.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> y <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Añadiendo aplicación al ordenador"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancelar"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 1594337..176741a 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Rakenduste soovitused on lubatud"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Rakenduste soovitused on keelatud"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennustatud rakendus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pühkige kindlasti parem- või vasakpoolsest servast."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pühkige ekraanikuva paremast või vasakust servast keskele ja eemaldage sõrm."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pöörake seadet"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pöörake seadet, et liigutustega navigeerimise õpetused lõpetada"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pühkige kindlasti parem- või vasakpoolsest servast"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pühkige ekraani paremast või vasakust servast keskele ja eemaldage sõrm"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Õppisite, kuidas tagasiliikumiseks paremalt pühkida. Nüüd vaadake, kuidas rakenduste vahel vahetada."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Tegite tagasiliikumise liigutuse."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Veenduge, et te ei pühiks liiga ekraanikuva allosa lähedalt."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Tegite tagasiliikumise liigutuse"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Veenduge, et te ei pühiks liiga ekraani allosa lähedalt."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Tagasiliigutuse tundlikkuse muutmiseks avage menüü Seaded"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Tagasiliikumiseks pühkige"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Eelmisele ekraanikuvale naasmiseks pühkige vasakust või paremast servast ekraanikuva keskele."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Eelmisele ekraanikuvale naasmiseks pühkige vasakust või paremast servast kahe sõrmega ekraanikuva keskele."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Tagasiliikumine"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pühkige kindlasti ekraanikuva alumisest servast üles."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Veenduge, et te enne vabastamist liigutust ei peataks."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pühkige kindlasti otse üles."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Tegite avakuvale minemise liigutuse. Järgmisena vaadake, kuidas minna tagasi."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Tegite avakuvale minemise liigutuse."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Pühkige ekraani paremast või vasakust servast keskele."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pühkige kindlasti ekraani alumisest servast üles."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Veenduge, et te enne vabastamist liigutust ei peataks."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pühkige kindlasti otse üles."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Tegite avakuvale minemise liigutuse. Järgmisena vaadake, kuidas minna tagasi."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Tegite avakuvale minemise liigutuse"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Pühkige avakuvale minemiseks"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pühkige ekraani alaosast üles. See liigutus viib teid alati tagasi avakuvale."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Pühkige ekraanikuva alumisest servast 2 sõrmega üles. See liigutus viib teid alati tagasi avakuvale."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Avalehele"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Mis tahes ajal avakuvale liikumiseks pühkige ekraanikuva allosast üles"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pühkige kindlasti ekraanikuva alumisest servast üles."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Hoidke sõrme aknal pisut kauem, enne kui vabastate."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pühkige kindlasti otse üles, seejärel peatuge."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Avakuvale"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Pühkige ekraani allosast üles."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Väga hea!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pühkige kindlasti ekraani alumisest servast üles."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Hoidke sõrme aknal pisut kauem, enne kui vabastate"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pühkige kindlasti otse üles, seejärel peatuge"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Õppisite liigutusi kasutama. Liigutuste väljalülitamiseks avage seaded."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Tegite rakenduste vahel vahetamise liigutuse."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Tegite rakenduste vahel vahetamise liigutuse"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pühkige rakenduste vahetamiseks"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Rakenduste vahel vahetamiseks pühkige ekraanikuva alaosast üles, hoidke ja seejärel vabastage."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Rakenduste vahel vahetamiseks pühkige kuva alaosast kahe sõrmega üles, hoidke ja seejärel vabastage."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Rakenduste vahetamine"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Pühkige ekraani allosast üles, hoidke ja seejärel vabastage."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Hästi tehtud!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Valmis"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Valmis"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Seaded"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Ekraanipilt"</string>
<string name="action_split" msgid="2098009717623550676">"Eralda"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Jagatud ekraanikuva kasutamiseks puudutage muud rakendust"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Jagatud ekraanikuva valikust väljumine"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Valige jagatud ekraanikuva jaoks muu rakendus"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Rakendus või teie organisatsioon on selle toimingu keelanud"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Kas jätta navigeerimise õpetused vahele?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Tegumiriba on kuvatud"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Tegumiriba on peidetud"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigeerimisriba"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Kuva tööriistariba alati"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Navigeerimisrežiimi muutmine"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Tegumiriba jagaja"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Teisalda üles/vasakule"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Teisalda alla/paremale"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Kuva veel # rakendus.}other{Kuva veel # rakendust.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ja <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Rakenduse lisamine arvutisse"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Tühista"</string>
</resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 1eba2b7..aa42f2f 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -24,7 +24,7 @@
<string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Aplikazioen erabileraren ezarpenak"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Garbitu guztiak"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Azken aplikazioak"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"Azkenaldiko aplikazioak"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Itxi da zeregina"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"< 1 min"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Gaituta daude aplikazioen iradokizunak"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Desgaituta daude aplikazioen iradokizunak"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Iragarritako aplikazioa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik hasten zarela pasatzen."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik erdialdera pasatzen eta altxatzen duzula."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Biratu gailua"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Keinu bidezko nabigazioaren tutoriala osatzeko, biratu gailua"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik hasten zarela pasatzen"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik erdialdera pasatzen duzula eta ondoren hatza jasotzen duzula"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Hatza eskuinetik pasatuta atzera egiten ikasi duzu. Jarraian, ikasi aplikazioa aldatzen."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ikasi duzu atzera egiteko keinua."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ziurtatu hatza ez duzula pantailaren behealdetik gertuegi pasatzen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ikasi duzu atzera egiteko keinua"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Ziurtatu hatza ez duzula pasatzen pantailaren behealdetik gertuegi"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Keinuaren sentikortasuna aldatzeko, joan ezarpenetara"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Pasatu hatza atzera egiteko"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Aurreko pantailara itzultzeko, pasatu hatza pantailaren ezkerreko edo eskuineko ertzetik erdialdera."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Aurreko pantailara itzultzeko, pasatu bi hatz pantailaren ezkerreko edo eskuineko ertzetik erdialdera."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Egin atzera"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Ziurtatu askatu aurretik ez duzula hatza gelditzen."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Ziurtatu hatza zuzen pasatzen duzula gora."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ikasi duzu hasierako pantailara joateko keinua. Jarraian, ikasi atzera egiten."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ikasi duzu hasierako pantailara joateko keinua."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Pasatu hatza pantailaren eskuineko edo ezkerreko ertzetik erdialdera"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Ziurtatu ez duzula mugimendua gelditzen askatu arte"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Ziurtatu hatza zuzen pasatzen duzula gora"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ikasi duzu hasierako pantailara joateko keinua. Orain, ikasi atzera egiten."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ikasi duzu hasierako pantailara joateko keinua"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Pasatu hatza hasierako pantailara joateko"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pasatu hatza pantailaren behealdetik gora. Keinu horrek hasierako pantailara eramango zaitu beti."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Pasatu bi hatz pantailaren behealdetik gora. Hasierako pantailara eramango zaitu beti keinu horrek."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Joan hasierako pantailara"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Hasierako pantailara joateko, pasatu hatza pantailaren behealdetik gora"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Eduki sakatuta leihoa luzaroago hatza altxatu aurretik."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Ziurtatu hatza zuzen pasatzen duzula gora; ondoren, gelditu."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Pasatu hatza pantailaren behealdetik gora"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Bikain!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Eduki sakatuta leihoa luzaroago hatza jaso aurretik"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Ziurtatu hatza zuzen pasatzen duzula gora; ondoren, gelditu"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ikasi duzu keinuak erabiltzen. Keinuak desaktibatzeko, joan ezarpenetara."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ikasi duzu aplikazioa aldatzeko keinua."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ikasi duzu aplikazioz aldatzeko keinua"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pasatu hatza aplikazioa aldatzeko"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aplikazio batetik bestera joateko, pasatu hatza pantailaren behealdetik gora, eduki pantaila sakatuta eta altxatu hatza."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Aplikazio batetik bestera joateko, pasatu bi hatz pantailaren behealdetik gora, eduki pantaila sakatuta eta altxatu hatza."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Aldatu aplikazioa"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Pasatu hatza pantailaren behealdetik gora, eduki sakatuta une batez, eta jaso hatza"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Oso ongi!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Dena prest"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Eginda"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ezarpenak"</string>
@@ -89,7 +95,8 @@
<string name="action_screenshot" msgid="8171125848358142917">"Atera pantaila-argazki bat"</string>
<string name="action_split" msgid="2098009717623550676">"Zatitu"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Sakatu beste aplikazio bat pantaila zatitzeko"</string>
- <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pantaila zatitua ikusteko, aukeratu beste aplikazio bat"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Irten pantaila zatituaren hautapenetik"</string>
+ <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pantaila zatitzeko, aukeratu beste aplikazio bat"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikazioak edo erakundeak ez du eman ekintza hori gauzatzeko baimena"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Nabigazio-tutoriala saltatu nahi duzu?"</string>
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioan dago eskuragarri tutoriala"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Biratu pantaila"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Zereginen barra erabiltzeko argibideak"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Bi aplikazio batera erabiltzeko, arrastatu bat albo batera"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Zereginen barra ikusteko, pasatu hatza motel gora"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Zereginen barra ikusteko, pasatu hatza gora poliki"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Jaso aplikazioen iradokizunak erabileran oinarrituta"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Zereginen barra automatikoki ezkutatzeko, aktibatu keinu bidezko nabigazioa ezarpenetan"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Egin gauza gehiago zereginen barrarekin"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Zereginen barra ikusgai dago"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Zereginen barra itxita dago"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Nabigazio-barra"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Erakutsi beti zereginen barra"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Aldatu nabigazio modua"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Zereginen barraren zatitzailea"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Eraman gora, ezkerretara"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Eraman behera, eskuinetara"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Erakutsi beste # aplikazio.}other{Erakutsi beste # aplikazio.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> eta <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Aplikazioa mahaigainean gehitzen"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Utzi"</string>
</resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 1a35f9c..85b4862 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«پیشنهاد برنامه» فعال است"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«پیشنهاد برنامه» غیرفعال است"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"برنامه پیشبینیشده: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"دقت کنید که از انتهای لبه سمت راست یا سمت چپ تند بکشید."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"دقت کنید که از لبه سمت راست یا سمت چپ تند به وسط صفحه بکشید و رها کنید."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"دستگاهتان را بچرخانید"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"لطفاً برای تکمیل آموزش گامبهگام پیمایش اشارهای، دستگاهتان را بچرخانید"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"دقت کنید که از انتهای لبه سمت راست یا سمت چپ تند بکشید"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"دقت کنید که از لبه سمت راست یا سمت چپ تند به وسط صفحه بکشید و رها کنید"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"یاد گرفتید چگونه برای رفتن به عقب از سمت راست تند بکشید. مورد بعدی، با نحوه جابهجا شدن بین برنامهها آشنا شوید."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"اشاره برگشتن را تکمیل کردید."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"دقت کنید که موقع تند کشیدن بیشاز حد به پایین صفحه نزدیک نشوید."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"اشاره برگشتن را تکمیل کردید"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"دقت کنید که موقع تند کشیدن، بیشاز حد به پایین صفحه نزدیک نشوید"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"برای تغییر حساسیت اشاره برگشت، به «تنظیمات» بروید"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"تند بکشید تا بهعقب برگردید"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"برای برگشتن به صفحه آخر، از لبه سمت چپ یا راست تند به وسط صفحه بکشید."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"برای برگشتن به صفحه قبلی، با ۲ انگشت از لبه سمت چپ یا راست تند بهوسط صفحه بکشید."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"برگشتن"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"دقت کنید که تا قبلاز رها کردن، کشیدن را متوقف نکنید."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"دقت کنید که مستقیماً تند به بالا بکشید."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"اشاره رفتن به «صفحه اصلی» را تکمیل کردید. مورد بعدی، با نحوه برگشتن به عقب آشنا شوید."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"اشاره رفتن به «صفحه اصلی» را تکمیل کردید."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"از لبه سمت راست یا سمت چپ تند به وسط صفحه بکشید"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"دقت کنید که قبلاز رها کردن مکث نکنید"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"دقت کنید که مستقیماً تند به بالا بکشید"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"اشاره رفتن به صفحه اصلی را تکمیل کردید. مورد بعدی، با نحوه برگشتن به عقب آشنا شوید."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"اشاره رفتن به صفحه اصلی را تکمیل کردید"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"تند کشیدن برای رفتن به صفحه اصلی"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"از پایین صفحه، تند بهسمت بالا بکشید. این اشاره همیشه شما را به صفحه اصلی میبرد."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"با ۲ انگشت از پایین صفحه تند بهبالا بکشید. این اشاره همیشه شما را به صفحه اصلی میبرد."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"رفتن به صفحه اصلی"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"برای رفتن به صفحه اصلی در هر زمانی، از پایین صفحه تند بهبالا بکشید"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"سعی کنید قبلاز رها کردن، پنجره را برای مدت طولانیتری نگه دارید."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"دقت کنید که مستقیماً تند به بالا بکشید و سپس توقف کنید."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"از پایین صفحه تند به بالا بکشید"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"عالی است!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"قبلاز رها کردن پنجره، آن را برای مدت طولانیتری نگه دارید"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"دقت کنید که مستقیماً تند به بالا بکشید و سپس توقف کنید"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"با نحوه استفاده از اشارهها آشنا شدید. برای خاموش کردن اشارهها، به «تنظیمات» بروید."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"اشاره جابهجا شدن بین برنامهها را تکمیل کردید."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"اشاره جابهجایی بین برنامهها را تکمیل کردید"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"برای جابهجا شدن بین برنامهها، تند بهبالا بکشید"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"برای جابهجا شدن بین برنامهها، از پایین صفحه تند بهبالا بکشید، نگه دارید، و سپس رها کنید."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"برای جابهجایی بین برنامهها، با ۲ انگشت از پایین صفحه تند بهبالا بکشید، نگه دارید، و سپس رها کنید."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"جابهجایی بین برنامهها"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"از پایین صفحه تند بهبالا بکشید، نگه دارید، سپس رها کنید"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"آفرین!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"همه چیز آماده است"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"تمام"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"تنظیمات"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"نماگرفت"</string>
<string name="action_split" msgid="2098009717623550676">"دونیمه"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"زدن روی برنامهای دیگر برای استفاده از صفحه دونیمه"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"خروج از انتخاب صفحهٔ دونیمه"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"انتخاب برنامهای دیگر برای استفاده از صفحه دونیمه"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"برنامه یا سازمان شما اجازه نمیدهد این کنش انجام شود."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"آموزش گامبهگام پیمایش رد شود؟"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"نوار وظیفه نمایان است"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"نوار وظیفه پنهان است"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"نوار پیمایش"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"نوار وظیفه همیشه نشان داده شود"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"تغییر حالت پیمایش"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"جداکننده نوار وظیفه"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"انتقال به بالا/ چپ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"انتقال به پایین/ راست"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{نمایش # برنامه دیگر.}one{نمایش # برنامه دیگر.}other{نمایش # برنامه دیگر.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> و <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"درحال افزودن برنامه به رایانه"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"لغو"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 428011b..60d6618 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sovellusehdotukset käytössä"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sovellusehdotukset on poistettu käytöstä"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennakoitu sovellus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Muista pyyhkäistä aivan oikeasta tai vasemmasta reunasta."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pyyhkäise näytön oikeasta tai vasemmasta reunasta keskelle ja päästä irti."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Käännä laite"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Käännä laite, niin voit katsoa esittelyn eleillä navigoinnista"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pyyhkäise aivan oikeasta tai vasemmasta reunasta"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pyyhkäise näytön oikeasta tai vasemmasta reunasta keskelle ja päästä irti"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Osaat palata takaisin pyyhkäisemällä oikeasta reunasta. Opettele seuraavaksi vaihtamaan sovellusta."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Olet oppinut Takaisin-eleen."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Varo, ettet pyyhkäise liian lähellä alareunaa."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Olet oppinut takaisin-eleen"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Varo, ettet pyyhkäise liian lähellä alareunaa"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Voit muuttaa Takaisin-eleen herkkyyttä asetuksista"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Siirry takaisin pyyhkäisemällä"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Voit palata edelliseen näkymään pyyhkäisemällä näytön vasemmasta tai oikeasta reunasta keskelle."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Palaa takaisin edelliselle näytölle pyyhkäisemällä kahdella sormella vasemmasta tai oikeasta reunasta näytön keskikohtaan."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Takaisin"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pyyhkäise ylös näytön alareunasta."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Varo keskeyttämästä ennen kuin päästät irti."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Muista pyyhkäistä suoraan ylöspäin."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Olet oppinut aloitusnäytölle palaamisen eleen. Opettele seuraavaksi siirtymään takaisin."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Olet oppinut aloitusnäytölle palaamisen eleen."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Edelliseen siirtyminen"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Pyyhkäise vasemmasta tai oikeasta reunasta näytön keskelle"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pyyhkäise ylös näytön alareunasta"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Varo pysähtymästä ennen kuin päästät irti"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pyyhkäise suoraan ylöspäin"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Olet oppinut aloitusnäytölle palaamiseleen. Opettele seuraavaksi siirtymään takaisin."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Olet oppinut aloitusnäytölle palaamiseleen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Siirry aloitusnäytölle pyyhkäisemällä"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pyyhkäise ylös näytön alareunasta. Tämä ele vie sinut aina aloitusnäytölle."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Pyyhkäise näytön alareunasta ylöspäin kahdella sormella. Tämä ele vie sinut aina aloitusnäytölle."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Aloitusnäytölle siirtyminen"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Voit siirtyä aloitusnäytölle milloin tahansa pyyhkäisemällä ylös näytön alareunasta"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pyyhkäise ylös näytön alareunasta."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Kokeile pitää ikkunaa painettuna pidempään ennen kuin päästät irti."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Muista pyyhkäistä suoraan ylöspäin ja keskeytä sitten."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Pyyhkäise ylös näytön alareunasta"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Hienoa!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pyyhkäise ylös näytön alareunasta"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Kokeile pitää ikkunaa painettuna pidempään ennen kuin päästät irti"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Muista pyyhkäistä suoraan ylöspäin ja pysähdy sitten"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Olet oppinut käyttämään eleitä. Jos haluat laittaa eleet pois päältä, avaa Asetukset."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Olet oppinut sovellusten vaihtamiseleen."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Olet oppinut sovellusten vaihtamiseleen"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vaihda sovellusta pyyhkäisemällä"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Voit vaihtaa sovelluksesta toiseen pyyhkäisemällä ylöspäin näytön alareunasta ja päästämällä sitten irti."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Vaihda sovelluksia pyyhkäisemällä ylös näytön alareunasta kahdella sormella ja päästä sitten irti."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Sovelluksen vaihtaminen"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Pyyhkäise ylöspäin näytön alareunasta ja päästä irti"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Hienoa!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Valmista"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Valmis"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Asetukset"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Kuvakaappaus"</string>
<string name="action_split" msgid="2098009717623550676">"Jaa"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Avaa jaettu näyttö napauttamalla toista sovellusta"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Poistu jaetun näytön valinnasta"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Käytä jaettua näyttöä valitsemalla toinen sovellus"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Sovellus tai organisaatio ei salli tätä toimintoa"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ohitetaanko navigointiohje?"</string>
@@ -97,7 +104,7 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ohita"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Käännä näyttö"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tehtäväpalkin ohje"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Vedä sovellus sivuun, niin voit käyttää samalla 2 sellaista"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Vedä sovellus sivuun, ja voit käyttää kahta sovellusta"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Näytä tehtäväpalkki pyyhkäisemällä ylös hitaasti"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Sovellussuosituksia käytön perusteella"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Laita eleillä navigointi päälle Asetuksista Tehtäväpalkin piilottamiseksi automaattisesti"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Tehtäväpalkki näkyvissä"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Tehtäväpalkki piilotettu"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigointipalkki"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Näytä tehtäväpalkki aina"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Vaihda navigointitilaa"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Tehtäväpalkin jakaja"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Siirrä ylös tai vasemmalle"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Siirrä alas tai oikealle"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Näytä # muu sovellus.}other{Näytä # muuta sovellusta.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ja <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Sovelluksen lisääminen työpöydälle"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Peru"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index af89ae5..a98e9c5 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Les suggestions d\'applications sont activées"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applications sont désactivées"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Application prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assurez-vous de balayer l\'écran à partir de l\'extrémité droite ou gauche."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Balayez l\'écran de l\'extrémité droite ou gauche jusqu\'au centre de l\'écran, puis levez le doigt."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Faites pivoter votre appareil"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Veuillez faire pivoter votre appareil pour terminer le tutoriel de navigation par gestes"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assurez-vous de balayer l\'écran à partir de l\'extrémité droite ou gauche"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Assurez-vous de balayer l\'écran à partir de l\'extrémité droite ou gauche vers le centre, puis allons-y"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Vous avez appris à balayer de la droite pour revenir en arrière. Apprenez comment changer d\'appli."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Vous avez appris le geste de retour en arrière."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assurez-vous de ne pas balayer trop près du bas de l\'écran."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Vous avez appris le geste de retour en arrière"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Assurez-vous de ne pas balayer trop près du bas de l\'écran"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Modifiez la sensibilité du geste de retour dans Paramètres"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Balayez l\'écran pour revenir en arrière"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pour revenir à l\'écran précédent, balayez l\'écran de l\'extrémité gauche ou droite vers le centre."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Pour revenir à l\'écran précédent, balayez l\'écran avec deux doigts du bord gauche ou droit jusqu\'au centre."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Retour"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assurez-vous de ne pas interrompre le geste avant de lever le doigt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assurez-vous de balayer l\'écran en ligne droite vers le haut."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Vous avez appris le geste de retour à l\'écran d\'accueil. Maintenant, apprenez à revenir en arrière."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Vous avez appris le geste de retour à l\'écran d\'accueil."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Balayez l\'écran à partir du bord gauche ou droit de l\'écran vers le centre"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Assurez-vous de ne pas interrompre le geste avant de lever le doigt"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Assurez-vous de balayer l\'écran en ligne droite vers le haut"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Vous avez appris le geste de retour à l\'écran d\'accueil. Maintenant, apprenez à revenir en arrière."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Vous avez appris le geste de retour à l\'écran d\'accueil"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Balayez pour revenir à l\'écran d\'accueil"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Balayez l\'écran du bas vers le haut. Ce geste vous ramène toujours à l\'écran d\'accueil."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Balayez l\'écran de bas en haut avec deux doigts. Ce geste vous ramène toujours à l\'écran d\'accueil."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Retour à la page d\'accueil"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Pour accéder à votre écran d\'accueil à tout moment, balayez l\'écran du bas vers le haut"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Essayez de tenir la fenêtre plus longtemps avant de relâcher."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assurez-vous de balayer l\'écran en ligne droite vers le haut, puis de faire une pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Balayez votre écran du bas vers le haut"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Super!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Essayez de tenir la fenêtre plus longtemps avant de relâcher"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Assurez-vous de balayer l\'écran vers le haut, puis de faire une pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Vous avez appris à utiliser les gestes. Pour les désactiver, accédez au menu Paramètres."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Vous avez appris le geste de changement d\'application."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Vous avez appris le geste de changement d\'application"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Balayez pour basculer entre les applications"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Pour changer d\'application, balayez l\'écran de bas en haut, maintenez le doigt, puis relâchez-le."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Pour changer d\'application, balayez l\'écran de bas en haut, maintenez le doigt dessus, puis relâchez-le."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Pour changer d\'appli, balayez l\'écran de bas en haut avec deux doigts, maintenez-les et relâchez-les."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Changer d\'application"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Balayez l\'écran de bas en haut, maintenez le doigt en place, puis relâchez-le"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Bien joué!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Terminé"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"OK"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Paramètres"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
<string name="action_split" msgid="2098009717623550676">"Partager"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Toucher une autre appli pour partager l\'écran"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Quitter la sélection d\'écran divisé"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Choisir une autre application pour utiliser l\'écran partagé"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"L\'application ou votre organisation n\'autorise pas cette action"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorer le tutoriel sur la navigation?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barre des tâches affichée"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barre des tâches masquée"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barre de navigation"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Touj. afficher barre des tâches"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Changer de mode de navigation"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Séparateur de la barre des tâches"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer vers le coin supérieur gauche de l\'écran"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer vers le coin inférieur droit de l\'écran"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Afficher # autre application.}one{Afficher # autre application.}other{Afficher # autres applications.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> et <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Ajout de l\'application au bureau en cours…"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annuler"</string>
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 3b08b89..2e2e0f1 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Suggestions d\'applications activées"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applications sont désactivées"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Application prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Veillez à bien balayer l\'écran depuis le bord gauche ou droit."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Balayez bien l\'écran depuis le bord gauche ou droit jusqu\'au centre avant de relever le doigt."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Faire pivoter l\'appareil"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Veuillez faire pivoter votre appareil pour effectuer le tutoriel de navigation par gestes"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Veillez à bien balayer l\'écran depuis le bord gauche ou droit"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Balayez bien l\'écran depuis le bord gauche ou droit jusqu\'au centre avant de relever le doigt"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Vous savez revenir en arrière en balayant depuis la droite. Apprenez à passer d\'une appli à l\'autre."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Vous avez appris le geste pour revenir en arrière."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Veillez à ne pas balayer l\'écran trop près du bas."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Vous avez appris le geste pour revenir en arrière"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Veillez à ne pas balayer l\'écran trop près du bas"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Modifiez la sensibilité du geste retour dans les paramètres"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Balayez l\'écran pour revenir en arrière"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pour revenir à l\'écran précédent, balayez l\'écran depuis le bord droit ou gauche jusqu\'au centre."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Pour revenir au dernier écran, balayez l\'écran avec deux doigts en partant du bord gauche ou droit vers le milieu."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Retour"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Veillez à balayer l\'écran de bas en haut."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Veillez à ne pas marquer de pause dans votre geste avant de relever le doigt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Veillez à balayer l\'écran vers le haut."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Vous savez désormais revenir à l\'écran d\'accueil. Apprenez maintenant à revenir en arrière."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Vous avez appris le geste pour revenir à l\'écran d\'accueil."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Balayez l\'écran à partir du bord gauche ou droit jusqu\'au centre"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Veillez à balayer vers le haut depuis le bord inférieur de l\'écran"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Veillez à ne pas marquer de pause dans votre geste avant de relever le doigt"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Veillez à balayer l\'écran vers le haut en ligne droite"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Vous avez appris le geste pour revenir à l\'écran d\'accueil. Apprenez ensuite à revenir en arrière."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Vous avez appris le geste pour revenir à l\'écran d\'accueil"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Balayez pour revenir à l\'écran d\'accueil"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Balayez l\'écran de bas en haut. Ce geste vous ramènera toujours à l\'écran d\'accueil."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Balayez l\'écran de bas en haut avec 2 doigts. Ce geste vous ramènera toujours à l\'écran d\'accueil."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Retour à l\'accueil"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Pour accéder à l\'écran d\'accueil à tout moment, balayez l\'écran du bas vers le haut"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Veillez à balayer l\'écran de bas en haut."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Essayez d\'appuyer plus longtemps sur la fenêtre avant de relever le doigt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Veillez à balayer l\'écran vers le haut, puis à marquer une pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Balayez l\'écran de bas en haut"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Bravo !"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Veillez à balayer vers le haut depuis le bord inférieur de l\'écran"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Essayez d\'appuyer plus longtemps sur la fenêtre avant de relever le doigt"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Veillez à balayer l\'écran vers le haut, puis à marquer une pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Vous avez appris à utiliser les gestes. Pour les désactiver, accédez aux paramètres."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Vous avez appris le geste pour passer d\'une appli à l\'autre."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Vous avez appris le geste pour passer d\'une appli à l\'autre"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Balayez pour passer d\'une appli à l\'autre"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Pour changer d\'appli, balayez l\'écran de bas en haut, appuyez de manière prolongée et relâchez."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Pour changer d\'appli, balayez l\'écran de bas en haut avec deux doigts, maintenez appuyé et relâchez."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Changer d\'appli"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Balayez l\'écran de bas en haut, appuyez de manière prolongée, puis relâchez"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Bravo !"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Vous avez terminé"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"OK"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Paramètres"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
<string name="action_split" msgid="2098009717623550676">"Partager"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Appuyez sur autre appli pour l\'écran partagé"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Quitter la sélection de l\'écran partagé"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Sélect. autre appli pour utiliser l\'écran partagé"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Cette action n\'est pas autorisée par l\'application ou par votre organisation"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorer le tutoriel de navigation ?"</string>
@@ -97,8 +104,8 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Passer"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Faire pivoter l\'écran"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Fonctionnement de la barre des tâches"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Faites glisser une appli sur le côté pour utiliser 2 applis"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Balayez lentement vers le haut pour l\'afficher"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Faites glisser une appli sur le côté pour en utiliser 2 à la fois"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Balayez lentement vers haut pour afficher barre des tâches"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Obtenez des suggestions d\'applis basées sur vos habitudes"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Activez la navigation par gestes dans paramètres pour masquage auto de la barre des tâches"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Faites-en plus avec la barre des tâches"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barre des tâches affichée"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barre des tâches masquée"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barre de navigation"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Toujours voir barre des tâches"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Modifier le mode de navigation"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Séparateur de barre des tâches"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer en haut ou à gauche"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer en bas ou à droite"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Afficher # autre appli.}one{Afficher # autre appli.}other{Afficher # autre applis.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> et <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Ajout de l\'appli au bureau"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annuler"</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index d5e7550..11479e1 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"As suxestións de aplicacións están activadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As suxestións de aplicacións están desactivadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación predita: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo ata o medio da pantalla e avanza."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Xira o dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Xira o dispositivo para completar o titorial de navegación con xestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo ata o medio da pantalla e levantalo"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Aprendiches a pasar o dedo desde a dereita para volver. Agora, aprende a cambiar de aplicación."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Completaches o xesto de volver á última pantalla."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Asegúrate de non pasar o dedo demasiado preto da parte inferior da pantalla."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Completaches o xesto de volver á última pantalla"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Asegúrate de non pasar o dedo demasiado preto da parte inferior da pantalla"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Podes cambiar a sensibilidade do xesto en Configuración"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Pasa o dedo para volver"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para volver á última pantalla, pasa o dedo cara ao medio desde o bordo dereito ou esquerdo."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para volver á última pantalla, pasa 2 dedos desde o bordo esquerdo ou o dereito ata a metade da pantalla."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Atrás"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Asegúrate de non facer unha pausa antes de avanzar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Asegúrate de pasar o dedo cara arriba cun movemento vertical."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Completaches o xesto de ir ao inicio. O próximo é aprender a volver á última pantalla."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Completaches o xesto de ir ao inicio."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Volver atrás"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Pasa o dedo desde o bordo esquerdo ou dereito ata o medio da pantalla"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Asegúrate de non facer unha pausa antes de levantar o dedo"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Asegúrate de pasar o dedo cara arriba cun movemento vertical"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Completaches o xesto de ir ao inicio. O próximo é aprender a volver á última pantalla."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Completaches o xesto de ir ao inicio"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Pasa o dedo para ir ao inicio"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pasa o dedo cara arriba desde a parte inferior da pantalla. Ao facelo, irás á pantalla de inicio."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Pasa 2 dedos desde a parte inferior da pantalla. Ao facelo, sempre irás á pantalla de inicio."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ir á pantalla de inicio"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para ir á pantalla de inicio, pasa o dedo cara arriba desde a parte inferior da pantalla"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Proba a manter premida a pantalla máis tempo antes de soltala."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Asegúrate de pasar o dedo cara arriba cun movemento vertical. Despois, fai unha pausa."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Pasa o dedo cara arriba desde a parte inferior da pantalla"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Moi ben!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Proba a manter premida a ventá máis tempo antes de levantar o dedo"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Asegúrate de pasar o dedo cara arriba cun movemento vertical. Despois, fai unha pausa"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Aprendiches a usar os xestos. Para desactivalos, vai a Configuración."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Completaches o xesto para cambiar de aplicación."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Completaches o xesto para cambiar de aplicación"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pasa o dedo para cambiar de aplicación"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de aplicación, pasa o dedo cara arriba desde a parte inferior da pantalla, mantén premido e levanta o dedo."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para cambiar de app, pasa 2 dedos cara arriba desde abaixo, mantén premida a pantalla e levántaos."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Pasar dunha aplicación a outra"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Pasa o dedo cara arriba desde a parte inferior da pantalla, mantena premida e sepárao"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Ben feito!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Todo listo"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Feito"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuración"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Facer captura"</string>
<string name="action_split" msgid="2098009717623550676">"Dividir"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Para usar a pantalla dividida, toca outra app"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Saír da selección de pantalla dividida"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Escolle outra app para usar a pantalla dividida"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"A aplicación ou a túa organización non permite realizar esta acción"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Queres omitir o titorial de navegación?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Estase mostrando a barra de tarefas"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Non se está mostrando a barra de tarefas"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegación"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Manter Barra de tarefas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Cambiar modo de navegación"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor da Barra de tarefas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover á parte superior ou á esquerda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover á parte inferior ou á dereita"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostrar # aplicación máis.}other{Mostrar # aplicacións máis.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> e <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Engadindo aplicación ao ordenador"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancelar"</string>
</resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 0924b68..ef44fb9 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ઍપના સુઝાવો ચાલુ છે"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ઍપના સુઝાવો બંધ છે"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"પૂર્વાનુમાનિત ઍપ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ખાતરી કરો કે તમે એકદમ દૂરની જમણી કે ડાબી કિનારીએથી સ્વાઇપ કરો છો."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ખાતરી કરો કે તમે જમણી કે ડાબી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો છો અને આંગળી ઊંચકી લો છો."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"તમારા ડિવાઇસને ફેરવો"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"સંકેતથી નૅવિગેશન ટ્યૂટૉરિઅલ પૂર્ણ કરવા માટે કૃપા કરીને તમારા ડિવાઇસને ફેરવો"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ખાતરી કરો કે તમે એકદમ દૂરની જમણી કે ડાબી કિનારીએથી સ્વાઇપ કરો છો"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ખાતરી કરો કે તમે જમણી કે ડાબી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો છો અને આંગળી ઊંચકી લો છો"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"પાછળ જવા જમણેથી કેવી રીતે સ્વાઇપ કરવું એ તમે શીખી લીધું છે. હવે પછી, ઍપ સ્વિચ કરવાની રીત જાણો."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"તમે પાછા જવાનો સંકેત પૂર્ણ કર્યો છે."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ખાતરી કરો કે તમારાથી સ્ક્રીનની એકદમ નીચેની કિનારીની ખૂબ નજીક સુધી સ્વાઇપ ન થઈ જાય."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"તમે પાછા જવાનો સંકેત પૂર્ણ કર્યો છે"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ખાતરી કરો કે તમારાથી સ્ક્રીનની એકદમ નીચેની કિનારીની ખૂબ નજીક સુધી સ્વાઇપ ન થઈ જાય"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"પાછા જવાના સંકેતની સંવેદિતા બદલવા માટે, સેટિંગમાં જાઓ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"પાછળ જવા માટે સ્વાઇપ કરો"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"છેલ્લી સ્ક્રીન પર પાછા જવા, ડાબી કે જમણી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"છેલ્લી સ્ક્રીન પર પાછા જવા માટે, 2 આંગળી વડે ડાબી કે જમણી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"પાછા જાઓ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ખાતરી કરો કે તમે આંગળી ઊંચકી લેતા પહેલાં સ્વાઇપ કરવાનું થોભાવતા નથી."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ખાતરી કરો કે તમે સીધું ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"તમે હોમ સ્ક્રીન પર પાછા જવાનો સંકેત પૂર્ણ કર્યો છે. હવે પછી, પાછા જવાની રીત વિશે જાણો."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"તમે હોમ સ્ક્રીન પર પાછા જવાનો સંકેત પૂર્ણ કર્યો છે."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"જમણી કે ડાબી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ખાતરી કરો કે તમે આંગળી ઊંચકી લેતા પહેલાં સ્વાઇપ કરવાનું થોભાવતા નથી"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ખાતરી કરો કે તમે સીધું ઉપરની તરફ સ્વાઇપ કરો છો"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"તમે હોમ સ્ક્રીન પર જવાનો સંકેત પૂર્ણ કર્યો. હવે પછી, પાછા જવાની રીત વિશે જાણો."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"તમે હોમ સ્ક્રીન પર જવાનો સંકેત પૂર્ણ કર્યો"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"હોમ સ્ક્રીન પર જવા માટે સ્વાઇપ કરો"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"તમારી સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો. આ સંકેત તમને હંમેશાં હોમ સ્ક્રીન પર લઈ જાય છે."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 આંગળી વડે સ્ક્રીનના સૌથી નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો. આ સંકેત તમને હંમેશાં હોમ સ્ક્રીન પર લઈ જાય છે."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"હોમ પર જાઓ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"કોઈપણ સમયે તમારી હોમ સ્ક્રીન પર જવા માટે, તમારી સ્ક્રીનની સૌથી નીચેની બાજુએથી ઉપરની તરફ સ્વાઇપ કરો"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"તમારી આંગળી ઊંચકતા પહેલાં તેને વિન્ડો પર થોડી વધારે વાર માટે દબાવી રાખવાનો પ્રયાસ કરો."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ખાતરી કરો કે તમે સીધું ઉપર સ્વાઇપ કરો છો, પછી થોભી જાઓ છો."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"તમારી સ્ક્રીનની સૌથી નીચેથી ઉપરની તરફ સ્વાઇપ કરો"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ખૂબ સરસ કામ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"તમારી આંગળી ઊંચકતા પહેલાં તેને વિન્ડો પર થોડી વધારે વાર માટે દબાવી રાખવાનો પ્રયાસ કરો"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ખાતરી કરો કે તમે સીધું ઉપર સ્વાઇપ કરો છો, પછી થોભી જાઓ છો"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"સંકેતોનો ઉપયોગ કરવાની રીત વિશે તમે જાણ્યું. સંકેતો બંધ કરવા, સેટિંગમાં જાઓ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"તમે ઍપ સ્વિચ કરવાનો સંકેત પૂર્ણ કર્યો છે."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"તમે ઍપ સ્વિચ કરવાનો સંકેત પૂર્ણ કર્યો."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ઍપ સ્વિચ કરવા સ્વાઇપ કરો"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"એક ઍપ પરથી બીજી ઍપ પર સ્વિચ કરવા માટે, તમારી સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરીને, થોડીવાર દબાવી રાખો, પછી છોડી દો."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"એક ઍપ પરથી બીજી ઍપ પર સ્વિચ કરવા માટે, 2 આંગળી વડે તમારી સ્ક્રીનના સૌથી નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરીને, થોડીવાર દબાવી રાખો, પછી છોડી દો."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ઍપ સ્વિચ કરો"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"તમારી સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરીને થોડીવાર દબાવી રાખો પછી છોડી દો"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"વાહ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"બધું સેટ થઈ ગયું"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"થઈ ગયું"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"સેટિંગ"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"સ્ક્રીનશૉટ"</string>
<string name="action_split" msgid="2098009717623550676">"વિભાજિત કરો"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"વિભાજિત સ્ક્રીન વાપરવા, કોઈ અન્ય ઍપ પર ટૅપ કરો"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"\'સ્ક્રીનને વિભાજિત કરો\' પસંદગીમાંથી બહાર નીકળો"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"સ્ક્રીન વિભાજનનો ઉપયોગ કરવા કોઈ અન્ય ઍપ પસંદ કરો"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ઍપ કે તમારી સંસ્થા દ્વારા આ ક્રિયા કરવાની મંજૂરી નથી"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"નૅવિગેશન ટ્યૂટૉરિઅલ છોડી દઈએ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ટાસ્કબાર બતાવવામાં આવ્યો"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ટાસ્કબાર છુપાવવામાં આવ્યો"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"નૅવિગેશન બાર"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"હંમેશાં ટાસ્કબાર બતાવો"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"નૅવિગેશન મોડ બદલો"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ટાસ્કબાર વિભાજક"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"સૌથી ઉપર ડાબી બાજુએ ખસેડો"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"સૌથી નીચે જમણી બાજુએ ખસેડો"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{વધુ # ઍપ બતાવો.}one{વધુ # ઍપ બતાવો.}other{વધુ # ઍપ બતાવો.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> અને <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ડેસ્કટૉપ પર ઍપ ઉમેરી રહ્યાં છીએ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"રદ કરો"</string>
</resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index b108371..28551ad 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करना"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करें"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"फ़्रीफ़ॉर्म"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ऐप्लिकेशन इस्तेमाल की सेटिंग"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सुझाए गए ऐप्लिकेशन की सुविधा चालू है"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सुझाए गए ऐप्लिकेशन की सुविधा बंद है"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"सुझाया गया ऐप्लिकेशन: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"देख लें कि आपने स्क्रीन की दाईं या बाईं ओर के बिलकुल किनारे से स्वाइप किया हो."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"स्क्रीन के दाएं या बाएं किनारे से स्क्रीन के बीच तक स्वाइप करें और अपनी उंगली उठा लें."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"अपना डिवाइस घुमाएं"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"जेस्चर वाले नेविगेशन से जुड़े ट्यूटोरियल को पूरा करने के लिए अपने डिवाइस को घुमाएं"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"स्क्रीन पर बिलकुल दाएं या बाएं किनारे से स्वाइप करें"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"स्क्रीन पर दाएं या बाएं किनारे से बीच तक स्वाइप करें और फिर अपनी उंगली को स्क्रीन से हटा दें"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"आपने स्क्रीन के दाएं किनारे से स्वाइप करके, पिछली स्क्रीन पर वापस जाने का तरीका सीख लिया है. अब, एक ऐप से दूसरे ऐप पर जाने का तरीका सीखें."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"आपने पेज पर पीछे ले जाने वाले हाथ के जेस्चर (हाव-भाव) के बारे में जान लिया है."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"देख लें कि आप स्क्रीन पर बिलकुल नीचे तक स्वाइप न कर रहे हों."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके पिछली स्क्रीन पर वापस कैसे जाएं"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"स्क्रीन पर बिलकुल नीचे तक स्वाइप न करें"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'सेटिंग\' में जाकर, पीछे जाने के लिए इस्तेमाल होने वाले हाथ के जेस्चर (हाव-भाव) की संवेदनशीलता बदलें"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"पिछली स्क्रीन पर वापस जाने के लिए स्वाइप करें"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"पिछली स्क्रीन पर वापस जाने के लिए, स्क्रीन के बाएं या दाएं किनारे से बीचों-बीच तक स्वाइप करें."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"पिछली स्क्रीन पर वापस जाने के लिए, स्क्रीन के बाएं या दाएं किनारे से स्क्रीन के बीच तक दो उंगलियों से स्वाइप करें."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"वापस जाएं"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"देख लें कि आप स्क्रीन के निचले किनारे से ऊपर की ओर स्वाइप कर रहे हों."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"देख लें कि आप स्क्रीन से अपनी उंगली उठाने से पहले, इसे कहीं न रोक रहे हों."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"देख लें कि आपने ऊपर की ओर बिलकुल सीधे स्वाइप किया हो."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"आपने होम स्क्रीन पर ले जाने वाले हाथ के जेस्चर के बारे में जान लिया है. अब, वापस जाने का तरीका जानें."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"आपने होम स्क्रीन पर ले जाने वाले हाथ के जेस्चर (हाव-भाव) के बारे में जान लिया है."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"पिछली स्क्रीन पर वापस जाना"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"स्क्रीन पर बाएं या दाएं किनारे से बीच तक स्वाइप करें"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"स्क्रीन पर निचले किनारे से ऊपर की ओर स्वाइप करें"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"उंगली हटाने से पहले उसे स्क्रीन पर कहीं न रोकें"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"स्क्रीन पर सीधे ऊपर की ओर स्वाइप करें"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"आपने जान लिया कि हाथ का जेस्चर इस्तेमाल करके होम स्क्रीन पर कैसे जाएं. अब वापस जाने का तरीका जानें."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके होम स्क्रीन पर कैसे जाएं"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रीन पर जाने के लिए स्वाइप करें"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रीन पर नीचे से ऊपर की ओर स्वाइप करें. हाथ का यह जेस्चर आपको हमेशा होम स्क्रीन पर ले जाता है."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"स्क्रीन के सबसे नीचे से ऊपर की ओर 2 उंगलियों से स्वाइप करें. जेस्चर हमेशा होम स्क्रीन पर ले जाता है."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"होम स्क्रीन पर जाएं"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"किसी भी समय फ़ोन की होम स्क्रीन पर जाने के लिए, फ़ोन पर सबसे नीचे से ऊपर की ओर स्वाइप करें"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"देख लें कि आप स्क्रीन के निचले किनारे से ऊपर की ओर स्वाइप कर रहे हों."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"कोशिश करें कि स्क्रीन से उंगली उठाने से पहले, इसे कुछ देर स्क्रीन पर दबाकर रखें."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"देख लें कि आप स्क्रीन पर ऊपर की तरफ़, बिलकुल सीधे स्वाइप कर रहे हों और फिर रुकें."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"होम स्क्रीन पर जाना"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"बहुत बढ़िया!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"स्क्रीन पर निचले किनारे से ऊपर की ओर स्वाइप करें"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"उंगली हटाने से पहले स्क्रीन को देर तक दबाकर रखें"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"स्क्रीन पर सीधे ऊपर की ओर स्वाइप करें और फिर रुकें"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"आपने हाथ के जेस्चर इस्तेमाल करने सीख लिए हैं. जेस्चर बंद करने के लिए, सेटिंग में जाएं."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"आपने एक ऐप्लिकेशन से दूसरे पर जाने के लिए इस्तेमाल होने वाले हाथ के जेस्चर के बारे में जान लिया है."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"आपने जान लिया है कि हाथ का जेस्चर इस्तेमाल करके ऐप्लिकेशन के बीच स्विच कैसे करें"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"एक ऐप्लिकेशन से दूसरे पर जाने के लिए स्वाइप करें"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"एक ऐप से दूसरे पर जाने के लिए, स्क्रीन पर नीचे से ऊपर की ओर स्वाइप करें, दबाकर रखें, और फिर छोड़ दें."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"एक ऐप से दूसरे पर जाने के लिए स्क्रीन पर नीचे से ऊपर की ओर स्वाइप करें, दबाकर रखें, और फिर छोड़ दें."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"इन ऐप के बीच स्विच करने के लिए, दो उंगलियों से नीचे से ऊपर स्वाइप करें, होल्ड करें, और फिर छोड़ें."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ऐप्लिकेशन के बीच स्विच करें"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ऐप्लिकेशन के बीच स्विच करना"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"अपनी स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें, स्क्रीन को दबाकर रखें, और फिर छोड़ दें"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"बहुत खूब!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"आप पूरी तरह तैयार हैं"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"हो गया"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिंग"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"हो गया!"</string>
<string name="allset_hint" msgid="459504134589971527">"होम पेज पर जाने के लिए, ऊपर की ओर स्वाइप करें"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"होम स्क्रीन पर जाने के लिए, होम बटन पर टैप करें"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"अब <xliff:g id="DEVICE">%1$s</xliff:g> इस्तेमाल के लिए तैयार हैं"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"अब <xliff:g id="DEVICE">%1$s</xliff:g> इस्तेमाल के लिए तैयार है"</string>
<string name="default_device_name" msgid="6660656727127422487">"डिवाइस"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"सिस्टम नेविगेशन सेटिंग"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"शेयर करें"</string>
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट लें"</string>
<string name="action_split" msgid="2098009717623550676">"स्प्लिट स्क्रीन मोड"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"स्प्लिट स्क्रीन के लिए दूसरे ऐप्लिकेशन पर टैप करें"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"स्प्लिट स्क्रीन मोड से बाहर निकलें"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"स्प्लिट स्क्रीन के लिए, दूसरा ऐप्लिकेशन चुनें"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"क्या आपको अभी नेविगेशन ट्यूटोरियल नहीं देखना है?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"टास्कबार दिखाया गया"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"टास्कबार छिपाया गया"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"नेविगेशन बार"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"टास्कबार हमेशा दिखाएं"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"नेविगेशन का मोड बदलें"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"टास्कबार डिवाइडर"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ऊपर/बाईं तरफ़ ले जाएं"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"नीचे/दाईं तरफ़ ले जाएं"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# और ऐप्लिकेशन दिखाएं.}one{# और ऐप्लिकेशन दिखाएं.}other{# और ऐप्लिकेशन दिखाएं.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> और <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"डेस्कटॉप पर ऐप्लिकेशन जोड़ा जा रहा है"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"रद्द करें"</string>
</resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 1aadeea..abad768 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlaganje apl. omogućeno"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlaganje apl. onemogućeno"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pazite da prijeđete prstom od krajnjeg desnog ili krajnjeg lijevog ruba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pazite da prijeđete prstom od desnog ili lijevog ruba do sredine zaslona i podignite prst."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zakrenite uređaj"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Zakrenite uređaj da biste dovršili vodič o navigaciji pokretima"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pazite da prijeđete prstom od krajnjeg desnog ili krajnjeg lijevog ruba"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pazite da prijeđete prstom od desnog ili lijevog ruba do sredine zaslona i podignite prst"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako prijeći prstom zdesna da biste se vratili. Sad saznajte kako promijeniti aplikaciju."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Izvršili ste pokret za povratak."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pazite da ne prijeđete prstom preblizu dnu zaslona."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Izvršili ste pokret za povratak"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pazite da ne prijeđete prstom preblizu dnu zaslona"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Osjetljivost pokreta povratka promijenite u postavkama"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Prijeđite prstom da biste se vratili"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Za povratak na zadnji zaslon prijeđite prstom od lijevog ili desnog ruba do sredine zaslona."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da biste se vratili na prethodni zaslon, prijeđite prstom od lijevog ili desnog ruba do sredine zaslona."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Da biste se vratili na posljednji zaslon, prijeđite s dva prsta od lijevog ili desnog ruba do sredine zaslona."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Natrag"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pazite da ne zastanete prije podizanja prsta."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pazite da prijeđete prstom ravno prema gore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Izvršili ste pokret za otvaranje početnog zaslona. Sad saznajte kako se vratiti."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Izvršili ste pokret za otvaranje početnog zaslona."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Povratak"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Prijeđite prstom od lijevog ili desnog ruba do sredine zaslona"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pazite da ne zastanete prije podizanja prsta"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pazite da prijeđete prstom ravno prema gore"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Izvršili ste pokret za otvaranje početnog zaslona. Sad saznajte kako se vratiti."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Izvršili ste pokret za otvaranje početnog zaslona"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Prijeđite prstom da biste otvorili početni zaslon"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prijeđite prstom od dna zaslona prema gore. Tim pokretom uvijek će se otvoriti početni zaslon."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Prijeđite s dva prsta od dna zaslona prema gore. Tim pokretom uvijek će se otvoriti početni zaslon."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Otvaranje početnog zaslona"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Da biste otvorili početni zaslon, prijeđite prstom od dna zaslona prema gore"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pokušajte zadržati prozor dulje prije podizanja prsta."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pazite da prijeđete prstom ravno prema gore, a zatim zastanete."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Prijeđite prstom od dna zaslona prema gore"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Sjajno!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Pokušajte zadržati prozor dulje prije podizanja prsta"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pazite da prijeđete prstom ravno prema gore, a zatim zastanete"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste koristiti pokrete. Pokrete možete isključiti u postavkama."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Izvršili ste pokret za promjenu aplikacije."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Izvršili ste pokret za promjenu aplikacije"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Povlačenje prstom za promjenu aplikacije"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za promjenu aplikacije prijeđite prstom od dna zaslona prema gore, zadržite pritisak pa pustite."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Da biste promijenili aplikaciju, prijeđite prstom od dna zaslona prema gore, zadržite pritisak pa pustite."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Za promjenu aplikacije prijeđite s dva prsta od dna zaslona prema gore, zadržite pritisak i pustite."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Promjena aplikacije"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Prijeđite prstom od dna zaslona prema gore, zadržite pritisak pa pustite"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Odlično!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Sve je spremno"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Postavke"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Snimka zaslona"</string>
<string name="action_split" msgid="2098009717623550676">"Podijeli"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Dodirnite drugu aplikaciju za podijeljeni zaslon"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Zatvori odabir podijeljenog zaslona"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Odaberite drugu aplikaciju za upotrebu podijeljenog zaslona"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili vaša organizacija ne dopuštaju ovu radnju"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite li preskočiti vodič za kretanje?"</string>
@@ -97,11 +104,11 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Zakretanje zaslona"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Upute za traku sa zadacima"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Povucite apl. u stranu radi istodobne upotrebe 2 aplikacije"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Povucite aplikaciju u stranu radi istodobne upotrebe dviju aplikacija"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Polako prijeđite prstom prema gore za prikaz trake sa zadacima"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Primajte prijedloge aplikacija na temelju svoje rutine"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Uključite navigaciju pokretima u postavkama da bi se traka sa zadacima automatski sakrila"</string>
- <string name="taskbar_edu_features" msgid="3320337287472848162">"Učinite više uz pomoć trake sa zadacima"</string>
+ <string name="taskbar_edu_features" msgid="3320337287472848162">"Učinite više pomoću trake sa zadacima"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Početna"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Traka sa zadacima prikazana"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Traka sa zadacima skrivena"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigacijska traka"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Uvijek prikaži traku zadataka"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Promijeni način navigacije"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Razdjelnik trake sa zadacima"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premjesti gore/lijevo"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premjesti dolje/desno"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Prikaži više aplikacija (još #).}one{Prikaži više aplikacija (još #).}few{Prikaži više aplikacija (još #).}other{Prikaži više aplikacija (još #).}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> i <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Dodavanje aplikacije na radnu površinu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Odustani"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index ba75d4f..16cd5f5 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Alkalmazásjavaslatok engedélyezve"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Alkalmazásjavaslatok letiltva"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Várható alkalmazás: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Csúsztasson a képernyő jobb vagy bal széléről."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Csúsztassa ujját a képernyő jobb vagy bal széléről a képernyő közepéig, majd emelje fel."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Forgassa el eszközét"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Forgassa el eszközét a kézmozdulatokkal való navigáció útmutatójának befejezéséhez"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Csúsztasson a képernyő jobb vagy bal széléről."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Csúsztassa ujját a képernyő jobb vagy bal széléről a képernyő közepéig, majd emelje fel."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Megtanulta, hogyan léphet vissza jobbról csúsztatva. A következő az appok közötti váltás."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Teljesítette a visszalépési kézmozdulatot."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ne csúsztasson túl közel a képernyő aljához."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Teljesítette a visszalépési kézmozdulatot."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Ne csúsztasson túl közel a képernyő aljához."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"A vissza mozdulat érzékenysége a Beállításokban módosítható"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Csúsztasson a visszalépéshez"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ha visszatérne a legutóbbi képernyőre, csúsztasson a képernyő közepére a bal vagy a jobb széléről."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Ha vissza szeretne térni a legutóbbi képernyőre, csúsztasson gyorsan két ujjal a képernyő bal vagy jobb széléről a közepe felé."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Vissza"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Csúsztasson felfelé a képernyő aljától."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Ne álljon meg, mielőtt elengedi a képernyőt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Csúsztasson egyenesen felfelé."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Teljesítette a kezdőképernyőre lépés kézmozdulatát. Most megtanulhatja, hogyan léphet vissza."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Teljesítette a kezdőképernyőre lépés kézmozdulatát."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Csúsztasson bal vagy jobb szélről a képernyő közepe felé."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Csúsztasson felfelé a képernyő aljától."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Ne álljon meg, mielőtt elengedi a képernyőt."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Csúsztasson egyenesen felfelé."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Teljesítette a kezdőképernyőre lépés kézmozdulatát. Most megtanulhatja, hogyan léphet vissza."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Teljesítette a kezdőképernyőre lépés kézmozdulatát."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Csúsztatás a kezdőképernyőre lépéshez"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Csúsztassa ujját felfelé a képernyő aljától. Ez a mozdulat mindig a kezdőképernyőre visz."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Csúsztasson felfelé két ujjal a képernyő aljáról. Ez a kézmozdulat mindig a kezdőképernyőre viszi."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ugrás a kezdőképernyőre"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Ha vissza szeretne térni a kezdőképernyőre, bármikor felfelé csúsztathat ujjával a képernyő aljáról"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Csúsztasson felfelé a képernyő aljától."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Próbálja tovább lenyomva tartani az ablakot, mielőtt elengedi a képernyőt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Csúsztasson egyenesen felfelé, majd várjon egy kicsit."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Húzza ujját felfelé a képernyő aljától."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Kiváló!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Csúsztasson felfelé a képernyő aljától."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Próbálja tovább lenyomva tartani az ablakot, mielőtt elengedi a képernyőt."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Csúsztasson egyenesen felfelé, majd várjon egy kicsit"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Eddig megismerhette a kézmozdulatok használatát. A kézmozdulatokat a Beállításokban kapcsolhatja ki."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Teljesítette az alkalmazásváltás kézmozdulatát."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Teljesítette az alkalmazásváltás kézmozdulatát."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Alkalmazásváltás csúsztatással"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Appok közti váltáshoz csúsztasson felfelé a kép aljáról, tartsa lenyomva az ujját, majd emelje fel."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Appváltáshoz csúsztasson fel két ujjal a kép aljáról, tartsa lenyomva ujjait, majd emelje fel őket."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Váltás az alkalmazások között"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Csúsztasson felfelé a képernyő aljáról, tartsa lenyomva ujját, majd emelje fel"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Szép munka!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Minden kész"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Kész"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Beállítások"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Kész is!"</string>
<string name="allset_hint" msgid="459504134589971527">"Felfelé csúsztatva megjelenik a kezdőképernyő"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"A kezdőképernyőre való lépéshez koppintson a kezdőképernyő gombra"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Készen áll a(z) <xliff:g id="DEVICE">%1$s</xliff:g> használatára"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Készen áll az <xliff:g id="DEVICE">%1$s</xliff:g> használatára"</string>
<string name="default_device_name" msgid="6660656727127422487">"eszköz"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Rendszer-navigációs beállítások"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Megosztás"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Képernyőkép"</string>
<string name="action_split" msgid="2098009717623550676">"Felosztás"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Koppintson másik appra az osztott képernyőhöz"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Kilépés az osztott képernyő elemeinek kiválasztásából"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Válasszon másik appot a képernyő felosztásához"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Az alkalmazás vagy az Ön szervezete nem engedélyezi ezt a műveletet"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Kihagyja a navigáció bemutatóját?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Képernyő elforgatása"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tálca használatának ismertetése"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Húzzon egy appot oldalra, ha kettőt használna egyidejűleg"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Csúsztassa ujját lassan fel a Feladatsáv megjelenítéséhez"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Lassan csúsztassa fel az ujját a Feladatsáv megjelenítéséhez"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Alkalmazásjavaslatokat kaphat a rutinja alapján"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"A Feladatsáv automatikus elrejtéséhez aktiválja a navigációs kézmozdulatokat a beállításokban"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Jobban kihasználhatja a Feladatsávot"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Feladatsáv megjelenítve"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Feladatsáv elrejtve"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigációs sáv"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Mindig megjelenő feladatsáv"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Navigációs mód módosítása"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Feladatsáv-elválasztó"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mozgatás felülre vagy a bal oldalra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mozgatás alulra vagy a jobb oldalra"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# további alkalmazás megjelenítése.}other{# további alkalmazás megjelenítése.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> és <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Alkalmazás hozzáadása az asztalhoz"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Mégse"</string>
</resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 43a7c5d..48eecd6 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -44,37 +44,43 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«Առաջարկվող հավելվածներ» գործառույթը միացված է"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«Առաջարկվող հավելվածներ» գործառույթն անջատված է"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Առաջարկվող հավելված՝ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Համոզվեք, որ մատը սահեցնում եք էկրանի աջ կամ ձախ եզրից։"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Մատը սահեցրեք էկրանի աջ կամ ձախ եզրից դեպի կենտրոն և բաց թողեք։"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Պտտեք սարքը"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Պտտեք սարքը՝ ժեստերով նավիգացիայի ուղեցույցն ավարտելու համար"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Համոզվեք, որ մատը սահեցնում եք էկրանի աջ կամ ձախ եզրից"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Մատը սահեցրեք էկրանի աջ կամ ձախ եզրից դեպի կենտրոն և բաց թողեք"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Դուք սովորեցիք՝ ինչպես մատը աջից սահեցնելով հետ գնալ։ Այժմ սովորենք՝ ինչպես անցնել մի հավելվածից մյուսը։"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Դուք սովորեցիք հետ գնալու ժեստը։"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Համոզվեք, որ մատը չափազանց մոտ չեք սահեցնում էկրանին ներքևի հատվածին։"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Դուք սովորեցիք հետ գնալու ժեստը"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Համոզվեք, որ մատը չափազանց մոտ չեք սահեցնում էկրանի ներքևի հատվածին"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Հետ գնալու ժեստի զգայունությունը փոփոխեք կարգավորումներում"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Սահեցրեք մատը՝ հետ գնալու համար"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Վերջին էկրանին վերադառնալու համար էկրանի աջ կամ ձախ եզրից մատը սահեցրեք դեպի կենտրոն։"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Վերջին էկրանին վերադառնալու համար 2 մատը սահեցրեք ձախ կամ աջ եզրից դեպի կենտրոն։"</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Վերադարձ հետ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում։"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Համոզվեք, որ դադար չեք տալիս նախքան բաց թողնելը։"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում։"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։ Այժմ սովորենք՝ ինչպես հետ գնալ։"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։"</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Հետ գնալ"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Էկրանի աջ կամ ձախ եզրից մատը սահեցրեք դեպի կենտրոն"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Համոզվեք, որ դադար չեք տալիս նախքան բաց թողնելը"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։ Այժմ սովորենք՝ ինչպես հետ գնալ։"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Սահեցրեք մատը՝ հիմնական էկրան անցնելու համար"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Մատը սահեցրեք էկրանի ներքևից վերև։ Այս ժեստը բացում է հիմնական էկրանը։"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Երկու մատը էկրանի ներքևից սահեցրեք վերև։ Այս ժեստը բացում է հիմնական էկրանը։"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Անցնել հիմնական էկրան"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Հիմնական էկրան վերադառնալու համար մատը էկրանի ներքևից սահեցրեք վերև"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում։"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Նախքան բաց թողնելը փորձեք հնարավորինս երկար պահել պատուհանը։"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում, այնուհետև դադար տվեք։"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Մատը սահեցրեք էկրանի ներքևից վերև"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Կեցցե՛ք"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Նախքան բաց թողնելը փորձեք հնարավորինս երկար պահել պատուհանը"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում, այնուհետև դադար տվեք"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Դուք սովորեցիք՝ ինչպես օգտագործել ժեստերը։ Ժեստերը կարող եք անջատել կարգավորումներում։"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Դուք սովորեցիք մի հավելվածից մյուսն անցնելու ժեստը։"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Դուք սովորեցիք մի հավելվածից մյուսն անցնելու ժեստը"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Մատը սահեցրեք՝ մյուս հավելվածին անցնելու համար"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Մեկ հավելվածից մյուսն անցնելու համար մատը էկրանի ներքևից սահեցրեք վերև, ապա հեռացրեք այն էկրանից։"</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Մեկ հավելվածից մյուսն անցնելու համար 2 մատը էկրանի ներքևից սահեցրեք վերև, ապա հեռացրեք այն էկրանից։"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Մեկ հավելվածից մյուսն անցնելու համար մատը էկրանի ներքևից սահեցրեք վերև, պահեք, ապա բաց թողեք։"</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Մեկ հավելվածից մյուսն անցնելու համար 2 մատը էկրանի ներքևից սահեցրեք վերև, պահեք, ապա բաց թողեք։"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Անցում մեկ հավելվածից մյուսին"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Մատը սահեցրեք էկրանի ներքևից վերև, պահեք և բաց թողեք"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Հիանալի՛ է"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Պատրաստ է"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Պատրաստ է"</string>
+ <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Ավարտել"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Կարգավորումներ"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Նորից փորձեք"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Գերազանց է"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Պատրաստ է"</string>
<string name="allset_hint" msgid="459504134589971527">"Մատը սահեցրեք վերև՝ հիմնական էկրան անցնելու համար"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Հիմնական էկրան վերադառնալու համար սեղմեք գլխավոր էկրանի կոճակը"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Դուք արդեն կարող եք օգտագործել ձեր <xliff:g id="DEVICE">%1$s</xliff:g> սարքը"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Դուք արդեն կարող եք օգտագործել ձեր <xliff:g id="DEVICE">%1$s</xliff:g>ը"</string>
<string name="default_device_name" msgid="6660656727127422487">"սարք"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Նավիգացիայի համակարգային կարգավորումներ"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Կիսվել"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Սքրինշոթ անել"</string>
<string name="action_split" msgid="2098009717623550676">"Տրոհել"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Հպեք այլ հավելվածի՝ տրոհված էկրանից օգտվելու համար"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Դուրս գալ տրոհված էկրանի ռեժիմից"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Ընտրեք այլ հավելված՝ կիսված էկրանից օգտվելու համար"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Բաց թողնե՞լ նավիգացիայի ուղեցույցը"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Խնդրագոտին ցուցադրվում է"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Խնդրագոտին թաքցված է"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Նավիգացիայի գոտի"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Միշտ ցուցադրել հավելվածները"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Փոխել նավիգացիայի ռեժիմը"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Հավելվածների վահանակի բաժանիչ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Տեղափոխել վերևի ձախ անկյուն"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Տեղափոխել ներքևի աջ անկյուն"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Ցուցադրել ևս # հավելված։}one{Ցուցադրել ևս # հավելված։}other{Ցուցադրել ևս # հավելված։}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> և <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Հավելվածն ավելացվում է աշխատասեղանին"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Չեղարկել"</string>
</resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 6f9d7c6..2852fc0 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -44,43 +44,49 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Saran aplikasi diaktifkan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Saran aplikasi dinonaktifkan"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikasi yang diprediksi: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pastikan Anda menggeser dari tepi ujung kanan atau ujung kiri."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pastikan Anda menggeser dari tepi kanan atau kiri ke tengah layar, lalu lepaskan."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Putar perangkat Anda"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Putar perangkat Anda untuk menyelesaikan tutorial navigasi gestur"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pastikan Anda menggeser dari tepi ujung kanan atau ujung kiri"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pastikan Anda menggeser dari tepi kanan atau kiri ke tengah layar, lalu lepaskan"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Anda telah belajar cara geser dari kanan untuk kembali. Berikutnya, pelajari cara beralih aplikasi."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Anda telah menyelesaikan gestur kembali."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pastikan Anda tidak menggeser terlalu dekat ke bagian bawah layar."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Anda telah menyelesaikan gestur kembali"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pastikan Anda tidak menggeser terlalu dekat ke bagian bawah layar"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Untuk mengubah sensitivitas gestur kembali, buka Setelan"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Geser untuk kembali"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Untuk kembali ke layar terakhir, geser dari tepi kiri atau kanan ke tengah layar."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Untuk kembali ke layar yang sebelumnya dibuka, geser dari tepi kiri atau kanan ke tengah layar."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Untuk kembali ke layar terakhir, geser dengan 2 jari dari tepi kiri atau kanan ke tengah layar."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Kembali"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pastikan Anda menggeser ke atas dari tepi bawah layar."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pastikan Anda tidak menjeda sebelum melepaskan."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pastikan Anda menggeser lurus ke atas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Anda telah menyelesaikan gestur menuju Layar utama. Selanjutnya, pelajari cara beralih kembali."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Anda telah menyelesaikan gestur menuju Layar utama."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Geser dari tepi kiri atau kanan ke tengah layar"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pastikan Anda menggeser ke atas dari tepi bawah layar"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pastikan Anda tidak berhenti sebelum melepaskan sentuhan"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pastikan Anda menggeser lurus ke atas"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Anda telah menyelesaikan gestur buka layar utama. Berikutnya, pelajari cara melakukan gestur kembali."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Anda telah menyelesaikan gestur buka layar utama"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Geser untuk beralih ke layar utama"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Geser ke atas dari bagian bawah layar. Gestur ini akan selalu membawa Anda ke Layar utama."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Geser ke atas dengan 2 jari dari bawah layar. Gestur ini akan selalu membawa Anda ke Layar utama."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Buka layar utama"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Untuk membuka layar utama kapan saja, geser ke atas dari bagian bawah layar"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pastikan Anda menggeser ke atas dari tepi bawah layar."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Coba tahan jendela lebih lama sebelum melepaskan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pastikan Anda menggeser lurus ke atas, lalu menjedanya."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Geser ke atas dari bagian bawah layar"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Bagus."</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pastikan Anda menggeser ke atas dari tepi bawah layar"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Coba tahan jendela lebih lama sebelum melepaskan"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pastikan Anda menggeser lurus ke atas, lalu berhenti sejenak"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Anda telah mempelajari cara menggunakan gestur. Untuk menonaktifkan gestur, buka Setelan."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Anda telah menyelesaikan gestur beralih aplikasi."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Anda telah menyelesaikan gestur beralih aplikasi"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Geser untuk beralih aplikasi"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Untuk beralih antar-aplikasi, geser ke atas dari bagian bawah layar, tahan, lalu lepaskan."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Untuk beralih dari satu aplikasi ke aplikasi lain, geser ke atas dari bagian bawah layar, tahan, lalu lepaskan."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Untuk beralih antar-aplikasi, geser ke atas dengan 2 jari dari bawah layar, tahan, lalu lepaskan."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Beralih aplikasi"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Geser ke atas dari bagian bawah layar, tahan, kemudian lepaskan"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Bagus."</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Semua siap"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Selesai"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Setelan"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Coba lagi"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Semua siap."</string>
- <string name="allset_hint" msgid="459504134589971527">"Geser ke atas untuk beralih ke layar utama"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Selesai!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Geser ke atas untuk membuka Layar utama"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Ketuk tombol layar utama untuk membuka layar utama"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Anda sudah siap untuk mulai menggunakan <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"perangkat"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"Bagikan"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Pisahkan"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Ketuk apl lain untuk menggunakan layar terpisah"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Ketuk aplikasi lain untuk memakai layar terpisah"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Keluar dari pemilihan layar terpisah"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pilih aplikasi lain untuk memakai layar terpisah"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Lewati tutorial gestur?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar ditampilkan"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar disembunyikan"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Menu navigasi"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Selalu tampilkan Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Ubah mode navigasi"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Pemisah Taskbar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Pindahkan ke atas/kiri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pindahkan ke bawah/kanan"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Tampilkan # aplikasi lain.}other{Tampilkan # aplikasi lain.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> dan <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Menambahkan aplikasi ke Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Batalkan"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index f58e6de..998c23f 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Kveikt á tillögum að forritum"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Slökkt er á tillögðum forritum"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tillaga að forriti: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar að miðju skjásins og sleppa síðan."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Snúðu tækinu"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Snúðu tækinu til að ljúka leiðsögn um bendingastjórnun"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar að miðju skjásins og sleppa síðan"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Þú lærðir að strjúka frá hægri til að bakka. Næst skaltu læra hvernig þú skiptir á milli forrita."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Þú laukst við að kynna þér bendinguna „til baka“."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Passaðu að strjúka ekki of nálægt neðri brún skjásins."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Þú laukst við að kynna þér bendinguna „til baka“"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Passaðu að strjúka ekki of nálægt neðri brún skjásins"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Til að breyta næmi til baka-bendingar ferðu í stillingar"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Strjúktu til að fara til baka"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Til að fara til baka á síðasta skjá skaltu strjúka frá vinstri eða hægri brún að miðju skjásins."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Strjúktu frá vinstri eða hægri brún að miðju skjásins með 2 fingrum til að fara aftur á síðasta skjá."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Til baka"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Passaðu að strjúka upp frá neðri brún skjásins."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Passaðu að stoppa ekki áður en þú sleppir."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Passaðu að strjúka beint upp."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Þú laukst við að kynna þér bendinguna „heim“. Næst skaltu læra hvernig þú ferð „til baka“."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Þú laukst við að kynna þér bendinguna „heim“."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Strjúktu frá vinstri eða hægri brún að miðju skjásins"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Passaðu að strjúka upp frá neðri brún skjásins"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Passaðu að stoppa ekki áður en þú sleppir"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Passaðu að strjúka beint upp"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Þú laukst við að kynna þér bendinguna „heim“. Næst skaltu læra hvernig þú ferð „til baka“."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Þú laukst við að kynna þér bendinguna „heim“"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Strjúktu til að fara heim"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Strjúktu upp frá neðri hluta skjásins. Þetta flytur þig alltaf á heimaskjáinn."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Strjúktu frá neðri brún skjásins með 2 fingrum. Þessi bending opnar ávallt heimaskjáinn."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Fara á heimaskjá"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Strjúktu upp frá neðsta hluta skjásins til að opna heimskjáinn hvenær sem er"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Passaðu að strjúka upp frá neðri brún skjásins."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prófaðu að halda fingrinum lengur á glugganum áður en þú sleppir."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Passaðu að strjúka beint upp og stoppa svo."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Strjúktu upp frá neðri hluta skjásins"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Vel gert!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Passaðu að strjúka upp frá neðri brún skjásins"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prófaðu að halda fingrinum lengur á glugganum áður en þú sleppir"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Passaðu að strjúka beint upp og stoppa svo"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Þú kynntir þér hvernig á að nota bendingar. Opnaðu stillingar til að slökkva á bendingum."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Þú laukst við að kynna þér bendinguna „skipta um forrit“."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Þú laukst við að kynna þér bendinguna „skipta um forrit“"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Strjúktu til að skipta á milli forrita"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Strjúktu upp frá neðri hluta skjásins, haltu og slepptu svo til að skipta á milli forrita."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Strjúktu upp frá neðri brún skjásins með 2 fingrum, haltu og slepptu til að skipta á milli forrita."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Skipta um forrit"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Strjúktu upp frá neðri hluta skjásins, haltu inni og slepptu svo"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Vel gert!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Allt til reiðu"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Lokið"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Stillingar"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skjámynd"</string>
<string name="action_split" msgid="2098009717623550676">"Skipta"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Ýttu á annað forrit til að nota skjáskiptingu"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Loka skjáskiptingu"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Veldu annað forrit til að nota skjáskiptingu"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Forritið eða fyrirtækið leyfir ekki þessa aðgerð"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Sleppa flettileiðsögn?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Forritastika sýnd"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Forritastika falin"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Yfirlitsstika"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Alltaf sýna forritastiku"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Breyta leiðsagnarstillingu"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Skipting forritastiku"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Færa efst/til vinstri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Færa neðst/til hægri"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Sýna # forrit í viðbót.}one{Sýna # forrit í viðbót.}other{Sýna # forrit í viðbót.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> og <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Forriti bætt við skjáborð"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Hætta við"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 17e379f..3755dbb 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"La funzionalità app suggerite è attiva"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"La funzionalità app suggerite è disattivata"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assicurati di scorrere dal bordo all\'estrema destra o all\'estrema sinistra."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Assicurati di scorrere dal bordo destro o sinistro verso il centro dello schermo e solleva il dito."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ruota il dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ruota il dispositivo per completare il tutorial relativo alla navigazione tramite gesti"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Assicurati di scorrere dal bordo all\'estrema destra o all\'estrema sinistra"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Assicurati di scorrere dal bordo destro o sinistro verso il centro dello schermo e solleva il dito"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Hai imparato a scorrere da destra per tornare indietro. Ora impara come passare da un\'app all\'altra."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Hai completato il gesto Indietro."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assicurati di non scorrere troppo vicino alla parte inferiore dello schermo."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Hai completato il gesto Indietro"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Assicurati di non scorrere troppo vicino alla parte inferiore dello schermo"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Usa Impostazioni per cambiare sensibilità del gesto Indietro"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Scorri per tornare indietro"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Per tornare all\'ultima schermata, scorri dal bordo sinistro o destro verso il centro dello schermo."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Per tornare all\'ultima schermata, scorri con 2 dita dal bordo sinistro o destro verso il centro dello schermo."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Vai indietro"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assicurati di non fare pause prima di sollevare il dito."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assicurati di scorrere verso l\'alto senza fermarti."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Hai completato il gesto per andare alla schermata Home. Ora, impara come tornare indietro."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Hai completato il gesto Vai alla schermata Home."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Scorri dal bordo sinistro o destro verso il centro dello schermo"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Assicurati di non fare pause prima di sollevare il dito"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Assicurati di scorrere verso l\'alto senza fermarti"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Hai completato il gesto Vai alla schermata Home. Ora, impara come tornare indietro."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Hai completato il gesto Vai alla schermata Home"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Scorri per andare alla schermata Home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Scorri verso l\'alto dalla parte inferiore dello schermo. Questo gesto ti porta sempre alla schermata Home."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Scorri verso l\'alto con 2 dita dal basso. Questo gesto ti porta sempre alla schermata Home."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Vai alla schermata Home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Per andare alla schermata Home in qualsiasi momento, scorri sullo schermo dal basso verso l\'alto"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prova a tenere premuta la finestra più a lungo prima di rilasciarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assicurati di scorrere verso l\'alto senza fermarti, poi fai una pausa."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Scorri verso l\'alto dalla parte inferiore dello schermo"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Ottimo lavoro!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prova a tenere premuta la finestra più a lungo prima di rilasciarla"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Assicurati di scorrere verso l\'alto senza fermarti, poi fai una pausa"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Hai imparato a usare i gesti. Per disattivarli, vai alle Impostazioni."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Hai completato il gesto Cambia app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Hai completato il gesto Cambia app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Scorri per passare da un\'app all\'altra"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Per spostarti tra le app, scorri verso l\'alto dal fondo dello schermo, tieni premuto e rilascia."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Per spostarti tra le app, scorri dal basso verso l\'alto sullo schermo, tieni premuto e rilascia."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Per spostarti tra le app, scorri verso l\'alto con 2 dita, tieni premuto e rilascia."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Cambia app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Scorri verso l\'alto dalla parte inferiore dello schermo, tieni premuto e poi rilascia"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Ben fatto!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Fatto"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fine"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Impostazioni"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Dividi"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tocca un\'altra app per usare lo schermo diviso"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Esci dalla selezione dello schermo diviso"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Scegli un\'altra app per usare lo schermo diviso"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Questa azione non è consentita dall\'app o dall\'organizzazione"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Saltare il tutorial di navigazione?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra delle app visualizzata"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra delle app nascosta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra di navigazione"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Mostra sempre barra delle app"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Cambia modalità di navigazione"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisore barra delle app"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sposta in alto/a sinistra"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sposta in basso/a destra"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostra # altra app.}other{Mostra altre # app.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> e <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Aggiunta app a desktop in corso…"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annulla"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index dc30dc6..e07d338 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -44,40 +44,46 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"התכונה \'הצעות לאפליקציות\' מופעלת"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ההצעות לאפליקציות מושבתות"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"האפליקציות החזויות: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"חשוב להקפיד להחליק מהקצה השמאלי או הימני."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"חשוב להקפיד להחליק מהקצה השמאלי או הימני למרכז המסך ואז לשחרר."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"צריך לסובב את המכשיר"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"צריך לסובב את המכשיר כדי להשלים את המדריך לניווט באמצעות תנועות"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"חשוב להחליק מהקצה השמאלי או הימני"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"חשוב להחליק מהקצה השמאלי או הימני למרכז המסך ואז לשחרר"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"למדת איך להחליק מצד ימין כדי לחזור אחורה. בשלב הבא לומדים איך לעבור בין אפליקציות."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"השלמת את תנועת \'הקודם\'."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"חשוב להקפיד שלא להחליק קרוב מדי לתחתית המסך."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"השלמת את התנועה \'חזרה אחורה\'"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"חשוב שלא להחליק קרוב מדי לתחתית המסך"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"כדי לשנות את מידת הרגישות של תנועת החזרה, יש לעבור להגדרות"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"יש להחליק כדי לחזור"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"כדי לחזור למסך הקודם, יש להחליק מהקצה השמאלי או הימני למרכז המסך."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"כדי לחזור למסך הקודם, יש להחליק עם שתי אצבעות מהקצה השמאלי או הימני למרכז המסך."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"הקודם"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"חשוב להקפיד להחליק למעלה מהקצה התחתון של המסך."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"חשוב לוודא שלא מחכים לפני שמשחררים."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"חשוב להקפיד להחליק ישר למעלה."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"השלמת את תנועת המעבר למסך הבית. בשלב הבא לומדים איך לחזור למסך הקודם."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"השלמת את תנועת המעבר למסך הבית."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"מחליקים מהקצה השמאלי או הימני למרכז המסך"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"חשוב להחליק למעלה מהקצה התחתון של המסך"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"חשוב שלא לחכות לפני שחרור האצבע"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"חשוב להחליק ישר למעלה"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"השלמת את תנועת המעבר למסך הבית. בשלב הבא נראה איך לחזור למסך הקודם."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"השלמת את תנועת המעבר למסך הבית"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"יש להחליק כדי לעבור למסך הבית"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"החלקה למעלה מתחתית המסך תמיד תעביר אותך למסך הבית."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"יש להחליק למעלה עם שתי אצבעות מתחתית המסך. התנועה הזו תמיד מעבירה אותך למסך הבית."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"מעבר למסך הבית"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"למעבר למסך הבית בכל שלב, צריך להחליק למעלה מהחלק התחתון של המסך"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"חשוב להקפיד להחליק למעלה מהקצה התחתון של המסך."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"אפשר להחזיק את החלון זמן רב יותר לפני שמשחררים."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"חשוב להקפיד להחליק ישר למעלה ואז להמתין."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"מחליקים כלפי מעלה מהחלק התחתון של המסך"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"מעולה!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"חשוב להחליק למעלה מהקצה התחתון של המסך"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"כדאי לנסות להחזיק את החלון זמן רב יותר לפני שחרור האצבע"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"חשוב להחליק ישר למעלה ואז להמתין"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"למדת איך להשתמש בתנועות. ניתן להשבית את התנועות ב\'הגדרות\'."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"השלמת את תנועת המעבר בין האפליקציות."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"השלמת את תנועת המעבר בין האפליקציות"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"יש להחליק כדי לעבור בין אפליקציות"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"כדי לעבור בין אפלקציות, יש להחליק למעלה מתחתית המסך, להחזיק ולאחר מכן לשחרר."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"כדי לעבור בין אפלקציות, יש להחליק למעלה עם שתי אצבעות מתחתית המסך, להחזיק ולאחר מכן לשחרר."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"מעבר בין אפליקציות"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"מחליקים כלפי מעלה מתחתית המסך, מחזיקים ואז משחררים"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"כל הכבוד!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"הכול מוכן"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"סיום"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"הגדרות"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ניסיון חוזר"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"איזה יופי!"</string>
+ <string name="gesture_tutorial_nice" msgid="2936275692616928280">"יפה!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"מדריך <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"הכול מוכן!"</string>
<string name="allset_hint" msgid="459504134589971527">"כדי לחזור לדף הבית, מחליקים כלפי מעלה"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"צילום מסך"</string>
<string name="action_split" msgid="2098009717623550676">"פיצול"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"צריך להקיש על אפליקציה אחרת כדי להשתמש במסך מפוצל"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"יציאה מתצוגת מסך מפוצל"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"כדי להשתמש במסך מפוצל צריך לבחור אפליקציה אחרת"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"האפליקציה או הארגון שלך אינם מתירים את הפעולה הזאת"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"לדלג על המדריך לניווט?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"סרגל האפליקציות מוצג"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"סרגל האפליקציות מוסתר"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"סרגל הניווט"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"סרגל האפליקציות מוצג תמיד"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"שינוי מצב הניווט"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"המחיצה בסרגל האפליקציות"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"העברה לפינה השמאלית/העליונה"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"העברה לפינה הימנית/התחתונה"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{הצגת אפליקציה אחת (#) נוספת.}one{הצגת # אפליקציות נוספות.}two{הצגת # אפליקציות נוספות.}other{הצגת # אפליקציות נוספות.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ו-<xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"האפליקציה מתווספת לשולחן העבודה"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ביטול"</string>
</resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 75e3bf8..7517f9d 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -44,39 +44,45 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"アプリの候補表示が有効です"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"アプリの候補は無効です"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"予測されたアプリ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"右端または左端からスワイプしてください。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"画面の右端または左端から中央に向かってスワイプし、指を離してください。"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"デバイスを回転してください"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ジェスチャー ナビゲーションのチュートリアルを終了するには、デバイスを回転してください"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"右端または左端からスワイプしてください"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"画面の右端または左端から中央に向かってスワイプし、指を離してください"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"右側からスワイプして前の画面に戻る方法を学習しました。次は、アプリを切り替える方法を覚えましょう。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"「戻る」操作を学習しました。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"スワイプする際は画面の下部に近づきすぎないようにしましょう。"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"「戻る」操作を学習しました"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"スワイプする際は画面の下部に近づきすぎないようにしましょう"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"「戻る」操作の感度を変更するには [設定] に移動します"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"スワイプで戻る"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"直前の画面に戻るには、画面の左端または右端から中央に向かってスワイプします。"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"直前の画面に戻るには、2 本の指で画面の左端または右端から中央に向かってスワイプします。"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"戻る"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"画面の下端から上にスワイプしてください。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"指を離す前にいったん止めないでください。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"まっすぐ上にスワイプしてください。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"「ホームに戻る」操作を学習しました。次は、前の画面に戻る方法を覚えましょう。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"「ホームに戻る」操作を学習しました。"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"画面の左端または右端から中央に向かってスワイプします"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"画面の下端から上にスワイプしてください"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"指を離す前にいったん止めないでください"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"まっすぐ上にスワイプしてください"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"「ホームに移動」操作を学習しました。次は、前の画面に戻る方法を覚えましょう。"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"「ホームに移動」操作を学習しました"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"スワイプでホームに戻る"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"画面を下から上にスワイプします。この操作でいつでもホーム画面に戻れます。"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 本の指で画面下部から上にスワイプします。この操作で常にホーム画面に戻ります。"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ホームに移動"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"画面を下から上にスワイプすると、ホーム画面にいつでも移動できます"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"画面の下端から上にスワイプしてください。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ウィンドウをもう少し長く押してから指を離すようにしてみましょう。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"まっすぐ上にスワイプしてから、いったん指を止めてください。"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"画面を下から上にスワイプします"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"よくできました!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"画面の下端から上にスワイプしてください"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ウィンドウをもう少し長く押してから指を離すようにしてみましょう"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"まっすぐ上にスワイプしてから、いったん指を止めてください"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"主なジェスチャーについて学びました。ジェスチャーを OFF にするには、設定に移動してください。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"「アプリを切り替える」操作を完了しました。"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"「アプリの切り替え」操作を学習しました"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"スワイプでアプリを切り替える"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"アプリを切り替えるには、画面を下から上にスワイプして長押しし、指を離します。"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"アプリを切り替えるには、2 本の指で画面下部から上にスワイプしたまま長押しし、指を離します。"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"アプリの切り替え"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"画面を下から上にスワイプして長押しし、指を離します"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"完了です!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"設定完了"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完了"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"もう一度"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"もう一度行ってください"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"その調子です!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"チュートリアル <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"設定完了"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"スクリーンショット"</string>
<string name="action_split" msgid="2098009717623550676">"分割"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"分割画面を使用するには、他のアプリをタップします"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"分割画面の選択を終了します"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"分割画面にするには、別のアプリを選択してください"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"この操作はアプリまたは組織で許可されていません"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"操作チュートリアルをスキップしますか?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"タスクバー表示"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"タスクバー非表示"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ナビゲーション バー"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"常にタスクバーを表示"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ナビゲーション モードを変更"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"タスクバーの区切り"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"上 / 左に移動"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"下 / 右に移動"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{他 # 件のアプリを表示できます。}other{他 # 件のアプリを表示できます。}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> と <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"アプリをデスクトップに追加する"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"キャンセル"</string>
</resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 13232da..64aa870 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"აპის შეთავაზებები ჩართულია"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"აპის შეთავაზებები გათიშულია"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ნაწინასწარმეტყველები აპი: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"გადაფურცლეთ უკიდურესი მარჯვენა ან მარცხენა ბოლოდან."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"გადაფურცლეთ მარჯვენა ან მარცხენა კიდიდან ეკრანის ცენტრისკენ და თითი აუშვით."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"შეატრიალეთ მოწყობილობა"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ჟესტებით ნავიგაციის სახელმძღვანელოს დასასრულებლად შეატრიალეთ თქვენი მოწყობილობა"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"გადაფურცლეთ უკიდურესი მარჯვენა ან მარცხენა ბოლოდან"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"გადაფურცლეთ მარჯვენა ან მარცხენა კიდიდან ეკრანის ცენტრისკენ და თითი აუშვით"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"თქვენ ისწავლეთ მარჯვნიდან გადაფურცვლა უკან დასაბრუნებლად. ახლა კი შეიტყვეთ, როგორ გადართოთ აპები."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"თქვენ შეასრულეთ უკან დაბრუნების ჟესტი."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"არ გადაფურცლოთ ეკრანის ბოლოსთან ახლოს."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"თქვენ შეასრულეთ უკან დაბრუნების ჟესტი"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"არ გადაფურცლოთ ეკრანის ბოლოსთან ახლოს"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"დაბრუნების ჟესტის მგრძნობელობის შესაცვლელად გადადით პარამეტრებზე"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"უკან დასაბრუნებლად გადაფურცლეთ"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ბოლო ეკრანზე დასაბრუნებლად გადაფურცლეთ მარცხენა ან მარჯვენა კიდიდან ეკრანის ცენტრისკენ."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ბოლო ეკრანზე დასაბრუნებლად ორი თითით გადაფურცლეთ მარცხენა ან მარჯვენა კიდიდან ეკრანის ცენტრისკენ."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"უკან დაბრუნება"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"არ დააპაუზოთ თითის აშვებამდე."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"გადაფურცლეთ ზემოთ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი. ახლა კი შევიტყოთ, თუ როგორ დავბრუნდეთ უკან."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"გადაფურცლეთ მარცხენა ან მარჯვენა ბოლოდან ეკრანის შუისკენ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"არ დააპაუზოთ თითის აშვებამდე"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"გადაფურცლეთ პირდაპირ ზემოთ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი. ახლა კი შევიტყოთ, თუ როგორ დავბრუნდეთ უკან."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"მთავარი გვერდის სანახავად გადაფურცლეთ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ. ამ ჟესტს ყოველთვის მთავარი გვერდის ეკრანზე გადაყავხართ."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ორი თითით გადაფურცლეთ ეკრანის ქვედა ნაწილიდან. ეს ჟესტი ყოველთვის მთავარ ეკრანზე გადაგიყვანთ."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"მთავარზე გადასვლა"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ნებისმიერ დროს მთავარ ეკრანზე გადასასვლელად, გადაფურცლეთ ეკრანის ქვემოდან ზემოთ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"უფრო ხანგრძლივად დააჭირეთ თითი ფანჯარას, რომ არ დაიხუროს."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"გადაფურცლეთ პირდაპირ ზემოთ და შემდეგ დააპაუზეთ."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"გადაფურცლეთ ზემოთ თქვენი ეკრანის ბოლოდან"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"შესანიშნავია!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"უფრო ხანგრძლივად დააჭირეთ თითი ფანჯარას, შემდეგ აუშვით"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"გადაფურცლეთ პირდაპირ ზემოთ და შემდეგ დააპაუზეთ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"თქვენ ისწავლეთ ჟესტების გამოყენება. ჟესტების გამოსართავად გადადით პარამეტრებში."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"თქვენ შეასრულეთ აპების გადართვის ჟესტი."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"თქვენ შეასრულეთ აპების გადართვის ჟესტი"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"აპების გადასართავად გადაფურცლეთ"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"აპების გადასართავად, გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ, დააყოვნეთ, შემდეგ თითი აუშვით."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"აპებს შორის გადასართავად ეკრანის ქვედა კიდიდან ორი თითით გადაფურცლეთ, დააყოვნეთ და აუშვით."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"აპების გადართვა"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ, დააყოვნეთ, შემდეგ აუშვით"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ყოჩაღ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"მზად არის"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"მზადაა"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"პარამეტრები"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ეკრანის ანაბეჭდი"</string>
<string name="action_split" msgid="2098009717623550676">"გაყოფა"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"შეეხეთ სხვა აპს ეკრანის გასაყოფად"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ეკრანის გაყოფის არჩევანიდან გასვლა"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"აირჩიეთ სხვა აპი ეკრანის გასაყოფად"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ეს მოქმედება არ არის დაშვებული აპის ან თქვენი ორგანიზაციის მიერ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"გსურთ, გამოტოვოთ ნავიგაციის სახელმძღვანელო?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ამოცანათა ზოლი ნაჩვენებია"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ამოცანათა ზოლი დამალულია"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ნავიგაციის ზოლი"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ამოცანათა ზოლის მუდამ ჩვენება"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"შეცვალეთ ნავიგაციის რეჟიმი"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ამოცანათა ზოლის გამყოფი"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ზემოთ/მარცხნივ გადატანა"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ქვემოთ/მარჯვნივ გადატანა"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{#-ით მეტი აპის ჩენება}other{#-ით მეტი აპის ჩვენება.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> და <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"მიმდინარეობს აპის დესკტოპზე დამატება"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"გაუქმება"</string>
</resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 9f006a9..cde0dfd 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -44,51 +44,58 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"\"Қолданба ұсыныстары\" функциясы қосылды."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"\"Қолданба ұсыныстары\" функциясы өшірулі."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Болжалды қолданба: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Экранның оң немесе сол жиегінен сырғытыңыз."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Экранның оң немесе сол жиегінен ортасына қарай сырғытып, саусағыңызды жіберіңіз."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Құрылғыны бұрыңыз"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Қимылмен басқару нұсқаулығын аяқтау үшін құрылғыны бұрыңыз."</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Экранның оң немесе сол жиегінен сырғытыңыз."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Экранның оң немесе сол жиегінен ортасына қарай сырғытып, саусағыңызды жіберіңіз."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Оңнан солға сырғыту арқылы артқа қайтуды үйрендіңіз. Енді қолданбаларды ауыстыруды үйреніңіз."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Артқа қайту қимылын аяқтадыңыз."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Саусағыңызбен сырғыту кезінде экранның төменгі жағына тым жақындамаңыз."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Артқа қайту қимылын аяқтадыңыз."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Сырғытқанда саусақты экранның төменгі жағына қатты жақындатпаңыз."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Артқа қайту қимылы сезгіштігін параметрлерден өзгертіңіз."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Артқа қайту үшін сырғытыңыз"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Соңғы ашылған экранға оралу үшін экранның сол немесе оң жақ шетінен ортасына қарай сырғытыңыз."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Соңғы ашылған экранға оралу үшін екі саусақпен экранның сол не оң жағынан ортасына сырғытыңыз."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Артқа"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Жіберер алдында кідіріс жасамаңыз."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Тігінен жоғары қарай сырғытыңыз."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Негізгі экранға қайту қимылын аяқтадыңыз. Енді артқа қайтуды үйреніңіз."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Негізгі экранға қайту қимылын аяқтадыңыз."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Экранның сол немесе оң жақ шетінен ортасына қарай сырғытыңыз."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Жіберер алдында кідіріс жасамаңыз."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Тігінен жоғары қарай сырғытыңыз."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Негізгі экранға қайту қимылын аяқтадыңыз. Енді артқа қайтуды үйреніңіз."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Негізгі экранға қайту қимылын аяқтадыңыз."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Негізгі экранға өту үшін сырғытыңыз"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Экранның төменгі жағынан жоғары қарай сырғытыңыз. Сонда негізгі экран ашылады."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Екі саусақпен экранның төменгі жағынан жоғары сырғытыңыз. Бұл қимыл үнемі негізгі экранды ашады."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Негізгі бетке өту"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Кез келген уақытта негізгі экранға өту үшін экранның астыңғы жағынан жоғары қарай сырғытыңыз."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Жіберер алдында терезені ұзағырақ ұстап тұруға тырысыңыз."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Тігінен жоғары қарай сырғытыңыз да, кідіріңіз."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Негізгі экранға өту"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Экранның төменгі жағынан жоғары қарай сырғытыңыз."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Жарайсыз!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Жіберер алдында терезені ұзағырақ ұстап тұруға тырысыңыз."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Тігінен жоғары қарай сырғытыңыз да, кідіріңіз."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Қимылдарды қолдануды үйрендіңіз. Қимылдарды өшіру үшін \"Параметрлер\" бөліміне өтіңіз."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Қолданбаларды ауыстыру қимылын аяқтадыңыз."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Қолданбаларды ауыстыру қимылын аяқтадыңыз."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Қолданбаларды ауыстыру үшін сырғытыңыз"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Бір қолданбадан екіншісіне ауысу үшін экранның төменгі жағынан жоғары қарай сырғытып, ұстап тұрып жіберіңіз."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Бір қолданбадан екіншісіне ауысу үшін экранның төменгі жағынан жоғары қарай сырғытып, ұстап тұрыңыз, кейін жіберіңіз."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Бір қолданбадан екіншісіне ауысу үшін екі саусақпен экранның төменгі жағынан жоғары қарай сырғытып, ұстап тұрып жіберіңіз."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Қолданбалар арасында ауысу"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Экранның төменгі жағынан жоғары қарай сырғытып, ұстап тұрыңыз да, жіберіңіз."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Жарайсыз!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Бәрі дайын"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Дайын"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Параметрлер"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Қайталау"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Қайталап көріңіз"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Жақсы!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Оқулық: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Бәрі дайын!"</string>
<string name="allset_hint" msgid="459504134589971527">"Негізгі экранға өту үшін жоғары қарай сырғытыңыз."</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Негізгі экранға өту үшін негізгі экран түймесін түртіңіз."</string>
<string name="allset_description_generic" msgid="5385500062202019855">"<xliff:g id="DEVICE">%1$s</xliff:g> пайдалануға дайын."</string>
- <string name="default_device_name" msgid="6660656727127422487">"құрылғы"</string>
+ <string name="default_device_name" msgid="6660656727127422487">"Құрылғы"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Навигацияның жүйелік параметрлері"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Бөлісу"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="action_split" msgid="2098009717623550676">"Бөлу"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Экранды бөлу режимін пайдалану үшін басқа қолданбаны түртіңіз."</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Экранды бөлу режимінен шығу"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Экранды бөлу үшін басқа қолданбаны таңдаңыз."</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Бұл әрекетке қолданба не ұйым рұқсат етпейді."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Қимылдар оқулығын өткізіп жіберу керек пе?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Тапсырмалар жолағы көрсетілді"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Тапсырмалар жолағы жасырылды"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Навигация жолағы"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Тапсырма жолағын үнемі көрсету"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Навигация режимін өзгерту"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Тапсырмалар жолағын бөлгіш"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Жоғары/солға жылжыту"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Төмен/оңға жылжыту"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Тағы # қолданбаны көрсету.}other{Тағы # қолданбаны көрсету.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> және <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Жұмыс үстеліне қолданба қосу"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Бас тарту"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 738e454..89d8335 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"បានបើកការណែនាំកម្មវិធី"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"បានបិទការណែនាំកម្មវិធី"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"កម្មវិធីដែលបានព្យាករ៖ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ត្រូវប្រាកដថាអ្នកអូសពីគែមខាងស្ដាំ ឬខាងឆ្វេង។"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ត្រូវប្រាកដថាអ្នកអូសពីគែមខាងស្ដាំ ឬខាងឆ្វេងទៅផ្នែកកណ្ដាលនៃអេក្រង់ រួចដកដៃ។"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"បង្វិលឧបករណ៍របស់អ្នក"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"សូមបង្វិលឧបករណ៍របស់អ្នក ដើម្បីបញ្ចប់មេរៀនអំពីការរុករកដោយប្រើចលនា"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ត្រូវប្រាកដថាអ្នកអូសពីគែមខាងស្ដាំ ឬខាងឆ្វេង"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ត្រូវប្រាកដថាអ្នកអូសពីគែមខាងស្ដាំ ឬខាងឆ្វេងទៅផ្នែកកណ្ដាលនៃអេក្រង់ រួចដកដៃ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"អ្នកបានស្វែងយល់ពីរបៀបអូសពីខាងស្ដាំ ដើម្បីថយក្រោយ។ បន្ទាប់ទៀត សូមស្វែងយល់ពីរបៀបប្ដូរកម្មវិធី។"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"អ្នកបានបញ្ចប់ចលនាថយក្រោយហើយ។"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ត្រូវប្រាកដថាអ្នកមិនអូសទៅជិតផ្នែកខាងក្រោមនៃអេក្រង់ពេក។"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"អ្នកបានបញ្ចប់ចលនាថយក្រោយហើយ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ត្រូវប្រាកដថាអ្នកមិនអូសទៅជិតផ្នែកខាងក្រោមនៃអេក្រង់ពេក"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ដើម្បីប្ដូរកម្រិតរំញោចនឹងចលនាថយក្រោយ សូមចូលទៅកាន់ការកំណត់"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"អូសដើម្បីថយក្រោយ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ដើម្បីត្រឡប់ទៅអេក្រង់ចុងក្រោយវិញ សូមអូសពីគែមខាងឆ្វេង ឬខាងស្ដាំទៅផ្នែកកណ្ដាលនៃអេក្រង់។"</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ដើម្បីត្រឡប់ទៅអេក្រង់មុនវិញ សូមអូសពីគែមខាងឆ្វេង ឬខាងស្ដាំទៅផ្នែកកណ្ដាលនៃអេក្រង់។"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ដើម្បីត្រឡប់ទៅអេក្រង់ចុងក្រោយវិញ អូសដោយប្រើម្រាមដៃពីរពីគែមខាងឆ្វេង ឬខាងស្ដាំទៅផ្នែកកណ្ដាលនៃអេក្រង់។"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ថយក្រោយ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ត្រូវប្រាកដថាអ្នកអូសឡើងលើពីគែមខាងក្រោមនៃអេក្រង់។"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ត្រូវប្រាកដថាអ្នកមិនផ្អាក មុនពេលដកដៃ។"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ត្រូវប្រាកដថាអ្នកអូសត្រង់ឡើងលើ។"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"អ្នកបានបញ្ចប់ចលនាចូលទៅកាន់ទំព័រដើមហើយ។ បន្ទាប់មកទៀត សូមស្វែងយល់ពីរបៀបថយក្រោយ។"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"អ្នកបានបញ្ចប់ចលនាចូលទៅកាន់ទំព័រដើមហើយ។"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"អូសពីគែមខាងឆ្វេង ឬខាងស្ដាំទៅផ្នែកកណ្ដាលនៃអេក្រង់"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ត្រូវប្រាកដថាអ្នកអូសឡើងលើពីគែមខាងក្រោមនៃអេក្រង់"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ត្រូវប្រាកដថាអ្នកមិនផ្អាក មុនពេលដកដៃ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ត្រូវប្រាកដថាអ្នកអូសត្រង់ឡើងលើ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"អ្នកបានបញ្ចប់ចលនាចូលទៅកាន់ទំព័រដើមហើយ។ បន្ទាប់មកទៀត សូមស្វែងយល់ពីរបៀបថយក្រោយ។"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"អ្នកបានបញ្ចប់ចលនាចូលទៅកាន់ទំព័រដើមហើយ"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"អូសដើម្បីចូលទៅកាន់អេក្រង់ដើម"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក។ ចលនានេះនាំអ្នកទៅអេក្រង់ដើមជានិច្ច។"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"អូសឡើងលើដោយប្រើម្រាមដៃពីរពីផ្នែកខាងក្រោមនៃអេក្រង់។ ចលនានេះតែងតែនាំអ្នកទៅអេក្រង់ដើមជានិច្ច។"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ទៅទំព័រដើម"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ដើម្បីទៅកាន់អេក្រង់ដើមរបស់អ្នកនៅពេលណាក៏បាន សូមអូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ត្រូវប្រាកដថាអ្នកអូសឡើងលើពីគែមខាងក្រោមនៃអេក្រង់។"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"សាកល្បងសង្កត់វិនដូឱ្យបានយូរជាងនេះ មុនពេលដកដៃ។"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ត្រូវប្រាកដថាអ្នកអូសត្រង់ឡើងលើ រួចផ្អាក។"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ទៅអេក្រង់ដើម"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ធ្វើបានល្អ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ត្រូវប្រាកដថាអ្នកអូសឡើងលើពីគែមខាងក្រោមនៃអេក្រង់"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"សាកល្បងសង្កត់វិនដូឱ្យបានយូរជាងនេះ មុនពេលដកដៃ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ត្រូវប្រាកដថាអ្នកអូសត្រង់ឡើងលើ រួចផ្អាក"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"អ្នកបានស្វែងយល់អំពីរបៀបប្រើចលនាហើយ។ ដើម្បីបិទចលនា សូមចូលទៅកាន់ការកំណត់។"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"អ្នកបានបញ្ចប់ចលនាប្ដូរកម្មវិធីហើយ។"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"អ្នកបានបញ្ចប់ចលនាប្ដូរកម្មវិធីហើយ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"អូសដើម្បីប្ដូរកម្មវិធី"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ដើម្បីប្ដូររវាងកម្មវិធី សូមអូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក រួចចុចឱ្យជាប់ បន្ទាប់មកដកដៃចេញ។"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ដើម្បីប្ដូរកម្មវិធី អូសឡើងលើដោយប្រើម្រាមដៃពីរពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក សង្កត់ ហើយលែងវិញ។"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ប្ដូរកម្មវិធី"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក រួចចុចឱ្យជាប់ បន្ទាប់មកដកដៃចេញ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ល្អណាស់!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"រួចហើយ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"រួចរាល់"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ការកំណត់"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"រួចហើយ!"</string>
<string name="allset_hint" msgid="459504134589971527">"អូសឡើងលើ ដើម្បីចូលទៅកាន់អេក្រង់ដើម"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"ចុចប៊ូតុងដើម ដើម្បីចូលទៅកាន់អេក្រង់ដើមរបស់អ្នក"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"អ្នកអាចចាប់ផ្ដើមប្រើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបានហើយ"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"អ្នកអាចចាប់ផ្ដើមប្រើ<xliff:g id="DEVICE">%1$s</xliff:g>របស់អ្នកបានហើយ"</string>
<string name="default_device_name" msgid="6660656727127422487">"ឧបករណ៍"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ការកំណត់ការរុករកប្រព័ន្ធ"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"ចែករំលែក"</string>
<string name="action_screenshot" msgid="8171125848358142917">"រូបថតអេក្រង់"</string>
<string name="action_split" msgid="2098009717623550676">"បំបែក"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"ចុចកម្មវិធីផ្សេងទៀត ដើម្បីប្រើមុខងារបំបែកអេក្រង់"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ចាកចេញពីការជ្រើសរើសរបស់មុខងារបំបែកអេក្រង់"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"ជ្រើសរើសកម្មវិធីផ្សេងទៀត ដើម្បីប្រើមុខងារបំបែកអេក្រង់"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"សកម្មភាពនេះមិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី ឬស្ថាប័នរបស់អ្នកទេ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"រំលងមេរៀនអំពីការរុករកឬ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"បានបង្ហាញរបារកិច្ចការ"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"បានលាក់របារកិច្ចការ"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"របាររុករក"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"បង្ហាញរបារកិច្ចការជានិច្ច"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ប្ដូរមុខងាររុករក"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"បន្ទាត់ខណ្ឌចែករបារកិច្ចការ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ផ្លាស់ទីទៅខាងលើ/ឆ្វេង"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{បង្ហាញកម្មវិធី # ទៀត។}other{បង្ហាញកម្មវិធី # ទៀត។}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> និង <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"កំពុងបញ្ចូលកម្មវិធីទៅកុំព្យូទ័រ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"បោះបង់"</string>
</resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 37e0acd..b7cdd15 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -44,44 +44,50 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ಶಿಫಾರಸು ಮಾಡಿದ ಆ್ಯಪ್: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ನೀವು ಬಲಕೊನೆಯ ಅಂಚಿನಿಂದ ಅಥವಾ ಎಡಕೊನೆಯ ಅಂಚಿನಿಂದ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ನೀವು ಬಲ ಅಥವಾ ಎಡ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ನ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಂಡು ಬಿಟ್ಟುಬಿಡಿ."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ಗೆಸ್ಚರ್ ನ್ಯಾವಿಗೇಶನ್ ಟುಟೋರಿಯಲ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು, ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ನೀವು ಬಲಕೊನೆಯ ಅಂಚಿನಿಂದ ಅಥವಾ ಎಡಕೊನೆಯ ಅಂಚಿನಿಂದ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ನೀವು ಬಲ ಅಥವಾ ಎಡ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ನ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಂಡು ಬಿಟ್ಟುಬಿಡಿ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ಹಿಂದೆ ಹೋಗಲು ಬಲದಿಂದ ಸ್ವೈಪ್ ಮಾಡುವುದು ಹೇಗೆಂದು ಕಲಿತಿರಿ. ಮುಂದೆ, ಆ್ಯಪ್ಗಳನ್ನು ಬದಲಿಸುವುದು ಹೇಗೆಂದು ತಿಳಿಯಿರಿ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ನೀವು ಗೋ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ನೀವು ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗಕ್ಕೆ ಹೆಚ್ಚು ಹತ್ತಿರ ಸ್ವೈಪ್ ಮಾಡದಂತೆ ನೋಡಿಕೊಳ್ಳಿ."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ನೀವು ಗೋ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ನೀವು ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗಕ್ಕೆ ಹೆಚ್ಚು ಹತ್ತಿರ ಸ್ವೈಪ್ ಮಾಡದಂತೆ ನೋಡಿಕೊಳ್ಳಿ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ನ ಸೂಕ್ಷ್ಮತೆ ಬದಲಾಯಿಸಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ಹಿಂದಕ್ಕೆ ಹೋಗಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ಕೊನೆಯ ಸ್ಕ್ರೀನ್ಗೆ ಹಿಂತಿರುಗಲು, ಎಡ ಅಥವಾ ಬಲ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ಹಿಂದಿನ ಸ್ಕ್ರೀನ್ಗೆ ಮರಳಲು, ಎಡ ಅಥವಾ ಬಲ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ ಮಧ್ಯದವರೆಗೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ಹಿಂದಿನ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಲು, 2 ಬೆರಳುಗಳಿಂದ ಎಡ ಅಥವಾ ಬಲ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ಹಿಂದಿರುಗಿ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ವಿರಾಮಗೊಳಿಸದೆ ನಿಮ್ಮ ಬೆರಳನ್ನು ಸ್ಕ್ರೀನ್ನಿಂದ ಮೇಲೆತ್ತಿ."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ನೀವು ಗೋ ಹೋಮ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ. ಮುಂದೆ, ಹಿಂದಕ್ಕೆ ಹೋಗುವುದು ಹೇಗೆ ಎಂದು ತಿಳಿಯಿರಿ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ನೀವು ಗೋ ಹೋಮ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ಎಡ ಅಥವಾ ಬಲ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ನ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ವಿರಾಮಗೊಳಿಸದೆ ನಿಮ್ಮ ಬೆರಳನ್ನು ಸ್ಕ್ರೀನ್ನಿಂದ ಮೇಲೆತ್ತಿ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ನೀವು ಹೋಮ್ಗೆ ಹೋಗಿ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ. ಮುಂದೆ, ಹಿಂದಕ್ಕೆ ಹೋಗುವುದು ಹೇಗೆ ಎಂದು ತಿಳಿಯಿರಿ."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ನೀವು ಹೋಮ್ಗೆ ಹೋಗಿ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಹಿಂತಿರುಗಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ ಮೇಲೆ ಸ್ವೈಪ್ ಮಾಡಿ. ಈ ಗೆಸ್ಚರ್ ಯಾವಾಗಲೂ ನಿಮ್ಮನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಕರೆದೊಯ್ಯುತ್ತದೆ."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 ಬೆರಳುಗಳಿಂದ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ. ಈ ಗೆಸ್ಚರ್ ಯಾವಾಗಲೂ ನಿಮ್ಮನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಕರೆದೊಯ್ಯುತ್ತದೆ."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಿ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ಬೆರಳನ್ನು ಮೇಲೆತ್ತುವ ಮೊದಲು ವಿಂಡೋವನ್ನು ಹೆಚ್ಚು ಸಮಯ ಹಿಡಿದಿಡಲು ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ, ನಂತರ ವಿರಾಮಗೊಳಿಸಿ."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ಹೋಮ್ಗೆ ಹೋಗಿ"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ಭೇಷ್!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ಸ್ಕ್ರೀನ್ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ಬೆರಳನ್ನು ಮೇಲೆತ್ತುವ ಮೊದಲು ವಿಂಡೋವನ್ನು ಹೆಚ್ಚು ಸಮಯ ಹಿಡಿದಿಡಲು ಪ್ರಯತ್ನಿಸಿ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ, ನಂತರ ವಿರಾಮಗೊಳಿಸಿ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ಗೆಶ್ಚರ್ಗಳನ್ನು ಬಳಸುವುದು ಹೇಗೆಂದು ನೀವು ತಿಳಿದುಕೊಂಡಿರುವಿರಿ. ಗೆಶ್ಚರ್ಗಳನ್ನು ಆಫ್ ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಹೋಗಿ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ನೀವು ಆ್ಯಪ್ಗಳನ್ನು ಬದಲಾಯಿಸುವ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ನೀವು ಆ್ಯಪ್ಗಳನ್ನು ಬದಲಾಯಿಸುವ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ಆ್ಯಪ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ಆ್ಯಪ್ಗಳ ನಡುವೆ ಬದಲಿಸಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ, ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಿ, ನಂತರ ಬಿಟ್ಟುಬಿಡಿ."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ಆ್ಯಪ್ಗಳ ನಡುವೆ ಬದಲಿಸಲು, 2 ಬೆರಳುಗಳಿಂದ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ, ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಿ, ನಂತರ ಬಿಟ್ಟುಬಿಡಿ."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ಆ್ಯಪ್ಗಳನ್ನು ಬದಲಿಸಿ"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ, ಹೋಲ್ಡ್ ಮಾಡಿ, ನಂತರ ಬಿಡುಗಡೆ ಮಾಡಿ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ಭೇಷ್!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ಸಂಪೂರ್ಣ ಸಿದ್ಧವಾಗಿದೆ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ಮುಗಿದಿದೆ"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ಚೆನ್ನಾಗಿದೆ!"</string>
+ <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ಭೇಷ್!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ಟ್ಯುಟೋರಿಯಲ್ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!"</string>
<string name="allset_hint" msgid="459504134589971527">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="allset_button_hint" msgid="2395219947744706291">"ನಿಮ್ಮ ಮುಖಪುಟದ ಪರದೆಗೆ ಹೋಗಲು ಮುಖಪುಟ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="allset_button_hint" msgid="2395219947744706291">"ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಹೋಗಲು ಹೋಮ್ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ಧರಾಗಿರುವಿರಿ"</string>
<string name="default_device_name" msgid="6660656727127422487">"ಸಾಧನ"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</annotation></string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
<string name="action_split" msgid="2098009717623550676">"ವಿಭಜಿಸಿ"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಲು ಬೇರೆ ಆ್ಯಪ್ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಆಯ್ಕೆಯಿಂದ ನಿರ್ಗಮಿಸಿ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"\"ಪರದೆ ಬೇರ್ಪಡಿಸಿ\" ಬಳಸಲು ಬೇರೆ ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ಆ್ಯಪ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಕ್ರಿಯೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ನ್ಯಾವಿಗೇಶನ್ ಟ್ಯುಟೋರಿಯಲ್ ಸ್ಕಿಪ್ ಮಾಡಬೇಕೇ?"</string>
@@ -103,20 +110,25 @@
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"ಟಾಸ್ಕ್ಬಾರ್ ಅನ್ನು ಸ್ವಯಂ-ಮರೆಮಾಡಲು ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಗೆಸ್ಚರ್ ನ್ಯಾವಿಗೇಶನ್ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"ಟಾಸ್ಕ್ಬಾರ್ ಮೂಲಕ ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ಮುಗಿದಿದೆ"</string>
+ <string name="taskbar_edu_done" msgid="6880178093977704569">"ಆಯಿತು"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"ಮುಖಪುಟ"</string>
<string name="taskbar_button_a11y" msgid="5241161324875094465">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
<string name="taskbar_button_back" msgid="8558862226461164514">"ಹಿಂದೆ"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ಪರಿವರ್ತಕ"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"ಇತ್ತೀಚಿನವು"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="taskbar_button_notifications" msgid="7471740351507357318">"ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string>
<string name="taskbar_button_quick_settings" msgid="227662894293189391">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="taskbar_a11y_title" msgid="6432169809852243110">"ಟಾಸ್ಕ್ಬಾರ್"</string>
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ಟಾಸ್ಕ್ಬಾರ್ ತೋರಿಸಲಾಗಿದೆ"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ಟಾಸ್ಕ್ಬಾರ್ ಮರೆಮಾಡಲಾಗಿದೆ"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ನ್ಯಾವಿಗೇಷನ್ ಬಾರ್"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ಯಾವಾಗಲೂ ಟಾಸ್ಕ್ಬಾರ್ ತೋರಿಸಿ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ನ್ಯಾವಿಗೇಶನ್ ಮೋಡ್ ಬದಲಾಯಿಸಿ"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ಟಾಸ್ಕ್ಬಾರ್ ಡಿವೈಡರ್"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ಮೇಲಿನ/ಎಡಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ಕೆಳಗಿನ/ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{ಇನ್ನೂ # ಆ್ಯಪ್ ಅನ್ನು ತೋರಿಸಿ.}one{ಇನ್ನೂ # ಆ್ಯಪ್ಗಳನ್ನು ತೋರಿಸಿ.}other{ಇನ್ನೂ # ಆ್ಯಪ್ಗಳನ್ನು ತೋರಿಸಿ.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ಡೆಸ್ಕ್ಟಾಪ್ಗೆ ಆ್ಯಪ್ ಅನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ರದ್ದುಮಾಡಿ"</string>
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index cff87a1..c00eeed 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"앱 제안이 사용 설정됨"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"앱 제안이 사용 중지됨"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"예상 앱: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"오른쪽 또는 왼쪽 가장자리 끝에서 스와이프하세요."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"오른쪽 또는 왼쪽 가장자리에서 화면 중앙으로 스와이프한 후 손가락을 떼세요."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"기기를 회전시키세요"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"동작 탐색 튜토리얼을 완료하려면 기기를 회전시키세요."</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"오른쪽 또는 왼쪽 가장자리 끝에서 스와이프하세요."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"오른쪽 또는 왼쪽 가장자리에서 화면 중앙으로 스와이프한 후 손가락을 떼세요."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"오른쪽에서 스와이프하여 뒤로 돌아가는 방법을 배웠습니다. 이번에는 앱 전환 방법을 알아보겠습니다."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"돌아가기 동작을 완료했습니다."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"화면 하단에 지나치게 가까운 곳에서 스와이프하면 안 됩니다."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"돌아가기 동작을 완료했습니다."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"화면 하단에 지나치게 가까운 곳에서 스와이프하면 안 됩니다."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"돌아가기 동작의 민감도를 변경하려면 설정으로 이동하세요"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"스와이프하여 돌아가기"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"이전 화면으로 돌아가려면 왼쪽 또는 오른쪽 가장자리에서 화면 중앙으로 스와이프하세요."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"마지막 화면으로 돌아가려면 두 손가락을 사용해 왼쪽 또는 오른쪽 가장자리에서 화면 중앙으로 스와이프하세요"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"뒤로"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"손가락을 떼기 전에 멈추지 않아야 합니다."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"위로 곧게 스와이프하세요."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"홈으로 이동 동작을 완료했습니다. 이번에는 뒤로 돌아가는 방법을 알아보겠습니다."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"홈으로 이동 동작을 완료했습니다."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"왼쪽 또는 오른쪽 가장자리에서 화면 중앙으로 스와이프하세요."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"손가락을 떼기 전에 멈추지 않아야 합니다."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"위로 곧게 스와이프하세요."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"홈으로 이동 동작을 완료했습니다. 이번에는 뒤로 돌아가는 방법을 알아보겠습니다."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"홈으로 이동 동작을 완료했습니다."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"스와이프하여 홈으로 이동"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"화면 하단에서 위로 스와이프합니다. 이 동작을 사용하면 언제든지 홈 화면으로 이동할 수 있습니다."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"두 손가락을 사용해 화면 하단에서 위로 스와이프하세요. 이 동작을 사용하면 언제든지 홈 화면으로 이동할 수 있습니다"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"홈으로 이동"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"언제든지 화면을 아래에서 위로 스와이프하여 홈 화면으로 이동할 수 있습니다"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"창을 더 오래 누르고 있다가 손가락을 떼 보세요."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"위로 곧게 스와이프한 후 잠시 멈추세요."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"화면 하단에서 위로 스와이프하세요."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"아주 좋습니다"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"창을 더 오래 누르고 있다가 손가락을 떼 보세요."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"위로 곧게 스와이프한 후 잠시 멈추세요."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"동작 사용 방법을 알아봤습니다. 동작을 사용 중지하려면 설정으로 이동하세요."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"앱 전환 동작을 완료했습니다."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"앱 전환 동작을 완료했습니다."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"스와이프하여 앱 전환"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"앱 간에 전환하려면 화면 하단에서 위로 스와이프하고 잠시 멈춘 다음 손가락을 떼세요."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"앱 간에 전환하려면 두 손가락을 사용해 화면 하단에서 위로 스와이프하고 잠시 멈춘 다음 손가락을 떼세요"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"앱 전환"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"화면 하단에서 위로 스와이프하고 잠시 멈춘 다음 손가락을 떼세요."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"잘하셨습니다"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"설정 완료"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"완료"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"설정"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"스크린샷"</string>
<string name="action_split" msgid="2098009717623550676">"분할"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"다른 앱을 탭하여 화면 분할 사용"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"화면 분할 선택 종료"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"화면 분할을 사용하려면 다른 앱을 선택하세요."</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"이 작업은 앱 또는 조직에서 허용되지 않습니다."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"이동 방법 튜토리얼을 건너뛰시겠습니까?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"태스크 바 표시"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"태스크 바 숨김"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"탐색 메뉴"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"태스크 바 항상 표시"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"탐색 모드 변경"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"태스크 바 분할"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"상단/왼쪽으로 이동"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"하단/오른쪽으로 이동"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{앱 #개 더 표시}other{앱 #개 더 표시}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> 및 <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"데스크톱에 앱 추가하기"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"취소"</string>
</resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 4cb31fd..f5d8782 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Сунушталган колдонмолор функциясы иштетилди"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Сунушталган колдонмолор функциясы өчүрүлгөн"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Божомолдонгон колдонмо: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Экранды эң четинен оңдон солго же солдон оңго карай сүрүңүз."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Экранды оң же сол жагынан ортосуна карай сүрүп, манжаңызды алыңыз."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Түзмөгүңүздү буруңуз"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Жаңсап чабыттоо үйрөткүчүнүн аягына чыгуу үчүн түзмөктү буруңуз"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Экранды эң четинен оңдон солго же солдон оңго карай сүрүңүз"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Экранды оң же сол жагынан ортосуна карай сүрүп, манжаңызды алыңыз"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Артка кайтуу үчүн экранды оңдон солго карай сүрүүнү үйрөндүңүз. Эми колдонмолорду которуштурганды үйрөнүп алыңыз."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"\"Артка\" жаңсоосун үйрөндүңүз."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Манжаңызды экрандын ылдый жагына өтө жакындатпай сүрүңүз."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\"Артка\" жаң-нун сезгичтигин өзгөртүү үчүн жөндөөлөргө өтүңүз"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"\"Артка\" жаңсоосун үйрөндүңүз"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Манжаңызды экрандын ылдый жагына өтө жакындатпай сүрүңүз"</string>
+ <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\"Артка\" жаң-нун сезгичтигин өзгөртүү үчүн параметрлерге өтүңүз"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Артка кайтуу үчүн сүрүңүз"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Акыркы экранга кайтуу үчүн экранды сол же оң жагынан ортосуна карай сүрүңүз."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Акыркы экранга кайтуу үчүн экранды сол же оң жагынан ортосуна карай 2 манжаңыз менен сүрүңүз."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Артка кайтуу"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Экранды ылдыйдан өйдө сүрүңүз."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Манжаңызды алганга чейин токтотпоңуз."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Экранды өйдө сүрүңүз."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз. Эми артка кайтууну үйрөнүп алыңыз."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Экранды сол же оң жагынан ортосуна карай сүрүңүз"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Экранды ылдыйдан өйдө сүрүңүз"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Манжаңызды алганга чейин токтотпоңуз"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Экранды өйдө сүрүңүз"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз. Эми артка кайтууну үйрөнүп алыңыз."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Башкы бетке өтүү үчүн сүрүп коюңуз"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Экранды ылдый жагынан өйдө сүрүңүз. Бул жаңсоо сизди ар дайым Башкы экранга алып барат."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Экранды ылдый жагынан өйдө 2 манжаңыз менен сүрүңүз. Бул жаңсоо ар дайым Башкы экранга алып барат."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Башкы бетке өтүү"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Каалаган убакта башкы экранга өтүү үчүн экранды ылдыйдан жогору карай сүрүңүз"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Экранды ылдыйдан өйдө сүрүңүз."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Манжаңызды алуудан мурун экранда узагыраак кармаңыз."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Экранды өйдө карай сүрүп, токтоп туруңуз."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Жаңсоолорду колдонгонду үйрөндүңүз. Жаңсоолорду өчүрүү үчүн жөндөөлөргө өтүңүз."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"\"Колдонмолорду которуштуруу\" жаңсоосун үйрөндүңүз."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Колдонмолорду которуштуруу үчүн сүрүңүз"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Экранды төмөндөн жогору карай сүрүңүз"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Азаматсыз!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Экранды ылдыйдан өйдө сүрүңүз"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Манжаңызды алуудан мурун экранда узагыраак кармаңыз"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Экранды өйдө карай сүрүп, токтоп туруңуз"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Жаңсоолорду колдонгонду үйрөндүңүз. Жаңсоолорду өчүрүү үчүн параметрлерге өтүңүз."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"\"Колдонмолорду которуштуруу\" жаңсоосун үйрөндүңүз"</string>
+ <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Башка колдонмого которулуу үчүн сүрүңүз"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Бир колдонмодон экинчисине өтүү үчүн экранды ылдыйдан өйдө карай сүрүп, бир аз коё бербей туруңуз."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Бир колдонмодон экинчисине өтүү үчүн экранды 2 манжа менен ылдыйдан өйдө сүрүп, коё бербей туруңуз."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Колдонмолорду которуштуруу"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Башка колдонмого которулуу"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Экранды төмөндөн жогору карай сүрүңүз да, бир аз коё бербей кармап туруңуз"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Эң жакшы!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Дапдаяр!"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Бүттү"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Параметрлер"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="action_split" msgid="2098009717623550676">"Бөлүү"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Экранды бөлүү үчүн башка колдонмону таптап коюңуз"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Тандалган экранды бөлүүдөн чыгуу"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Экранды бөлүү үчүн башка колдонмону тандаңыз"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Бул аракетти аткарууга колдонмо же ишканаңыз тыюу салган"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Жаңсоолор үйрөткүчүн өткөрүп жибересизби?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Тапшырмалар панели көрсөтүлдү"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Тапшырмалар панели жашырылды"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Чабыттоо тилкеси"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Тапшырмалар панелин ар дайым көрсөтүү"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Өтүү режимин өзгөртүү"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Тапшырмалар панелин бөлгүч"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Жогорку/сол бурчка жылдыруу"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Төмөнкү/оң бурчка жылдыруу"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Дагы # колдонмону көрсөтүү.}other{Дагы # колдонмону көрсөтүү.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> жана <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Колдонмону иш тактага кошуу"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Жокко чыгаруу"</string>
</resources>
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index ee594c8..2b17b93 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -84,4 +84,5 @@
<dimen name="keyboard_quick_switch_taskview_width">205dp</dimen>
<dimen name="keyboard_quick_switch_taskview_height">119dp</dimen>
+
</resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index be5d894..2f67c30 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ເປີດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ປິດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ແອັບທີ່ຄາດເດົາໄວ້: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາສຸດ ຫຼື ຊ້າຍສຸດ."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາ ຫຼື ຊ້າຍໄປຫາທາງກາງຂອງໜ້າຈໍແລ້ວປ່ອຍນິ້ວ."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ໝຸນອຸປະກອນຂອງທ່ານ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ກະລຸນາໝຸນອຸປະກອນຂອງທ່ານເພື່ອເຮັດຕາມການສອນການນຳໃຊ້ກ່ຽວກັບການນຳທາງແບບທ່າທາງໃຫ້ສຳເລັດ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາສຸດ ຫຼື ຊ້າຍສຸດ"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາ ຫຼື ຊ້າຍໄປຫາທາງກາງຂອງໜ້າຈໍແລ້ວປ່ອຍນິ້ວ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ທ່ານຮຽນຮູ້ວິທີປັດຈາກຂວາເພື່ອກັບຄືນແລ້ວ. ຕໍ່ໄປ, ມາສຶກສາວິທີສະຫຼັບແອັບ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ທ່ານໃຊ້ທ່າທາງກັບຄືນສຳເລັດແລ້ວ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ໄດ້ປັດໃກ້ກັບທາງລຸ່ມຂອງໜ້າຈໍເກີນໄປ."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ທ່ານໃຊ້ທ່າທາງກັບຄືນສຳເລັດແລ້ວ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ໄດ້ປັດໃກ້ກັບທາງລຸ່ມຂອງໜ້າຈໍເກີນໄປ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ເພື່ອປ່ຽນຄວາມລະອຽດອ່ອນຂອງທ່າທາງກັບຄືນ, ໃຫ້ໄປຫາການຕັ້ງຄ່າ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ປັດເພື່ອກັບຄືນ"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ເພື່ອກັບໄປໜ້າຈໍຫຼ້າສຸດ, ໃຫ້ປັດຈາກຂອບຊ້າຍ ຫຼື ຂວາໄປຫາທາງກາງຂອງໜ້າຈໍ."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ເພື່ອກັບໄປໜ້າຈໍຫຼ້າສຸດ, ໃຫ້ປັດດ້ວຍ 2 ນິ້ວຈາກຂອບຊ້າຍ ຫຼື ຂວາໄປຫາທາງກາງຂອງໜ້າຈໍ."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ກັບຄືນ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ຢຸດຊົ່ວຄາວກ່ອນປ່ອຍນິ້ວ."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນໄປຊື່ໆ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ. ຕໍ່ໄປ, ມາສຶກສາວິທີກັບຄືນ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ປັດຈາກຂອບຊ້າຍ ຫຼື ຂວາໄປຫາກາງໜ້າຈໍ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ຢຸດຊົ່ວຄາວກ່ອນປ່ອຍນິ້ວ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນໄປຊື່ໆ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ. ຕໍ່ໄປ, ມາສຶກສາວິທີກັບຄືນ."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ປັດເພື່ອໄປໜ້າຫຼັກ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ປັດຂຶ້ນມາຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ. ທ່າທາງນີ້ຈະພາທ່ານໄປໂຮມສະກຣີນສະເໝີ."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ປັດຂຶ້ນດ້ວຍ 2 ນິ້ວຈາກລຸ່ມສຸດຂອງໜ້າຈໍ. ທ່າທາງນີ້ຈະພາທ່ານໄປໂຮມສະກຣີນສະເໝີ."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ໄປໜ້າຫຼັກ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານເພື່ອກັບໄປໂຮມສະກຣີນຂອງທ່ານໄດ້ທຸກເວລາ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ລອງກົດໃສ່ໜ້າຈໍຄ້າງໄວ້ດົນຂຶ້ນກ່ອນປ່ອຍນິ້ວ."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຊື່ໆ, ຈາກນັ້ນຢຸດຊົ່ວຄາວ."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ດີຫຼາຍ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ລອງກົດໃສ່ໜ້າຈໍຄ້າງໄວ້ດົນຂຶ້ນກ່ອນປ່ອຍນິ້ວ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຊື່ໆ, ຈາກນັ້ນຢຸດຊົ່ວຄາວ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ທ່ານໄດ້ສຶກສາວິທີໃຊ້ທ່າທາງແລ້ວ. ເພື່ອປິດທ່າທາງຕ່າງໆ, ໃຫ້ເຂົ້າໄປຫາການຕັ້ງຄ່າ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ທ່ານໃຊ້ທ່າທາງສະຫຼັບແອັບສຳເລັດແລ້ວ."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ທ່ານໃຊ້ທ່າທາງສະຫຼັບແອັບສຳເລັດແລ້ວ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ປັດເພື່ອສະຫຼັບແອັບ"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ເພື່ອສະຫຼັບລະຫວ່າງແອັບ, ໃຫ້ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ, ກົດຄ້າງໄວ້, ຈາກນັ້ນປ່ອຍ."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ເພື່ອສະຫຼັບລະຫວ່າງແອັບ, ໃຫ້ປັດຂຶ້ນດ້ວຍ 2 ນິ້ວຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ, ກົດຄ້າງໄວ້ແລ້ວປ່ອຍ."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ສະຫຼັບແອັບ"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານຄ້າງໄວ້ແລ້ວປ່ອຍ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ດີຫຼາຍ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ທຸກຢ່າງພ້ອມແລ້ວ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ແລ້ວໆ"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ການຕັ້ງຄ່າ"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ຮູບໜ້າຈໍ"</string>
<string name="action_split" msgid="2098009717623550676">"ແບ່ງ"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"ແຕະແອັບອື່ນເພື່ອໃຊ້ໜ້າຈໍແຍກ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ອອກຈາກາກນເລືອກການແບ່ງໜ້າຈໍ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"ເລືອກແອັບອື່ນເພື່ອໃຊ້ການແບ່ງໜ້າຈໍ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ແອັບ ຫຼື ອົງການຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ໃຊ້ຄຳສັ່ງນີ້"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ຂ້າມການສອນການນຳໃຊ້ການນຳທາງບໍ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ແຖບໜ້າວຽກທີ່ສະແດງຢູ່"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ແຖບໜ້າວຽກທີ່ເຊື່ອງໄວ້ຢູ່"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ແຖບການນຳທາງ"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ສະແດງແຖບໜ້າວຽກສະເໝີ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ປ່ຽນໂໝດການນຳທາງ"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ເສັ້ນແບ່ງແຖບໜ້າວຽກ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ຍ້າຍໄປຊ້າຍ/ເທິງ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ຍ້າຍໄປຂວາ/ລຸ່ມ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{ສະແດງອີກ # ແອັບ.}other{ສະແດງອີກ # ແອັບ.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ແລະ <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ການເພີ່ມແອັບໄປໃສ່ເດັສທັອບ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ຍົກເລີກ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 06c4f79..8bb1252 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Siūlomų programų funkcija įgalinta"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Siūlomų programų funkcija išjungta"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Numatoma programa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Turite perbraukti nuo dešiniojo ar kairiojo krašto."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Turite perbraukti nuo dešiniojo ar kairiojo krašto link ekrano vidurio ir pakelti pirštą."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pasukite įrenginį"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Pasukite įrenginį, kad pereitumėte į naršymo gestais mokomąją medžiagą"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Turite perbraukti nuo dešiniojo ar kairiojo krašto"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Turite perbraukti nuo dešiniojo ar kairiojo krašto link ekrano vidurio ir pakelti pirštą"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Išmokote, kaip sugrįžti perbraukiant iš dešinės. Toliau sužinosite, kaip perjungti programas."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Atlikote grįžimo atgal gestą."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nebraukite per arti ekrano apačios."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Atlikote grįžimo atgal gestą"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Nebraukite per arti ekrano apačios"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Norėd. pak. grįžimo gesto jautr., eikite į sk. „Nustatymai“"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Norėdami grįžti, perbraukite"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Norėdami grįžti į ankstesnį ekraną, perbr. nuo kairiojo arba dešinio krašto link ekrano vidurio."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Jei norite grįžti į ankstesnį ekraną, perbraukite dviem pirštais nuo kairiojo arba dešiniojo krašto link ekrano vidurio."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Grįžti"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Turite perbraukti aukštyn nuo apatinio ekrano krašto."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nepristabdykite prieš pakeldami pirštą."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Turite tiesiai perbraukti aukštyn."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Atlikote perėjimo į pagrindinį ekraną gestą. Toliau sužinosite, kaip grįžti atgal."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Atlikote perėjimo į pagrindinį ekraną gestą."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Perbraukite nuo kairiojo arba dešiniojo krašto link ekrano vidurio"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Turite perbraukti aukštyn nuo apatinio ekrano krašto"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Nepristabdykite prieš pakeldami pirštą"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Turite tiesiai perbraukti aukštyn"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Atlikote perėjimo į pagrindinį ekraną gestą. Toliau sužinosite, kaip grįžti atgal."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Atlikote perėjimo į pagrindinį ekraną gestą"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Perbraukite, kad pereitumėte į pagrindinį ekraną"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Perbraukite aukštyn nuo ekrano apačios. Atlikus šį gestą, visada nukreipiama į pagrindinį ekraną."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Perbraukite dviem pirštais nuo ekrano apačios. Šis gestas visada nukreipia į pagrindinį ekraną."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Eikite į pagrindinį ekraną"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Jei norite bet kada pasiekti pagrindinį ekraną, perbraukite aukštyn iš ekrano apačios"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Turite perbraukti aukštyn nuo apatinio ekrano krašto."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pabandykite palaikyti langą ilgiau prieš pakeldami pirštą."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Turite tiesiai perbraukti aukštyn, o tada pristabdyti."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"išmokote naudotis gestais. Gestus galite išjungti nustatymuose."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Atlikote programų perjungimo gestą."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Eiti į pagrindinį ekraną"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Perbraukite aukštyn nuo ekrano apačios"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Puiku!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Turite perbraukti aukštyn nuo apatinio ekrano krašto"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Pabandykite palaikyti langą ilgiau prieš pakeldami pirštą"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Turite tiesiai perbraukti aukštyn, o tada pristabdyti"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Išmokote naudotis gestais. Gestus galite išjungti nustatymuose."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Atlikote programų perjungimo gestą"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Perbraukite, kad perjungtumėte programas"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Norėdami perjungti programas, perbraukite aukštyn nuo ekrano apačios, palaikykite ir paleiskite."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Perjunkite programas perbraukę dviem pirštais aukštyn nuo ekrano apačios, palaikę ir paleidę."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Perjungti programas"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Perbraukite aukštyn nuo ekrano apačios, palaikykite ir paleiskite"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Puiku!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Viskas nustatyta"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Atlikta"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nustatymai"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Ekrano kopija"</string>
<string name="action_split" msgid="2098009717623550676">"Išskaidymo režimas"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Išskaidyto ekrano režimas palietus kitą programą"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Išeiti iš išskaidyto ekrano pasirinkimo"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Išskaidyto ekrano režimą naudokite kita programa"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Jūsų organizacijoje arba naudojant šią programą neleidžiama atlikti šio veiksmo"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Praleisti naršymo mokymo programą?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Užduočių juosta rodoma"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Užduočių juosta paslėpta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Naršymo juosta"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Visada rodyti užduočių juostą"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Keisti naršymo režimą"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Užduočių juostos daliklis"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Perkelti aukštyn, kairėn"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Perkelti žemyn, dešinėn"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Rodyti dar # programą.}one{Rodyti dar # programą.}few{Rodyti dar # programas.}many{Rodyti dar # programos.}other{Rodyti dar # programų.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"„<xliff:g id="APP_NAME_1">%1$s</xliff:g>“ ir „<xliff:g id="APP_NAME_2">%2$s</xliff:g>“"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Pridedama programa prie darbalaukio"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Atšaukti"</string>
</resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 9ab8259..a8bff55 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ieteicamās lietotnes ir iespējotas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Ieteicamās lietotnes ir atspējotas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Prognozētā lietotne: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Velciet no pašas labās vai kreisās malas."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Velciet no ekrāna labās vai kreisās malas uz vidu un atlaidiet."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Pagrieziet ierīci"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Lūdzu, pagrieziet savu ierīci, lai pabeigtu žestu navigācijas apmācību."</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Jāvelk no pašas labās vai kreisās malas."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Jāvelk no ekrāna labās vai kreisās malas uz vidu un jāatlaiž."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Jūs esat apguvis, kā vilkt no labās malas, lai pārietu atpakaļ. Tagad mācieties pārslēgt lietotnes."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Jūs sekmīgi veicāt atgriešanās žestu."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nevelciet pārāk tuvu ekrāna apakšdaļai."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Jūs sekmīgi veicāt atgriešanās žestu."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Nevelciet pārāk tuvu ekrāna apakšdaļai."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Atgriešanās žesta jutīguma līmeni varat mainīt iestatījumos."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Vilkšana, lai atgrieztos"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Lai atgrieztos iepriekšējā ekrānā, velciet no kreisās vai labās malas uz ekrāna vidu."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Lai pārietu uz iepriekšējo ekrānu, ar diviem pirkstiem velciet no kreisās vai labās malas uz ekrāna vidu."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Atpakaļ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Jāvelk augšup no ekrāna apakšmalas."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pirms atlaišanas nepārtrauciet kustību."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Jāvelk tieši uz augšu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu. Tagad varat iemācīties, kā pāriet atpakaļ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Velciet no ekrāna kreisās vai labās malas uz vidu."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Jāvelk augšup no ekrāna apakšmalas."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pirms atlaišanas nepārtrauciet kustību."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Jāvelk tieši uz augšu."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu. Tagad varat iemācīties, kā pāriet atpakaļ."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Vilkšana, lai pārietu uz sākumu"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Velciet augšup no ekrāna apakšdaļas. Ar šo žestu vienmēr varat atvērt sākuma ekrānu."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Ar 2 pirkstiem velciet augšup no ekrāna apakšdaļas. Ar šo žestu vienmēr varat atvērt sākuma ekrānu."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Došanās uz sākuma ekrānu"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Jebkurā laikā varat doties uz sākuma ekrānu, no ekrāna apakšdaļas velkot augšup."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Jāvelk augšup no ekrāna apakšmalas."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Mēģiniet ilgāk turēt logu, pirms atlaižat."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Jāvelk tieši uz augšu un pēc tam jāaptur kustība."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Velciet augšup no ekrāna apakšdaļas."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Lieliski!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Jāvelk augšup no ekrāna apakšmalas."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Mēģiniet ilgāk turēt logu, pirms atlaižat."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Jāvelk tieši uz augšu un pēc tam jāaptur kustība."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jūs esat apguvis žestu izmantošanu. Lai izslēgtu žestus, pārejiet uz sadaļu Iestatījumi."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Jūs sekmīgi veicāt lietotņu pārslēgšanas žestu."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Jūs sekmīgi veicāt lietotņu pārslēgšanas žestu."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vilkšana, lai pārslēgtu lietotnes"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Lai pārslēgtu lietotnes, velciet augšup no ekrāna apakšdaļas, turiet un pēc tam atlaidiet."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Lai pārslēgtu lietotnes, ar 2 pirkstiem velciet no ekrāna apakšdaļas, turiet un pēc tam atlaidiet."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Lietotņu pārslēgšana"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Velciet augšup no ekrāna apakšdaļas, turiet un pēc tam atlaidiet."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Ļoti labi!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gatavs"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gatavs"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Iestatījumi"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Veikt ekrānuzņēmumu"</string>
<string name="action_split" msgid="2098009717623550676">"Sadalīt"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Lai sadalītu ekrānu, pieskarieties citai lietotnei"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Izejiet no ekrāna sadalīšanas režīma atlases."</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Izvēlieties citu lietotni, lai sadalītu ekrānu"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Lietotne vai jūsu organizācija neatļauj veikt šo darbību."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vai izlaist navigācijas mācības?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Uzdevumu josla tiek rādīta"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Uzdevumu josla paslēpta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigācijas josla"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Vienmēr rādīt uzdevumu joslu"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Mainīt navigācijas režīmu"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Uzdevumu joslas atdalītājs"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Pārvietot uz augšējo/kreiso stūri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pārvietot uz apakšējo/labo stūri"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Rādīt vēl # lietotni}zero{Rādīt vēl # lietotnes}one{Rādīt vēl # lietotni}other{Rādīt vēl # lietotnes}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"“<xliff:g id="APP_NAME_1">%1$s</xliff:g>” un “<xliff:g id="APP_NAME_2">%2$s</xliff:g>”"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Notiek lietotnes pievienošana datoram"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Atcelt"</string>
</resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index bd6b12a..258a544 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -44,43 +44,49 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлозите за апликации се овозможени"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлозите за апликации се оневозможени"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидена апликација: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Повлечете од крајниот десен или крајниот лев раб."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Повлечете од десниот или левиот раб кон средината на екранот и пуштете."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ротирајте го уредот"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ротирајте го уредот за да го завршите упатството за навигација со движење"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Повлечете од крајниот десен или крајниот лев раб"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Повлечете од десниот или левиот раб кон средината на екранот и пуштете"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научивте како да повлекувате оддесно за враќање назад. Научете и како да се префрлате помеѓу апликациите."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Завршивте со упатството за враќање назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не повлекувајте преблиску до долниот раб на екранот."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Завршивте со упатството за враќање назад"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Не повлекувајте преблиску до дното на екранот"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"За да ја промените чувствителноста, одете во „Поставки“"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Повлечете за да се вратите назад"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"За да се вратите на последниот екран, повлечете од левиот или десниот раб кон средината на екранот."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"За да се вратите на последниот екран на кој бевте, повлечете со два прста од левиот или десниот раб кон средината на екранот."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Назад"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Повлечете нагоре од долниот раб на екранот."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не правете пауза пред да пуштите."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Повлечете право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Го научивте движењето за отворање на почетниот екран. Научете го и движењето за враќање назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Го научивте движењето за отворање на почетниот екран."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Враќање назад"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Повлечете од левиот или десниот раб кон средината на екранот"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Повлечете нагоре од долниот раб на екранот"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Не правете пауза пред да пуштите"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Повлечете право нагоре"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Го научивте движењето за отворање на почетниот екран. Научете го и движењето за враќање назад."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Го научивте движењето за враќање на почетниот екран"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Повлечете за да одите на почетниот екран"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Повлечете нагоре од долниот раб на екранот. Ова движење секогаш ќе ве одведе на почетниот екран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Повлечете нагоре со два прста од долниот раб на екранот. Движењево секогаш ве носи на почетниот екран."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Одете на почетниот екран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"За да одите на вашиот почетен екран во кое било време, повлечете нагоре од дното на екранот"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Повлечете нагоре од долниот раб на екранот."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Задржете го прозорецот подолго пред да го пуштите."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Повлечете право нагоре, а потоа застанете."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Отворање на почетниот екран"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Повлечете нагоре од дното на екранот"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Одлично сторено!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Повлечете нагоре од долниот раб на екранот"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Задржете го прозорецот подолго пред да го пуштите"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Повлечете право нагоре, а потоа застанете"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Научивте како се користат движењата. За да ги исклучите движењата, одете во „Поставки“."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Завршивте со упатството за префрлање помеѓу апликации."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Го научивте движењето за префрлање помеѓу апликации"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Повлечете за префрлање помеѓу апликации"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За да смените апликација, повлечете нагоре од дното на екранот и задржете, па пуштете."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"За да се префрлате помеѓу апликации, повлечете нагоре со два прста од долниот раб на екранот, задржете и потоа отпуштете."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Променете ја апликацијата"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Повлечете нагоре од дното на екранот и задржете, па пуштете"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Браво!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Поставки"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Обиди се пак"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Обидете се повторно"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Одлично!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Упатство <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="459504134589971527">"Повлечете нагоре за да појдете на почетен екран"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Повлечете нагоре за да го отворите почетниот екран"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Допрете го копчето за почетен екран за да одите на почетниот екран"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Подготвени сте да почнете да го користите вашиот <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"уред"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Слика од екранот"</string>
<string name="action_split" msgid="2098009717623550676">"Раздели"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Допрете друга аплик. за да користите поделен екран"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Излези од изборот на поделен екран"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Изберете друга апликација за да користите поделен екран"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Апликацијата или вашата организација не го дозволува дејствово"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Да се прескокне упатството за навигација?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Ротирајте го екранот"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Обука за лентата со задачи"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Повлечете апликација настрана за да користите 2 апликации"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Полека повлечете нагоре за да се прикаже „Лентата со задачи“"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Полека повлечете нагоре за да се прикаже лентата со задачи"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Добивајте предлози за апликации според вашата рутина"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Вклучете навигација со движење во „Поставки“ за автоматско сокривање на „Лентата со задачи“"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Правете повеќе со една лента со задачи"</string>
@@ -113,10 +120,15 @@
<string name="taskbar_button_quick_settings" msgid="227662894293189391">"Брзи поставки"</string>
<string name="taskbar_a11y_title" msgid="6432169809852243110">"Лента со задачи"</string>
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Лентата со задачи е прикажана"</string>
- <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Лентата со задачи е сокриена"</string>
+ <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Лентата со задачи е скриена"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Лента за навигација"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Секогаш прикажувај „Лента“"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Променете режим на навигација"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Разделник на „Лента со задачи“"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Премести горе лево"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Премести долу десно"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Прикажи уште # апликација.}one{Прикажи уште # апликација.}other{Прикажи уште # апликации.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> и <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Додавање на апликацијата во „Работна површина“"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Откажи"</string>
</resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 74fdd75..fffcd54 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"പ്രവചിച്ച ആപ്പ്: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"വലത്തേയറ്റത്തെയോ ഇടത്തേയറ്റത്തെയോ അരികിൽ നിന്ന് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"വലതോ ഇടതോ അരികിൽ നിന്ന് സ്ക്രീനിന്റെ മധ്യഭാഗത്തേക്ക് സ്വെെപ്പ് ചെയ്ത് വിടുക."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"നിങ്ങളുടെ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ജെസ്ച്ചർ നാവിഗേഷൻ ട്യൂട്ടോറിയൽ പൂർത്തിയാക്കാൻ നിങ്ങളുടെ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"വലത്തേയറ്റത്തെയോ ഇടത്തേയറ്റത്തെയോ അരികിൽ നിന്നാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"വലതോ ഇടതോ അരികിൽ നിന്ന് സ്ക്രീനിന്റെ മധ്യഭാഗത്തേക്കാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"മടങ്ങാൻ വലതുഭാഗത്ത് നിന്ന് സ്വൈപ്പ് ചെയ്യുന്ന രീതി മനസ്സിലായി. ഇനി, ആപ്പുകൾ മാറുന്ന രീതി അറിയുക."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"മടങ്ങുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"സ്ക്രീനിന്റെ ഏറ്റവും അടിഭാഗത്തേക്ക് സ്വെെപ്പ് ചെയ്യുന്നില്ലെന്ന് ഉറപ്പാക്കുക."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"മടങ്ങുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"സ്ക്രീനിന്റെ ഏറ്റവും അടിഭാഗത്തേക്ക് സ്വെെപ്പ് ചെയ്യുന്നില്ലെന്ന് ഉറപ്പാക്കുക"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ബാക്ക്ജെസ്റ്ററിന്റെ സെൻസിറ്റിവിറ്റി മാറ്റാൻ ക്രമീകരണത്തിൽ പോകൂ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"മടങ്ങാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"മുൻ സ്ക്രീനിലേക്ക് മടങ്ങാൻ, ഇടതോ വലതോ അരികിൽ നിന്ന് സ്ക്രീനിന്റെ നടുവിലേക്ക് സ്വെെപ്പ് ചെയ്യുക."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"മുമ്പത്തെ സ്ക്രീനിലേക്ക് മടങ്ങാൻ, 2 വിരലുകൾ ഉപയോഗിച്ച് ഇടത് അല്ലെങ്കിൽ വലത് മൂലയിൽ നിന്ന് സ്ക്രീനിന്റെ മധ്യഭാഗത്തേക്ക് സ്വൈപ്പ് ചെയ്യുക."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"മടങ്ങുക"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"സ്ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"വിടുന്നതിന് മുമ്പ് നിങ്ങൾ താൽക്കാലികമായി നിർത്തുന്നില്ലെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"നേരെ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ഹോമിലേക്ക് പോകുക ജെസ്ച്ചർ പൂർത്തിയാക്കി. അടുത്തത്, എങ്ങനെ മടങ്ങാമെന്ന് അറിയുക."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ഹോമിലേക്ക് പോകുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ഇടതോ വലതോ അരികിൽ നിന്ന് സ്ക്രീനിന്റെ മധ്യഭാഗത്തേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"സ്ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്കാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"വിടുന്നതിന് മുമ്പ് നിങ്ങൾ താൽക്കാലികമായി നിർത്തുന്നില്ലെന്ന് ഉറപ്പാക്കുക"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"നേരെ മുകളിലേക്കാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ഹോം ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി. അടുത്തത്, തിരികെ എങ്ങനെ പോകാമെന്ന് മനസ്സിലാക്കുക."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ഹോം ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ഹോമിലേക്ക് പോകാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യൂ. ഈ ജെസ്ച്ചർ എപ്പോഴും ഹോം സ്ക്രീനിലേക്ക് നയിക്കുന്നു."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് 2 വിരലുകൾ കൊണ്ട് സ്വൈപ്പ് ചെയ്യൂ. ഈ ജെസ്ച്ചർ എല്ലായ്പ്പോഴും ഹോം സ്ക്രീനിലേക്ക് നയിക്കുന്നു."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ഹോമിലേക്ക് പോകൂ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ഏതുസമയത്തും ഹോം സ്ക്രീനിലേക്ക് പോകാൻ, സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യൂ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"സ്ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"റിലീസ് ചെയ്യുന്നതിന് മുമ്പ് വിൻഡോ കൂടുതൽ സമയം ഹോൾഡ് ചെയ്യാൻ ശ്രമിക്കുക."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"നേരെ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്ത് അൽപ്പസമയം പിടിച്ചുനിർത്തുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"കൊള്ളാം!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"സ്ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്കാണ് സ്വെെപ്പ് ചെയ്യുന്നതെന്ന് ഉറപ്പാക്കുക"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"റിലീസ് ചെയ്യുന്നതിന് മുമ്പ് വിൻഡോ കൂടുതൽ സമയം ഹോൾഡ് ചെയ്യാൻ ശ്രമിക്കുക"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"നേരെ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്ത് അൽപ്പസമയം പിടിച്ചുനിർത്തുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ജെസ്ച്ചറുകൾ ഉപയോഗിക്കുന്ന രീതി നിങ്ങൾ മനസ്സിലാക്കി. ജെസ്ച്ചറുകൾ ഓഫാക്കാൻ ക്രമീകരണത്തിലേക്ക് പോകുക."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ആപ്പുകൾ തമ്മിൽ മാറുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ആപ്പുകൾ തമ്മിൽ മാറുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ആപ്പുകൾ മാറാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ആപ്പുകൾക്കിടയിൽ മാറാൻ സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്ത് പിടിച്ച ശേഷം വിടുക."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ആപ്പുകൾക്കിടയിൽ മാറാൻ സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് 2 വിരലുകൾ കൊണ്ട് സ്വൈപ്പ് ചെയ്ത് പിടിച്ച ശേഷം വിടുക."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ആപ്പുകൾ മാറുക"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്ത് പിടിച്ച ശേഷം, വിടുക"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"അഭിനന്ദനങ്ങൾ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"എല്ലാം സജ്ജീകരിച്ചു"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"പൂർത്തിയായി"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ക്രമീകരണം"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"പങ്കിടുക"</string>
<string name="action_screenshot" msgid="8171125848358142917">"സ്ക്രീൻഷോട്ട്"</string>
<string name="action_split" msgid="2098009717623550676">"വിഭജിക്കുക"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"സ്പ്ലിറ്റ് സ്ക്രീനിനായി മറ്റൊരു ആപ്പ് ടാപ്പുചെയ്യൂ"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"സ്പ്ലിറ്റ് സ്ക്രീനിന് മറ്റൊരു ആപ്പിൽ ടാപ്പ് ചെയ്യൂ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"സ്ക്രീൻ വിഭജന തിരഞ്ഞെടുപ്പിൽ നിന്ന് പുറത്തുകടക്കുക"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"സ്ക്രീൻ വിഭജന മോഡിന് മറ്റൊരു ആപ്പ് തിരഞ്ഞെടുക്കൂ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ഈ നടപടി എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"നാവിഗേഷൻ ട്യൂട്ടോറിയൽ ഒഴിവാക്കണോ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ടാസ്ക്ബാർ കാണിച്ചിരിക്കുന്നു"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ടാസ്ക്ബാർ മറച്ചിരിക്കുന്നു"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"നാവിഗേഷൻ ബാർ"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ടാസ്ക്ബാർ എപ്പോഴും കാണിക്കൂ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"നാവിഗേഷൻ മോഡ് മാറ്റുക"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ടാസ്ക്ബാർ ഡിവൈഡർ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"താഴേക്കോ വലത്തേക്കോ നീക്കുക"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# ആപ്പ് കൂടി കാണിക്കുക.}other{# ആപ്പുകൾ കൂടി കാണിക്കുക.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g>, <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ആപ്പ് ഡെസ്ക്ടോപ്പിലേക്ക് ചേർക്കുന്നു"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"റദ്ദാക്കുക"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 7c6314e..8c7ae78 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -23,7 +23,7 @@
<string name="recent_task_option_freeform" msgid="48863056265284071">"Чөлөөтэй хувьсах"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Сүүлийн үеийн зүйл алга"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Апп ашиглалтын тохиргоо"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг устгах"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг арилгах"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Саяхны аппууд"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Ажлыг хаасан"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Санал болгож буй аппуудыг идэвхжүүлсэн"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Санал болгож буй аппуудыг идэвхгүй болгосон"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Таамаглаж буй апп: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Та баруун зах эсвэл зүүн захын булангаас шударна уу."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Та баруун эсвэл зүүн булангаас дэлгэцийн дунд хэсэг хүртэл шударч, суллана уу."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Төхөөрөмжөө эргүүлэх"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Зангааны навигацын практик хичээлийг дуусгахын тулд төхөөрөмжөө эргүүлнэ үү"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Та баруун зах эсвэл зүүн захын ирмэгээс шударна уу"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Та баруун эсвэл зүүн ирмэгээс дэлгэцийн дунд хэсэг хүртэл шударч, суллана уу"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Та буцахын тулд баруунаас хэрхэн шудрахыг мэдэж авлаа. Дараа нь аппууд хооронд хэрхэн сэлгэхийг мэдэж аваарай."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Та буцах зангааг гүйцэтгэлээ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Та дэлгэцийн доод хэсэгтэй хэт ойр бүү шудраарай."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Та буцах зангааг гүйцэтгэлээ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Та дэлгэцийн доод хэсэгтэй хэт ойр бүү шудраарай"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Буцах зангааны мэдрэгшлийг өөрчлөх бол Тохиргоо руу очно уу"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Буцахын тулд шудрах"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Сүүлийн дэлгэц рүү буцахын тулд дэлгэцийн зүүн эсвэл баруун булангаас дунд хэсэг рүү шударна уу."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Сүүлийн дэлгэц рүү буцахын тулд 2 хуруугаараа дэлгэцийн голоос зүүн эсвэл баруун ирмэг рүү шударна уу."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Буцах"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Та дэлгэцийн доод булангаас дээш шударна уу."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Та суллахаасаа өмнө түр зогсоож болохгүй."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Та чигээрээ шударна уу."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Та Нүүр лүү очих зангааг гүйцэтгэлээ. Дараа нь хэрхэн буцахыг мэдэж авна уу."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Та Нүүр лүү очих зангааг гүйцэтгэлээ."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Зүүн эсвэл баруун ирмэгээс дэлгэцийн дунд хэсэг хүртэл шударна уу"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Та дэлгэцийн доод ирмэгээс дээш шударна уу"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Та суллахаасаа өмнө түр зогсоож болохгүй"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Та дээш чигээрээ шударна уу"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Та үндсэн нүүр лүү очих зангааг гүйцэтгэлээ. Дараа нь хэрхэн буцахыг мэдэж авна уу."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Та үндсэн нүүр лүү очих зангааг гүйцэтгэлээ."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Нүүр лүү очихын тулд шудрах"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Дэлгэцийнхээ доороос дээш шударна уу. Энэ зангаа таныг тогтмол Үндсэн нүүрэнд аваачна."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 хуруугаараа дэлгэцийн доороос дээш шударна уу. Энэ зангаа таныг тогтмол Үндсэн нүүрэнд аваачна."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Үндсэн нүүр лүү очих"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Үндсэн нүүр лүүгээ хүссэн үедээ очихын тулд дэлгэцийн доороос дээш шударна уу"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Та дэлгэцийн доод булангаас дээш шударна уу."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Суллахаасаа өмнө цонхыг илүү удаан дарж үзнэ үү."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Та чигээрээ шударч, дараа нь түр зогсооно уу."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Дэлгэцийнхээ доороос дээш шударна уу"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Үнэхээр сайн ажиллалаа!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Та дэлгэцийн доод ирмэгээс дээш шударна уу"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Суллахаасаа өмнө цонхыг илүү удаан дарж үзнэ үү"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Та дээш чигээрээ шударч, дараа нь түр зогсооно уу"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Та зангааг хэрхэн ашиглахыг мэдэж авлаа. Зангааг унтраахын тулд Тохиргоо руу очно уу."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Та аппуудыг сэлгэх зангааг гүйцэтгэлээ."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Та аппуудыг сэлгэх зангааг гүйцэтгэлээ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Аппуудыг сэлгэхийн тулд шудрах"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Аппуудын хооронд сэлгэхийн тулд дэлгэцийнхээ доод хэсгээс дээш шударч, удаан дараад, суллана уу."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Аппуудын хооронд сэлгэхийн тулд 2 хуруугаараа дэлгэцийнхээ доод хэсгээс дээш шударч, удаан дараад, суллана уу."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Аппуудыг сэлгэх"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Дэлгэцийнхээ доод хэсгээс дээш шударч, удаан дараад суллана уу"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Сайн байна!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Бүгдийг тохируулсан"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Дууссан"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Тохиргоо"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Дэлгэцийн агшин дарах"</string>
<string name="action_split" msgid="2098009717623550676">"Хуваах"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Дэлгэцийг хуваахыг ашиглахын тулд өөр аппыг товш"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Дэлгэцийг хуваах сонголтоос гарах"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Дэлгэцийг хуваах горим ашиглах өөр апп сонгоно уу"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Энэ үйлдлийг апп эсвэл танай байгууллага зөвшөөрдөггүй"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Навигацын практик хичээлийг алгасах уу?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Ажлын хэсгийг харуулсан"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Ажлын хэсгийг нуусан"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Навигацын самбар"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Ажлын хэсгийг үргэлж харуулах"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Навигацын горимыг өөрчлөх"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Ажлын хэсгийг хуваагч"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Зүүн дээд хэсэг рүү зөөх"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Баруун доод хэсэг рүү зөөх"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Өөр # аппыг харуулна уу.}other{Өөр # аппыг харуулна уу.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> болон <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Компьютерт апп нэмж байна"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Цуцлах"</string>
</resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index cfaf2d8..5bf47ce 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"अॅप सूचना सुरू केल्या आहेत"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"अॅप सूचना बंद केल्या आहेत"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान केलेले अॅप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"तुम्ही स्क्रीनच्या अगदी उजव्या किंवा अगदी डाव्या कडेला स्वाइप केल्याची खात्री करा."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"तुम्ही स्क्रीनच्या उजव्या किंवा डाव्या कडेपासून मध्यभागी स्वाइप करून सोडून दिल्याची खात्री करा."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"तुमचे डिव्हाइस फिरवा"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"कृपया जेश्चर नेव्हिगेशन ट्यूटोरियल पूर्ण करण्यासाठी तुमचे डिव्हाइस फिरवा"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"तुम्ही स्क्रीनच्या अगदी उजव्या किंवा अगदी डाव्या कडेपासून स्वाइप करत आहात खात्री करा"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"तुम्ही स्क्रीनच्या उजव्या किंवा डाव्या कडेपासून मध्यभागी स्वाइप करून सोडून देत आहात याची खात्री करा"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"मागे जाण्यासाठी उजवीकडून कसे स्वाइप करावे ते शिकलात. आता पुढे, ॲप्स कशी स्विच करायची ते जाणून घ्या."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"तुम्ही गो बॅक जेश्चर पूर्ण केले."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"तुम्ही स्क्रीनच्या तळाच्या अगदी जवळून स्वाइप करत नाही याची खात्री करा."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"तुम्ही गो बॅक जेश्चर पूर्ण केले आहे"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"तुम्ही स्क्रीनच्या तळाच्या अगदी जवळून स्वाइप करत नाही याची खात्री करा"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"बॅक जेश्चरची संवेदनशीलता बदलण्यासाठी, सेटिंग्ज वर जा"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"परत जाण्यासाठी स्वाइप करा"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"मागील स्क्रीनवर परत जाण्यासाठी, स्क्रीनच्या डाव्या किंवा उजव्या कडेपासून मध्यावर स्वाइप करा."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"मागील स्क्रीनवर परत जाण्यासाठी, दोन बोटांनी डाव्या किंवा उजव्या कडेपासून स्क्रीनच्या मध्यभागी स्वाइप करा."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"मागे जा"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"तुम्ही स्क्रीनवरून बोट उचलण्यापूर्वी ते थांबवत नाही याची खात्री करा."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"तुम्ही सरळ वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"तुम्ही गो होम जेश्चर पूर्ण केले. आता, मागे कसे जायचे ते जाणून घ्या."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"तुम्ही गो होम जेश्चर पूर्ण केले."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"डाव्या किंवा उजव्या कडेपासून स्क्रीनच्या मध्यभागी स्वाइप करा"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"तुम्ही स्क्रीनवरून बोट उचलण्यापूर्वी थांबत नाही याची खात्री करा"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"तुम्ही सरळ वर स्वाइप करत आहात याची खात्री करा"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"तुम्ही गो होम जेश्चर पूर्ण केले आहे. आता, मागे कसे जायचे ते जाणून घ्या."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"तुम्ही गो होम जेश्चर पूर्ण केले आहे"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"होमवर जाण्यासाठी स्वाइप करा"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"तुमच्या स्क्रीनच्या तळाकडून वर स्वाइप करा. हे जेश्चर तुम्हाला नेहमी होम स्क्रीनवर घेऊन जाते."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"स्क्रीनच्या तळापासून दोन बोटांनी वर स्वाइप करा. हे जेश्चर तुम्हाला नेहमी होम स्क्रीनवर घेऊन जाते."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"होमवर जा"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"कधीही तुमच्या होम स्क्रीनवर जाण्यासाठी, तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"विंडोवरून बोट उचलण्यापूर्वी थोडा वेळ ते तेथेच धरून ठेवा."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"तुम्ही सरळ वर स्वाइप करून, त्यानंतर बोट थांबवत आहात याची खात्री करा."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"उत्तम कामगिरी!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"विंडोवरून बोट उचलण्यापूर्वी थोडा वेळ ते तेथेच धरून ठेवा"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"तुम्ही सरळ वर स्वाइप करून थांबत आहात याची खात्री करा"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"तुम्ही जेश्चर कसे वापरायचे हे शिकलात. जेश्चर बंद करण्यासाठी, सेटिंग्ज वर जा."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"तुम्ही ॲप्स स्विच करण्याचे जेश्चर पूर्ण केले."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"तुम्ही स्विच ॲप्स जेश्चर पूर्ण केले आहे"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"अॅप्स स्विच करण्यासाठी स्वाइप करा"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ॲप्सदरम्यान स्विच करण्यासाठी, स्क्रीनच्या तळापासून वर स्वाइप करा, धरून ठेवा, त्यानंतर सोडून द्या."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ॲप्सदरम्यान स्विच करण्यासाठी, स्क्रीनच्या तळापासून दोन बोटांनी वर स्वाइप करा, धरून ठेवा नंतर सोडा."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"अॅप्स स्विच करा"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा, धरून ठेवा, त्यानंतर सोडा"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"छान!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"सर्व तयार आहे"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"पूर्ण झाले"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिंग्ज"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट"</string>
<string name="action_split" msgid="2098009717623550676">"स्प्लिट"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"स्प्लिट स्क्रीन वापरण्यासाठी दुसऱ्या ॲपवर टॅप करा"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"स्प्लिट स्क्रीन निवडीतून बाहेर पडा"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"स्प्लिट स्क्रीन वापरण्यासाठी दुसरे ॲप निवडा"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"अॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"टास्कबार दाखवलेला आहे"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"टास्कबार लपवलेले आहे"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"नेव्हिगेशन बार"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"नेहमी टास्कबार दाखवा"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"नेव्हिगेशन मोड बदला"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"टास्कबार विभाजक"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सर्वात वरती/डावीकडे हलवा"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"तळाशी/उजवीकडे हलवा"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{आणखी # अॅप दाखवा.}other{आणखी # अॅप्स दाखवा.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> आणि <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"डेस्कटॉपवर ॲप जोडत आहे"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"रद्द करा"</string>
</resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 4ed6493..5e61b88 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Cadangan apl didayakan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Cadangan apl dilumpuhkan"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Apl yang diramalkan: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pastikan anda meleret dari hujung sebelah kanan atau sebelah kiri."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pastikan anda meleret dari tepi sebelah kanan atau kiri ke tengah skrin dan lepaskan."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Anda belajar cara meleret dari kanan untuk kembali. Seterusnya, ketahui cara menukar apl."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Anda telah melengkapkan gerak isyarat undur."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pastikan anda tidak meleret terlalu dekat dengan bahagian bawah skrin."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Putarkan peranti anda"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Sila putarkan peranti anda untuk melengkapkan tutorial navigasi gerak isyarat"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pastikan anda meleret dari hujung sebelah kanan atau hujung sebelah kiri"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pastikan anda meleret dari tepi sebelah kanan atau kiri ke bahagian tengah skrin dan lepaskan"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Anda sudah belajar cara meleret dari kanan untuk kembali. Seterusnya, ketahui cara menukar apl."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Anda telah melengkapkan gerak isyarat undur"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pastikan anda tidak meleret terlalu dekat dengan bahagian bawah skrin"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Utk mengubah kepekaan gerak isyarat undur, pergi ke Tetapan"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Leret untuk kembali"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Untuk kembali ke skrin terakhir, leret dari tepi sebelah kiri atau kanan ke tengah skrin."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Untuk kembali ke skrin terakhir, leret dengan 2 jari dari tepi kiri atau kanan ke tengah skrin."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Kembali"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pastikan anda meleret ke atas dari tepi sebelah bawah skrin."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pastikan anda tidak menjeda sebelum melepaskan gerak isyarat tersebut."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pastikan anda meleret terus ke atas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Anda telah melengkapkan gerak isyarat pergi ke Laman Utama. Seterusnya, ketahui cara kembali."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Anda telah melengkapkan gerak isyarat pergi ke Laman Utama."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Leret dari sisi kiri atau kanan ke bahagian tengah skrin"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pastikan anda meleret ke atas dari sisi bahagian bawah skrin"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pastikan anda tidak menjeda sebelum melepaskan leretan tersebut"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pastikan anda meleret terus ke atas"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Anda telah melengkapkan gerak isyarat akses laman utama. Seterusnya, ketahui cara kembali."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Anda telah melengkapkan gerak isyarat akses laman utama"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Leret untuk kembali ke laman utama"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Leret ke atas dari bahagian bawah skrin. Gerak isyarat ini sentiasa membawa anda ke Skrin utama."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Leret ke atas dengan 2 jari dari bawah skrin. Gerak isyarat ini sentiasa bawa anda ke Skrin utama."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Pergi ke laman utama"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Untuk pergi ke skrin utama anda pada bila-bila masa, leret ke atas dari bahagian bawah skrin anda"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pastikan anda meleret ke atas dari tepi sebelah bawah skrin."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Cuba tahan tetingkap untuk tempoh yang lebih lama sebelum melepaskan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pastikan anda meleret ke atas, kemudian menjeda."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Anda mempelajari cara menggunakan gerak isyarat. Untuk mematikan gerak isyarat, pergi ke Tetapan."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Anda telah melengkapkan gerak isyarat menukar apl."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Pergi ke skrin utama"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Leret ke atas dari bahagian bawah skrin anda"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Syabas!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pastikan anda meleret ke atas dari sisi bahagian bawah skrin"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Cuba tahan tetingkap untuk tempoh yang lebih lama sebelum melepaskan"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pastikan anda meleret terus ke atas, kemudian menjeda"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Anda sudah belajar cara menggunakan gerak isyarat. Untuk mematikan gerak isyarat, pergi ke Tetapan."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Anda telah melengkapkan gerak isyarat menukar apl"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Leret untuk menukar apl"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Untuk beralih antara apl, leret ke atas dari bahagian bawah skrin anda, tahan, kemudian lepaskan."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Untuk beralih antara apl, leret ke atas dengan 2 jari dari bawah skrin, tahan, kemudian lepaskan."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Tukar apl"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Beralih antara apl"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Leret ke atas dari bahagian bawah skrin anda, tahan, kemudian lepaskan"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Syabas!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Selesai"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Selesai"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Tetapan"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Siap!"</string>
- <string name="allset_hint" msgid="459504134589971527">"Leret ke atas untuk mencapai laman utama"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Leret ke atas untuk ke laman utama"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Ketik butang skrin utama untuk pergi ke skrin utama anda"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Anda sudah sedia untuk mula menggunakan <xliff:g id="DEVICE">%1$s</xliff:g> anda"</string>
<string name="default_device_name" msgid="6660656727127422487">"peranti"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Tangkapan skrin"</string>
<string name="action_split" msgid="2098009717623550676">"Pisah"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Ketik apl lain untuk menggunakan skrin pisah"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Keluar daripada pilihan skrin pisah"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pilih apl lain untuk menggunakan skrin pisah"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak dibenarkan oleh apl atau organisasi anda"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Langkau tutorial navigasi?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Bar Tugas dipaparkan"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Bar Tugas disembunyikan"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Bar navigasi"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Sentiasa paparkan Bar Tugas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Tukar mod navigasi"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Pembahagi Bar Tugas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Alihkan ke atas/kiri"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Alihkan ke bawah/kanan"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Tunjukkan # lagi apl.}other{Tunjukkan # lagi apl.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> dan <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Menambahkan apl pada Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Batal"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 617473c..6f1a276 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -24,7 +24,7 @@
<string name="recents_empty_message" msgid="7040467240571714191">"မကြာမီကဖွင့်ထားသည်များ မရှိပါ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"အက်ပ်အသုံးပြုမှု ဆက်တင်များ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးရှင်းရန်"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"လတ်တလောသုံး အက်ပ်များ"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"မကြာသေးမီက အက်ပ်များ"</string>
<string name="task_view_closed" msgid="9170038230110856166">"လုပ်ဆောင်စရာ ပိတ်ထားသည်"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>၊ <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"< ၁ မိနစ်"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"အက်ပ်အကြံပြုချက်များ ဖွင့်ထားသည်"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"အက်ပ်အကြံပြုချက်များကို ပိတ်ထားသည်"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ကြိုတင်မှန်းဆထားသော အက်ပ်− <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ညာ သို့မဟုတ် ဘယ်ဘက်အစွန်မှ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"စခရင်၏ ညာ သို့မဟုတ် ဘက်ဘက်အစွန်မှ အလယ်သို့ ပွတ်ဆွဲပြီး လွှတ်လိုက်ကြောင်း သေချာပါစေ။"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"သင့်စက်ကို လှည့်ပါ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"လက်ဟန်ဖြင့် လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်အား အပြီးသတ်ရန် သင့်စက်ကို လှည့်ပါ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ညာ (သို့) ဘယ်အစွန်း၏ ခပ်လှမ်းလှမ်းမှ ပွတ်ဆွဲကြောင်း သေချာပါစေ"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ဖန်သားပြင်၏ ညာ (သို့) ဘယ်အစွန်းမှ အလယ်သို့ ပွတ်ဆွဲပြီး လွှတ်လိုက်ကြောင်း သေချာပါစေ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"နောက်ပြန်သွားရန် ညာဘက်မှပွတ်ဆွဲနည်းကို သိသွားပါပြီ။ နောက်အဆင့်တွင် အက်ပ်များပြောင်းနည်းကို လေ့လာပါ။"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"နောက်ဆုတ်လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ဖန်သားပြင် အောက်ခြေနှင့် အလွန်နီးကပ်စွာ ပွတ်ဆွဲခြင်းမရှိကြောင်း သေချာပါစေ။"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"နောက်သို့ လက်ဟန် အပြီးသတ်လိုက်ပါပြီ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ဖန်သားပြင် အောက်ခြေနှင့် အလွန်နီးကပ်စွာ ပွတ်ဆွဲခြင်းမရှိကြောင်း သေချာပါစေ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"နောက်ဆုတ်လက်ဟန်၏ အာရုံခံစွမ်းကိုပြောင်းရန် ‘ဆက်တင်များ’ သို့ သွားပါ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"နောက်ပြန်သွားရန် ပွတ်ဆွဲပါ"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"နောက်ဆုံးဖန်သားပြင်သို့ ပြန်သွားရန် ဘယ်ဘက် (သို့) ညာဘက်အစွန်မှ ဖန်သားပြင်အလယ်သို့ ပွတ်ဆွဲပါ။"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ပြီးခဲ့သည့်ဖန်သားပြင်သို့သွားရန် ဘယ်ဘက် (သို့) ညာဘက်အစွန်းမှ ဖန်သားပြင်အလယ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲပါ။"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"နောက်သို့"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ဖန်သားပြင် အောက်ခြေအစွန်မှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"လက်မလွှတ်ခင် ခဏရပ်ခြင်းမရှိကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။ နောက်အဆင့်တွင် နောက်သို့ပြန်သွားနည်းကို လေ့လာပါ။"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ဖန်သားပြင်၏ ဘယ် (သို့) ညာအစွန်းမှ အလယ်သို့ ပွတ်ဆွဲပါ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ဖန်သားပြင် အောက်ခြေအစွန်းမှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"လက်မလွှတ်ခင် ခဏရပ်ခြင်းမရှိကြောင်း သေချာပါစေ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် အပြီးသတ်လိုက်ပါပြီ။ နောက်အဆင့်တွင် နောက်သို့ပြန်သွားပုံကို လေ့လာပါ။"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် အပြီးသတ်လိုက်ပါပြီ"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ပင်မစာမျက်နှာသို့သွားရန် ပွတ်ဆွဲပါ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"သင့်ဖန်သားပြင် အောက်ခြေမှ အပေါ်သို့ပွတ်ဆွဲပါ။ ဤလက်ဟန်ဖြင့် ပင်မစာမျက်နှာသို့ အမြဲပြန်သွားနိုင်သည်။"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ဖန်သားပြင်အောက်မှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲပါ။ ဤလက်ဟန်က ပင်မစာမျက်နှာသို့ အမြဲပို့ပေးမည်။"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ပင်မစာမျက်နှာသို့ သွားပါ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ပင်မစာမျက်နှာသို့ အချိန်မရွေး ပြန်သွားရန် စခရင်အောက်ခြေမှ အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ဖန်သားပြင် အောက်ခြေအစွန်မှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"မလွှတ်ခင် ဝင်းဒိုးကို အချိန်ကြာကြာ ဖိထားကြည့်ပါ။"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲပြီးနောက် ခဏရပ်ကြောင်း သေချာပါစေ။"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ပင်မစာမျက်နှာသွားရန်"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"သင့်ဖန်သားပြင် အောက်ခြေမှ အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"တော်ပါပေသည်။"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ဖန်သားပြင် အောက်ခြေအစွန်းမှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"မလွှတ်ခင် ဝင်းဒိုးကို အချိန်ကြာကြာ ဖိထားကြည့်ပါ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲပြီးနောက် ခဏရပ်ကြောင်း သေချာပါစေ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"လက်ဟန်များသုံးနည်းကို သင်သိသွားပါပြီ။ လက်ဟန်များကို ပိတ်ရန် ဆက်တင်များသို့ သွားပါ။"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"အက်ပ်များပြောင်းသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"အက်ပ်များပြောင်းသည့် လက်ဟန် အပြီးသတ်လိုက်ပါပြီ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"အက်ပ်များပြောင်းရန် ပွတ်ဆွဲပါ"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"အက်ပ်တစ်ခုမှတစ်ခုသို့ ပြောင်းရန် စခရင်အောက်ခြေမှ အပေါ်သို့ ပွတ်ဆွဲ၍ ဖိထားပြီးနောက် လွှတ်ပါ။"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"အက်ပ်များကြားပြောင်းရန် ဖန်သားပြင်အောက်မှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့်ဆွဲ၍ ထိန်းထားပြီး လွှတ်ပါ။"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"အက်ပ်များ ကူးပြောင်းရန်"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"သင့်ဖန်သားပြင် အောက်ခြေမှ အပေါ်သို့ ပွတ်ဆွဲ၍ ဖိထားပြီးလွှတ်လိုက်ပါ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"အလွန်ကောင်းပါသည်။"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"အားလုံးအဆင်သင့်ဖြစ်ပါပြီ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ပြီးပြီ"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ဆက်တင်များ"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
<string name="action_split" msgid="2098009717623550676">"ခွဲထုတ်ရန်"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"မျက်နှာပြင် ခွဲ၍ပြသရန် အက်ပ်နောက်တစ်ခုကို တို့ပါ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း ရွေးချယ်မှုမှ ထွက်ရန်"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"မျက်နှာပြင်ခွဲ၍ပြသခြင်းသုံးရန် နောက်အက်ပ်တစ်ခုရွေးပါ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ဤလုပ်ဆောင်ချက်ကို အက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်ကို ကျော်မလား။"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar ပြထားသည်"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar ဖျောက်ထားသည်"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"လမ်းညွှန်ဘား"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"‘လုပ်ဆောင်စရာဘား’ အမြဲပြပါ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ရွှေ့ကြည့်သည့်မုဒ် ပြောင်းရန်"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"လုပ်ဆောင်စရာဘား ပိုင်းခြားစနစ်"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"အောက်ခြေ/ညာဘက်သို့ ရွှေ့ရန်"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{နောက်ထပ်အက်ပ် # ခု ပြပါ။}other{နောက်ထပ်အက်ပ် # ခု ပြပါ။}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> နှင့် <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"‘ဒက်စ်တော့’ တွင် အက်ပ်ကို ထည့်ခြင်း"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"မလုပ်တော့"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index e4d75be..d4b8de9 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er på"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er slått av"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Foreslått app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Sørg for at du sveiper fra kanten helt til høyre eller venstre."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Sørg for at du sveiper fra den høyre eller venstre kanten til midten av skjermen og slipper."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Roter enheten"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Roter enheten for å fullføre veiledningen for navigasjon med bevegelser"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Sørg for at du sveiper fra kanten helt til høyre eller venstre"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Sørg for at du sveiper fra den høyre eller venstre kanten til midten av skjermen og slipper"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du har lært hvordan du sveiper fra høyre for å gå tilbake. I neste trinn lærer du å bytte app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du har fullført bevegelsen for å gå tilbake."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Sørg for at du ikke sveiper for nær bunnen av skjermen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du har fullført bevegelsen for å gå tilbake"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Sørg for at du ikke sveiper for nær bunnen av skjermen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Gå til Innstillinger for å endre tilbakebevegelsefølsomheten"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Sveip for å gå tilbake"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"For å gå tilbake til forrige skjerm, sveip fra venstre eller høyre kant til midten av skjermen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"For å gå tilbake til den forrige skjermen, sveip med to fingre fra den venstre eller høyre kanten til midten av skjermen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Gå tilbake"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Sørg for at du sveiper opp fra den nederste kanten av skjermen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Sørg for at du ikke setter på pause før du slipper."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Sørg for at du sveiper rett opp."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du har fullført bevegelsen for å gå til startskjermen. I neste trinn ser du hvordan du går tilbake."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du har fullført bevegelsen for å gå til startskjermen."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Sveip fra venstre eller høyre kant til midten av skjermen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Sørg for at du sveiper opp fra den nederste kanten av skjermen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Sørg for at du ikke setter på pause før du slipper"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Sørg for at du sveiper rett opp"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du har fullført bevegelsen for å gå til startskjermen. I neste trinn ser du hvordan du går tilbake."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du har fullført bevegelsen for å gå til startskjermen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Sveip for å gå til startskjermen"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Sveip opp fra bunnen av skjermen. Denne bevegelsen tar deg alltid til startskjermen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Sveip opp med to fingre fra bunnen av skjermen. Denne bevegelsen tar deg alltid til startskjermen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Gå til startskjermen"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"For å gå til startskjermen, sveip opp fra bunnen av skjermen når som helst"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Sørg for at du sveiper opp fra den nederste kanten av skjermen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prøv å holde vinduet lenger før du slipper."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sørg for at du sveiper rett opp, og så stopper du."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Sveip opp fra bunnen av skjermen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Bra jobbet!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Sørg for at du sveiper opp fra den nederste kanten av skjermen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Prøv å holde vinduet lenger før du slipper"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Sørg for at du sveiper rett opp, og så stopper du"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lært hvordan du bruker bevegelser. For å slå av bevegelser, gå til Innstillinger."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du har fullført bevegelsen for å bytte app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du har fullført bevegelsen for å bytte app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Sveip for å bytte app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"For å bytte mellom apper, sveip opp fra bunnen av skjermen, hold, og slipp"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"For å bytte mellom apper, sveip opp med to fingre fra bunnen av skjermen, hold, og slipp."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Bytt app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Sveip opp fra bunnen av skjermen, hold, og slipp"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Bra!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Ferdig"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Ferdig"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Innstillinger"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skjermdump"</string>
<string name="action_split" msgid="2098009717623550676">"Del opp"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Trykk på en annen app for å bruke delt skjerm"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Avslutt valg av delt skjerm"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Velg en annen app for å bruke delt skjerm"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisasjonen din tillater ikke denne handlingen"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vil du hoppe over navigeringsveiledningen?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Oppgavelinjen vises"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Oppgavelinjen er skjult"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigasjonsrad"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Vis alltid oppgavelinjen"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Endre navigasjonsmodus"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Skille for oppgavelinjen"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytt til øverst/venstre"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytt til nederst/høyre"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Vis # app til.}other{Vis # apper til.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> og <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Legg til apper på datamaskin"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Avbryt"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index b9e8e1c..b326cb4 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सिफारिस गरिएका एप देखाउने सुविधा अन गरिएको छ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सिफारिस गरिएका एपहरू देखाउने सुविधा असक्षम पारिएको छ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान गरिएको एप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"स्क्रिनको सबैभन्दा दायाँ किनारा वा सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"स्क्रिनको दायाँ वा बायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्।"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"इसारामार्फत गरिने नेभिगेसनको ट्युटोरियल पूरा गर्न कृपया आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"स्क्रिनको सबैभन्दा दायाँ किनारा वा सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"स्क्रिनको दायाँ वा बायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"तपाईंले स्क्रिनको दायाँ किनाराबाट स्वाइप गरेर अघिल्लो स्क्रिनमा फर्कने तरिका सिक्नुभयो। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"तपाईंले \'पछाडि जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"स्क्रिनको फेदको धेरै नजिकसम्म स्वाइप नगर्नुहोस्।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"तपाईंले \"पछाडि जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"स्क्रिनको फेदको धेरै नजिकसम्म स्वाइप नगर्नुहोस्"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'पछाडि\' नामक इसाराको संवेदनशीलता बदल्न सेटिङमा जानुहोस्"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"पछाडि जान स्वाइप गर्नुहोस्"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"यसअघिको स्क्रिनमा फर्कन स्क्रिनको बायाँ वा दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस्।"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"तपाईं यसअघि जुन स्क्रिनमा हुनुहुन्थ्यो त्यही स्क्रिनमा फर्कन चाहनुहुन्छ भने २ वटा औँला प्रयोग गरी स्क्रिनको बायाँ वा दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस्।"</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"पछाडि जानुहोस्"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"औँला उठाउनुअघि नरोकिनुहोस्।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"सीधै माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"तपाईंले \'होम स्क्रिनमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब पछाडि जाने तरिका सिक्नुहोस्।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"तपाईंले \'होम स्क्रिनमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"पछाडि जाने तरिका"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"स्क्रिनको बायाँ वा दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस्"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"औँला उठाउनुअघि नरोकिनुहोस्"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"सीधै माथितिर स्वाइप गर्नुहोस्"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब पछाडि जाने तरिका सिक्नुहोस्।"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"तपाईंले \"होम स्क्रिनमा जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रिनमा जान स्वाइप गर्नुहोस्"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्। यो इसारा प्रयोग गर्दा सधैँ होम स्क्रिन खुल्छ।"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"२ वटा औँला प्रयोग गरी स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्। यो जेस्चर प्रयोग गर्दा सधैँ होम स्क्रिन खुल्छ।"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"होम स्क्रिनमा जाने तरिका"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"जुनसुकै बेला होम स्क्रिनमा जान स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस्"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"स्क्रिनबाट औँला उठाउनुअघि एपको विन्डोमा केही बेर छोइराख्नुहोस्।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"सीधै माथितिर स्वाइप गर्नुहोस् अनि रोकिनुहोस्।"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"अद्भुत!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"स्क्रिनबाट औँला उठाउनुअघि एपको विन्डोमा केही बेर छोइराख्नुहोस्"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"सीधै माथितिर स्वाइप गर्नुहोस् अनि रोकिनुहोस्"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"तपाईंले इसाराहरू प्रयोग गर्ने तरिका सिक्नुभयो। इसारा अफ गर्न सेटिङमा जानुहोस्।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"तपाईंले \'एउटा एपबाट अर्को एपमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"तपाईंले \"एउटा एपबाट अर्को एपमा जानुहोस्\" नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"एउटा एपबाट अर्को एपमा जान स्वाइप गर्नुहोस्"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"एउटा एपबाट अर्कोमा जान स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्, छोइराख्नुहोस् अनि औँला उठाउनुहोस्।"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"एउटा एपबाट अर्कोमा जान २ वटा औँला प्रयोग गरी स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्, छोइराख्नुहोस् अनि औँला उठाउनुहोस्।"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"एउटा एपबाट अर्को एपमा जाने तरिका"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्, छोइराख्नुहोस् अनि औँला उठाउनुहोस्"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"स्याबास!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"सबै तयार छ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"सम्पन्न भयो"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिङ"</string>
@@ -89,12 +95,13 @@
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रिनसट"</string>
<string name="action_split" msgid="2098009717623550676">"स्प्लिट गर्नुहोस्"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"स्प्लिटस्क्रिन प्रयोग गर्न अर्को एपमा ट्याप गर्नु…"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"स्प्लिट स्क्रिन मोडबाट बाहिरिनुहोस्"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"स्प्लिट स्क्रिन प्रयोग गर्न अर्को एप रोज्नुहोस्"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेभिगेसन ट्युटोरियल स्किप गर्ने हो?"</string>
<string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तपाईं पछि <xliff:g id="NAME">%1$s</xliff:g> नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द गर्नुहोस्"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नु…"</string>
+ <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नुहोस्"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रिन घुमाउनुहोस्"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"टास्कबार एजुकेसन"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"एपलाई छेउतिर ड्र्याग गरेर एकै पटक २ वटा एप चलाउनुहोस्"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"टास्कबार देखाइएको छ"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"टास्कबार लुकाइएको छ"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"नेभिगेसन बार"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"टास्कबार सधैँ देखाइयोस्"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"नेभिगेसन मोड बदल्नुहोस्"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"टास्कबार डिभाइडर"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सिरान/बायाँतिर सार्नुहोस्"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"फेद/दायाँतिर सार्नुहोस्"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{थप # एप देखाइयोस्।}other{थप # वटा एप देखाइयोस्।}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> र <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"डेस्कटपमा एप हालिँदै छ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"रद्द गर्नुहोस्"</string>
</resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index f2a9d88..6a7efe5 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -44,40 +44,46 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App-suggesties staan aan"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App-suggesties staan uit"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Swipe helemaal vanaf de rechter- of linkerrand."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Swipe vanaf de rechter- of linkerrand naar het midden van het scherm en laat los."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Het apparaat draaien"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Draai het apparaat om de tutorial voor navigatie met gebaren af te ronden"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Swipe vanaf de rechter- of linkerrand"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Swipe vanaf de rechter- of linkerrand naar het midden van het scherm en laat los"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Je weet nu hoe je vanaf rechts kunt swipen om terug te gaan. Ontdek nu hoe je tussen apps schakelt."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Je weet nu hoe je het gebaar Terug maakt."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Swipe niet te dicht bij de onderkant van het scherm."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Je weet nu hoe je het gebaar Terug maakt"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Swipe niet te dicht bij de onderkant van het scherm"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Open Instellingen om de gevoeligheid van Terug te wijzigen"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe om terug te gaan"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Swipe vanaf de linker- of rechterrand naar het midden om terug te gaan naar het vorige scherm."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Als je wilt teruggaan naar het laatste scherm, swipe je met 2 vingers vanaf de linker- of rechterrand naar het midden van het scherm."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Terug"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Swipe vanaf de onderrand van het scherm omhoog."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pauzeer niet voordat je loslaat."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Swipe recht omhoog."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Je hebt geleerd hoe je weer naar het startscherm gaat. Ontdek nu hoe je weer teruggaat."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Je weet nu hoe je teruggaat naar het startscherm."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swipe vanaf de linker- of rechterrand naar het midden van het scherm"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Swipe vanaf de onderrand van het scherm omhoog"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pauzeer niet voordat je loslaat"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Swipe recht omhoog"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Je weet nu hoe je het gebaar Naar startscherm maakt. Ontdek als volgende hoe je kunt teruggaan."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Je weet nu hoe je teruggaat naar het startscherm"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe om naar het startscherm te gaan"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe omhoog vanaf de onderkant van het scherm. Met dit gebaar ga je altijd naar het startscherm."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swipe met 2 vingers omhoog vanaf de onderkant van het scherm. Met dit gebaar ga je altijd naar het startscherm."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Naar het startscherm"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Ga op elk moment naar je startscherm door omhoog te swipen vanaf de onderkant van je scherm"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Swipe vanaf de onderrand van het scherm omhoog."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Houd het venster langer vast voordat je loslaat."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Swipe recht omhoog en pauzeer dan."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swipe omhoog vanaf de onderkant van het scherm"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Goed gedaan"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Swipe vanaf de onderrand van het scherm omhoog"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Houd je vinger langer op het venster voordat je loslaat"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Swipe recht omhoog en pauzeer dan"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Je weet nu hoe je gebaren gebruikt. Als je gebaren wilt uitzetten, kun je dat via Instellingen doen."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Je weet nu hoe je het gebaar Schakelen tussen apps maakt."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Je weet nu hoe je het gebaar Schakelen tussen apps maakt"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe om tussen apps te schakelen"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Swipe omhoog vanaf de onderkant van het scherm, houd vast en laat los om tussen apps te schakelen."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Swipe met 2 vingers omhoog vanaf de onderkant van het scherm, houd vast en laat los om tussen apps te schakelen."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Schakelen tussen apps"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swipe omhoog vanaf de onderkant van het scherm, houd je vinger op het scherm en laat dan los"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Goed bezig"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Klaar"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klaar"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Instellingen"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probeer opnieuw"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Dat gaat lekker."</string>
+ <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Dat gaat lekker"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Klaar"</string>
<string name="allset_hint" msgid="459504134589971527">"Swipe omhoog om naar het startscherm te gaan"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Splitsen"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tik op nog een app om je scherm te splitsen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Sluit de selectie voor gesplitst scherm"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Kies andere app om gesplitst scherm te gebruiken"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Deze actie wordt niet toegestaan door de app of je organisatie"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Navigatietutorial overslaan?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Scherm draaien"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Taakbalk Onderwijs"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Sleep een app naar de zijkant om 2 apps tegelijk te gebruiken"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Swipe kort omhoog om de taakbalk te tonen"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Swipe langzaam omhoog om de taakbalk te tonen"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Krijg app-suggesties op basis van je routine"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Zet navigatie met gebaren aan bij Instellingen om de Taakbalk automatisch te verbergen"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Doe meer met de taakbalk"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taakbalk wordt getoond"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taakbalk is verborgen"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigatiebalk"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Taakbalk altijd tonen"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Navigatiemodus wijzigen"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Scheiding voor Taakbalk"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Naar boven/links verplaatsen"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Naar beneden/rechts verplaatsen"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Nog # app tonen.}other{Nog # apps tonen.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> en <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"App toevoegen aan desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annuleren"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 2affa6f..f0a5053 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -21,7 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"ପିନ୍"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ଫ୍ରିଫର୍ମ"</string>
- <string name="recents_empty_message" msgid="7040467240571714191">"କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"</string>
+ <string name="recents_empty_message" msgid="7040467240571714191">"ବର୍ତ୍ତମାନର କୌଣସି ଆଇଟମ ନାହିଁ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ଆପ ବ୍ୟବହାର ସେଟିଂସ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ବର୍ତ୍ତମାନର ଆପ୍"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ପୂର୍ବାନୁମାନ କରାଯାଇଥିବା ଆପ୍: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ଆପଣ ସ୍କ୍ରିନର ଏକଦମ୍-ଡାହାଣ ବା ବାମ ଧାରରୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ଆପଣ ସ୍କ୍ରିନର ଡାହାଣ ବା ବାମ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ୍ କରି ଛାଡ଼ି ଦେଉଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ଆପଣଙ୍କ ଡିଭାଇସକୁ ରୋଟେଟ କରନ୍ତୁ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ଜେଶ୍ଚର ନାଭିଗେସନ ଟ୍ୟୁଟୋରିଆଲ ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ଦୟାକରି ଆପଣଙ୍କ ଡିଭାଇସ ରୋଟେଟ କରନ୍ତୁ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ଆପଣ ସ୍କ୍ରିନର ଏକଦମ୍-ଡାହାଣ ବା ବାମ ଧାରରୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ଆପଣ ସ୍କ୍ରିନର ଡାହାଣ ବା ବାମ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ କରି ଛାଡ଼ି ଦେଉଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ଆପଣ ଡାହାଣରୁ ସ୍ୱାଇପ୍ କରି ପଛକୁ କିପରି ଫେରିବେ ତାହା ଜାଣିଲେ। ତା\'ପରେ, ଆପକୁ କିପରି ସ୍ୱିଚ୍ କରିବେ ତାହା ଜାଣନ୍ତୁ।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ଆପଣ \'ପଛକୁ ଫେରନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ଆପଣ ସ୍କ୍ରିନର ତଳଭାଗର ଅତି ନିକଟରୁ ସ୍ୱାଇପ୍ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ଆପଣ \'ପଛକୁ ଫେରନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ଆପଣ ସ୍କ୍ରିନର ତଳଭାଗର ଅତି ନିକଟରୁ ସ୍ୱାଇପ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ପଛକୁ ଫେରିବା ଜେଶ୍ଚରର ସମ୍ବେଦନଶୀଳତା ବଦଳାଇବାକୁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ପଛକୁ ଫେରିବା ପାଇଁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ପୂର୍ବବର୍ତ୍ତୀ ସ୍କ୍ରିନକୁ ଫେରିବା ପାଇଁ, ସ୍କ୍ରିନର ବାମ କିମ୍ବା ଡାହାଣ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ।"</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ପୂର୍ବ ସ୍କ୍ରିନକୁ ଫେରିବା ପାଇଁ, ସ୍କ୍ରିନର ବାମ କିମ୍ବା ଡାହାଣ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ପୂର୍ବ ସ୍କ୍ରିନକୁ ଫେରିବା ପାଇଁ, ସ୍କ୍ରିନର ବାମ କିମ୍ବା ଡାହାଣ ଧାରରୁ ମଝିକୁ 2ଟି ଆଙ୍ଗୁଠିରେ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ପଛକୁ ଫେରନ୍ତୁ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ଆପଣ ଛାଡ଼ିବା ପୂର୍ବରୁ ବିରତ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ଆପଣ ହୋମ ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି। ତା\'ପରେ, ପଛକୁ କିପରି ଫେରିବେ ତାହା ଜାଣନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ଆପଣ ହୋମ ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ସ୍କ୍ରିନର ବାମ କିମ୍ବା ଡାହାଣ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ଆପଣ ଛାଡ଼ିବା ପୂର୍ବରୁ ବିରତ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ଆପଣ \'ହୋମକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି। ତା\'ପରେ, ପଛକୁ କିପରି ଫେରିବେ ତାହା ଜାଣନ୍ତୁ।"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ଆପଣ \'ମୂଳପୃଷ୍ଠାକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ହୋମକୁ ଯିବା ପାଇଁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ଆପଣଙ୍କ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ। ଏହି ଜେଶ୍ଚର ସର୍ବଦା ଆପଣଙ୍କୁ ହୋମ ସ୍କ୍ରିନକୁ ନେଇଥାଏ।"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2ଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ। ଏହି ଜେଶ୍ଚର ସର୍ବଦା ଆପଣଙ୍କୁ ହୋମ ସ୍କ୍ରିନକୁ ନେଇଥାଏ।"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ହୋମକୁ ଯାଆନ୍ତୁ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ଯେ କୌଣସି ସମୟରେ ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ଆପଣଙ୍କ ସ୍କିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ୱିଣ୍ଡୋକୁ ରିଲିଜ୍ କରିବା ପୂର୍ବରୁ ଅଧିକ ସମୟ ଧରି ରଖିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ୍ କରି ତା\'ପରେ ବିରତ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ଆପଣଙ୍କ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ବଢ଼ିଆ କାମ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ୱିଣ୍ଡୋକୁ ରିଲିଜ୍ କରିବା ପୂର୍ବରୁ ଅଧିକ ସମୟ ଧରି ରଖିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ୍ କରି ତା\'ପରେ ବିରତ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ଜେଶ୍ଚରଗୁଡ଼ିକୁ କିପରି ବ୍ୟବହାର କରାଯିବ ଆପଣ ତାହା ଶିଖିଛନ୍ତି। ଜେଶ୍ଚରଗୁଡ଼ିକୁ ବନ୍ଦ କରିବାକୁ, ସେଟିଂସକୁ ଯାଆନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ଆପଣ \'ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ୍ କରନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ଆପଣ \'ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ୍ କରନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ଆପଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ, ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ୍ କରନ୍ତୁ।"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ଆପ୍ସ ମଧ୍ୟରେ ସୁଇଚ କରିବାକୁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ, ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ କରନ୍ତୁ।"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ଆପ୍ସ ମଧ୍ୟରେ ସ୍ୱିଚ କରିବାକୁ, 2ଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ କରି ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ କର।"</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ଆପ୍ସ ସ୍ୱିଚ କରନ୍ତୁ"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ଆପ୍ସ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ଆପଣଙ୍କ ସ୍କ୍ରିନ୍ର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ୍ କରନ୍ତୁ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ବହୁତ ବଢ଼ିଆ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ସବୁ ପ୍ରସ୍ତୁତ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ହୋଇଗଲା"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ସେଟିଂସ"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ବଢ଼ିଆ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ଟ୍ୟୁଟୋରିଆଲ୍ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!"</string>
- <string name="allset_hint" msgid="459504134589971527">"ମୂଳପୃଷ୍ଠାକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
+ <string name="allset_hint" msgid="459504134589971527">"ହୋମକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ହୋମ ବଟନରେ ଟାପ କରନ୍ତୁ"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"ଆପଣ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g> ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି"</string>
<string name="default_device_name" msgid="6660656727127422487">"ଡିଭାଇସ"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ସ୍କ୍ରିନସଟ୍"</string>
<string name="action_split" msgid="2098009717623550676">"ସ୍ପ୍ଲିଟ୍"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"ସ୍ପ୍ଲିଟସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପରେ ଟାପ କର"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ଚୟନରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପ ବାଛନ୍ତୁ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ଆପ୍ କିମ୍ବା ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ଏହି କାର୍ଯ୍ୟକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ନାଭିଗେସନ୍ ଟ୍ୟୁଟୋରିଆଲକୁ ବାଦ୍ ଦେବେ?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ଟାସ୍କବାର ଦେଖାଯାଇଛି"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ଟାସ୍କବାର ଲୁଚାଯାଇଛି"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ନାଭିଗେସନ ବାର"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ସର୍ବଦା ଟାସ୍କବାର ଦେଖାନ୍ତୁ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ନାଭିଗେସନ ମୋଡ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ଟାସ୍କବାର ଡିଭାଇଡର"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{ଅଧିକ #ଟି ଆପ ଦେଖାନ୍ତୁ।}other{ଅଧିକ #ଟି ଆପ୍ସ ଦେଖାନ୍ତୁ।}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ଏବଂ <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ଡେସ୍କଟପରେ ଆପ ଯୋଗ କରାଯାଉଛି"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ବାତିଲ କରନ୍ତୁ"</string>
</resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index df9cc35..c66e26f 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ਪੂਰਵ ਅਨੁਮਾਨਿਤ ਐਪ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਪਾਸੇ ਦੇ ਬਿਲਕੁਲ ਕਿਨਾਰੇ ਤੋਂ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰਦੇ ਹੋ ਅਤੇ ਛੱਡ ਦਿੰਦੇ ਹੋ।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ਤੁਸੀਂ ਪਿੱਛੇ ਜਾਣ ਲਈ ਸੱਜੇ ਪਾਸੇ ਤੋਂ ਸਵਾਈਪ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣਿਆ। ਅੱਗੇ, ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣੋ।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ਤੁਸੀਂ \'ਵਾਪਸ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਹਿੱਸੇ ਦੇ ਬਹੁਤ ਨੇੜੇ ਸਵਾਈਪ ਨਾ ਕਰੋ।"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁੰਮਾਓ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"ਕਿਰਪਾ ਕਰਕੇ ਇਸ਼ਾਰਾ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਪੂਰਾ ਕਰਨ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁੰਮਾਓ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਪਾਸੇ ਦੇ ਬਿਲਕੁਲ ਕਿਨਾਰੇ ਤੋਂ ਸਵਾਈਪ ਕਰਦੇ ਹੋ"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰਦੇ ਹੋ ਅਤੇ ਛੱਡ ਦਿੰਦੇ ਹੋ"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ਤੁਸੀਂ ਪਿੱਛੇ ਜਾਣ ਲਈ ਸੱਜੇ ਪਾਸੇ ਤੋਂ ਸਵਾਈਪ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣਿਆ। ਅੱਗੇ, ਐਪਾਂ ਵਿਚਾਲੇ ਸਵਿੱਚ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣੋ।"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ਤੁਸੀਂ \'ਵਾਪਸ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਹਿੱਸੇ ਦੇ ਬਹੁਤ ਨੇੜੇ ਸਵਾਈਪ ਨਾ ਕਰੋ"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ਪਿੱਛੇ ਜਾਣ ਦੇ ਸੰਕੇਤ ਦੀ ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਬਦਲਣ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ਪਿੱਛੇ ਜਾਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ਪਿਛਲੀ ਸਕ੍ਰੀਨ \'ਤੇ ਵਾਪਸ ਜਾਣ ਲਈ, ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰੋ।"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"ਪਿਛਲੀ ਸਕ੍ਰੀਨ \'ਤੇ ਵਾਪਸ ਜਾਣ ਲਈ, ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ 2 ਉਂਗਲਾਂ ਨਾਲ ਸਵਾਈਪ ਕਰੋ।"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ਵਾਪਸ ਜਾਓ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ਪੱਕਾ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਨੂੰ ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਰੁਕੋ ਨਾ।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ। ਅੱਗੇ, ਜਾਣੋ ਕਿ ਪਿੱਛੇ ਕਿਵੇਂ ਜਾਣਾ ਹੈ।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ਪੱਕਾ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਨੂੰ ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਰੁਕੋ ਨਾ"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧਾ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ। ਅੱਗੇ, ਜਾਣੋ ਕਿ ਪਿੱਛੇ ਕਿਵੇਂ ਜਾਣਾ ਹੈ।"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ। ਇਹ ਇਸ਼ਾਰਾ ਹਮੇਸ਼ਾਂ ਤੁਹਾਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲੈ ਜਾਂਦਾ ਹੈ।"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ 2 ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ। ਇਹ ਇਸ਼ਾਰਾ ਹਮੇਸ਼ਾਂ ਤੁਹਾਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲੈ ਜਾਂਦਾ ਹੈ।"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਓ"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ਕਿਸੇ ਵੀ ਸਮੇਂ ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਣ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਵਿੰਡੋ ਨੂੰ ਕੁਝ ਸਮੇਂ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ, ਫਿਰ ਰੋਕੋ।"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"ਬਹੁਤ ਵਧੀਆ!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਵਿੰਡੋ ਨੂੰ ਕੁਝ ਸਮੇਂ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧਾ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ, ਫਿਰ ਰੋਕੋ"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ਤੁਸੀਂ ਇਸ਼ਾਰੇ ਵਰਤਣ ਬਾਰੇ ਜਾਣਿਆ। ਇਸ਼ਾਰੇ ਬੰਦ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ਤੁਸੀਂ \'ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ਤੁਸੀਂ \'ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਅਤੇ ਫਿਰ ਛੱਡੋ।"</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ 2 ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ ਅਤੇ ਫਿਰ ਛੱਡੋ।"</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ਐਪਾਂ ਵਿਚਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ਐਪਾਂ ਵਿਚਾਲੇ ਸਵਿੱਚ ਕਰਨ ਲਈ, ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਤੇ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ ਅਤੇ ਫਿਰ ਛੱਡੋ।"</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ਐਪਾਂ ਵਿਚਾਲੇ ਸਵਿੱਚ ਕਰਨ ਲਈ, ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ 2 ਉਂਗਲਾਂ ਨਾਲ ਉੱਤੇ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ ਅਤੇ ਫਿਰ ਛੱਡੋ।"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ਐਪਾਂ ਸਵਿੱਚ ਕਰੋ"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਦਬਾਈ ਰੱਖੋ, ਅਤੇ ਫਿਰ ਛੱਡੋ"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"ਬਹੁਤ ਵਧੀਆ!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ਹੋ ਗਿਆ"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ਸੈਟਿੰਗਾਂ"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
<string name="action_split" msgid="2098009717623550676">"ਸਪਲਿਟ"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਨੂੰ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਚੋਣ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਨੂੰ ਚੁਣੋ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਕਾਰਵਾਈ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ਕੀ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਛੱਡਣਾ ਹੈ?"</string>
@@ -97,7 +104,7 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ਛੱਡੋ"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"ਸਕ੍ਰੀਨ ਘੁਮਾਓ"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"ਟਾਸਕਬਾਰ ਸਿੱਖਿਆ"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ਇੱਕ ਵਾਰ ਵਿੱਚ 2 ਐਪਾਂ ਵਰਤਣ ਲਈ, ਐਪ ਨੂੰ ਪਾਸੇ ਵੱਲ ਘਸੀਟੋ"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ਇੱਕੋ ਸਮੇਂ \'ਤੇ 2 ਐਪਾਂ ਵਰਤਣ ਲਈ, ਐਪ ਨੂੰ ਪਾਸੇ ਵੱਲ ਘਸੀਟੋ"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"ਟਾਸਕਬਾਰ ਦਿਖਾਉਣ ਲਈ ਥੋੜ੍ਹਾ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"ਤੁਹਾਡੇ ਨਿਯਮਬੱਧ ਕੰਮ ਦੇ ਆਧਾਰ \'ਤੇ ਐਪ ਸੁਝਾਅ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"ਟਾਸਕਬਾਰ ਨੂੰ ਸਵੈ-ਲੁਕਾਉਣ ਲਈ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਇਸ਼ਾਰਾ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ਟਾਸਕਬਾਰ ਨੂੰ ਦਿਖਾਇਆ ਗਿਆ"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ਟਾਸਕਬਾਰ ਨੂੰ ਲੁਕਾਇਆ ਗਿਆ"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"ਨੈਵੀਗੇਸ਼ਨ ਵਾਲੀ ਪੱਟੀ"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ਹਮੇਸ਼ਾਂ ਟਾਸਕਬਾਰ ਦਿਖਾਓ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"ਨੈਵੀਗੇਸ਼ਨ ਮੋਡ ਬਦਲੋ"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ਟਾਸਕਬਾਰ ਵਿਭਾਜਕ"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ਸਿਖਰਲੇ/ਖੱਬੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ਹੇਠਾਂ/ਸੱਜੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# ਹੋਰ ਐਪ ਦਿਖਾਓ।}one{# ਹੋਰ ਐਪ ਦਿਖਾਓ।}other{# ਹੋਰ ਐਪਾਂ ਦਿਖਾਓ।}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ਅਤੇ <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ਐਪ ਨੂੰ ਡੈਸਕਟਾਪ \'ਤੇ ਸ਼ਾਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ਰੱਦ ਕਰੋ"</string>
</resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index f09e412..7f0600f 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Włączono sugestie aplikacji"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestie aplikacji są wyłączone"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Przewidywana aplikacja: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pamiętaj, aby przesuwać palcem od samej krawędzi (prawej lub lewej)."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pamiętaj, aby przesuwać palcem od prawej lub lewej krawędzi do środka ekranu i podnieść palec."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Obróć urządzenie"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Obróć urządzenie, aby ukończyć samouczek nawigacji przy użyciu gestów"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pamiętaj, aby przesuwać palcem od samej krawędzi (prawej lub lewej)"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pamiętaj, aby przesuwać palcem od prawej lub lewej krawędzi do środka ekranu i podnieść palec"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Wiesz już, jak przesuwać palcem, aby przejść wstecz. Poćwicz teraz przełączanie aplikacji."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Gest przejścia wstecz został opanowany."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pamiętaj, aby nie przesuwać palcem zbyt blisko dolnej części ekranu."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Gest przejścia wstecz został opanowany"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pamiętaj, aby nie przesuwać palcem zbyt blisko dolnej części ekranu"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Czułość gestu cofania możesz zmienić w Ustawieniach"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Przesuń palcem, aby przejść wstecz"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Aby wrócić do ostatniego ekranu, przesuń palcem od lewej lub prawej krawędzi do środka ekranu."</string>
- <string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Aby wrócić do ostatniego ekranu, przesuń 2 palcami od lewej lub prawej krawędzi do środka ekranu."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Aby wrócić do poprzedniego ekranu, przesuń palcem od lewej lub prawej krawędzi do środka ekranu."</string>
+ <string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Aby wrócić do poprzedniego ekranu, przesuń 2 palcami od lewej lub prawej krawędzi do środka ekranu."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Przejście wstecz"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pamiętaj, aby przed podniesieniem palca nie było przerwy."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pamiętaj, aby przesuwać palcem prosto do góry."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Potrafisz już przejść na ekran główny. Teraz naucz się, jak wrócić do poprzedniego ekranu."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Gest przechodzenia na ekran główny został opanowany."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Przesuń palcem od lewej lub prawej krawędzi do środka ekranu"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pamiętaj, aby przed podniesieniem palca nie było przerwy"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pamiętaj, aby przesuwać palcem prosto do góry"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Gest przechodzenia na ekran główny został opanowany. Poćwicz teraz wracanie do poprzedniego ekranu."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Gest przechodzenia na ekran główny został opanowany"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Przesuń palcem, aby przejść na ekran główny"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Przesuń palcem od dołu ekranu. Ten gest zawsze powoduje przejście na ekran główny."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Przesuń 2 palcami od dołu ekranu. Ten gest zawsze powoduje przejście do ekranu głównego."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Otwórz ekran główny"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Aby wyświetlić ekran główny w dowolnym momencie, przesuń od dołu do góry ekranu"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Przytrzymaj okno dłużej, zanim podniesiesz palec."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pamiętaj, aby przesuwać palcem prosto do góry, a potem przerwać ruch."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Przejście na ekran główny"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Przesuń palcem z dołu ekranu w górę"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Brawo!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Przytrzymaj okno dłużej, zanim podniesiesz palec"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pamiętaj, aby przesuwać palcem prosto do góry, a potem przerwać ruch"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Wiesz już, jak używać gestów. Aby wyłączyć gesty, przejdź do Ustawień."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Gest przełączania aplikacji został opanowany."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Gest przełączania aplikacji został opanowany"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Przesuń palcem, aby przełączać aplikacje"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aby przełączać się między aplikacjami, przesuń palcem od dołu ekranu, przytrzymaj i puść."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aby przełączać się między aplikacjami, przesuń palcem od dołu do góry ekranu, przytrzymaj i puść."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Aby przełączać się między aplikacjami, przesuń 2 palcami od dołu ekranu, przytrzymaj i puść."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Przełączanie aplikacji"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Przełącz aplikację"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Przesuń palcem z dołu ekranu w górę, przytrzymaj i puść"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Brawo!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Wszystko gotowe"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotowe"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ustawienia"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"Udostępnij"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Zrzut ekranu"</string>
<string name="action_split" msgid="2098009717623550676">"Podziel"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Kliknij drugą aplikację, aby podzielić ekran"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Aby podzielić ekran, kliknij drugą aplikację"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Wyjdź z wyboru podzielonego ekranu"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Wybierz drugą aplikację, aby podzielić ekran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Nie możesz wykonać tego działania, bo nie zezwala na to aplikacja lub Twoja organizacja"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Pominąć samouczek nawigacji?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Obróć ekran"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Informacje o pasku aplikacji"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Przeciągnij aplikację w bok, aby używać 2 aplikacji naraz"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Przesuń palcem krótko w górę, aby wyświetlić pasek aplikacji"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Aby wyświetlić pasek aplikacji, przesuń palcem krótko w górę"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Otrzymuj sugestie aplikacji na podstawie rutyny"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Włącz nawigację przy użyciu gestów w Ustawieniach, aby automatycznie ukrywać pasek aplikacji"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Wykorzystaj potencjał paska aplikacji"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Pasek aplikacji widoczny"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Pasek aplikacji ukryty"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Pasek nawigacyjny"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Zawsze pokazuj pasek aplikacji"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Zmień tryb nawigacji"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Linia dzielenia paska aplikacji"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Przesuń w górny lewy róg"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Przesuń w dolny prawy róg"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Pokaż jeszcze # aplikację.}few{Pokaż jeszcze # aplikacje.}many{Pokaż jeszcze # aplikacji.}other{Pokaż jeszcze # aplikacji.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> i <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Dodaję aplikację do komputera"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Anuluj"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 2b287b3..791a127 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestões de apps ativadas"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As sugestões de apps estão desativadas"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Deslize rapidamente a partir da extremidade mais à direita ou mais à esquerda."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Deslize rapidamente a partir da extremidade esquerda ou direita até ao centro do ecrã e solte."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rode o dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rode o seu dispositivo para concluir o tutorial de navegação por gestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Deslize rapidamente a partir da extremidade mais à direita ou mais à esquerda"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Deslize rapidamente a partir da extremidade esquerda ou direita até ao centro do ecrã e solte"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Aprendeu a deslizar a partir da direita para retroceder. A seguir, saiba como alternar entre apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Concluiu o gesto para retroceder."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Garanta que não desliza rapidamente com o dedo demasiado perto da parte inferior do ecrã."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Concluiu o gesto para retroceder"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Garanta que não desliza rapidamente com o dedo demasiado perto da parte inferior do ecrã"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Altere a sensibilidade do gesto para voltar nas Definições."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Deslize rapidamente com o dedo para retroceder"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para voltar ao último ecrã, deslize rapidamente do limite esquerdo ou direito até ao centro do ecrã."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para voltar ao último ecrã, deslize rapidamente com 2 dedos a partir da extremidade esquerda ou direita até ao centro do ecrã."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Voltar"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Garanta que desliza rapidamente com o dedo a partir do limite inferior do ecrã."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Garanta que não faz uma pausa antes de soltar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Garanta que desliza rapidamente com o dedo para cima."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Concluiu o gesto para aceder ao ecrã principal. A seguir, saiba como retroceder."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Concluiu o gesto para aceder ao ecrã principal."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Deslize rapidamente a partir da extremidade esquerda ou direita para o meio do ecrã"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Deslize rapidamente com o dedo a partir do limite inferior do ecrã"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Não faça uma pausa antes de soltar"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Deslize rapidamente com o dedo para cima"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Concluiu o gesto para aceder ao ecrã principal. A seguir, saiba como retroceder."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Concluiu o gesto para aceder ao ecrã principal"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Deslize rapidamente com o dedo para aceder ao ecrã principal"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Deslize rapidamente para cima a partir da parte inferior. Este gesto abre sempre o ecrã principal."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Deslize rapidamente para cima com 2 dedos no fundo do ecrã. Este gesto abre sempre o ecrã principal."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Aceda ao ecrã principal"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para aceder ao ecrã principal em qualquer altura, deslize rapidamente de baixo para cima no seu ecrã"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Deslize rapidamente com o dedo a partir do limite inferior do ecrã."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Experimente premir a janela durante mais tempo antes de soltar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Garanta que desliza rapidamente com o dedo para cima e, em seguida, faz uma pausa."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Deslize rapidamente para cima a partir da parte inferior do ecrã"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Muito bem!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Deslize rapidamente com o dedo a partir do limite inferior do ecrã"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Experimente premir a janela durante mais tempo antes de soltar"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Garanta que desliza rapidamente com o dedo para cima e, em seguida, faz uma pausa"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Aprendeu a utilizar gestos. Para desativar os gestos, aceda às Definições."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Concluiu o gesto para alternar entre apps."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Concluiu o gesto para alternar entre apps"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Deslize rapidamente com o dedo para alternar entre apps"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para alternar entre apps, deslize para cima sem soltar a partir da parte inferior do ecrã e solte."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para mudar de app, deslize rapidamente para cima com 2 dedos sem soltar no fundo do ecrã e solte."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Mude de app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Deslize rapidamente para cima a partir da parte inferior do ecrã sem soltar e, em seguida, solte"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Muito bem!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Está tudo pronto"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Concluído"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Definições"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Fazer captura de ecrã"</string>
<string name="action_split" msgid="2098009717623550676">"Dividir"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Toque noutra app para usar o ecrã dividido"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Saia da seleção de ecrã dividido"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Escolher outra app para usar o ecrã dividido"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Esta ação não é permitida pela app ou a sua entidade."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorar o tutorial de navegação?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tarefas apresentada"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tarefas ocultada"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegação"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Mostr. sempre Barra de tarefas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Alterar modo de navegação"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor da Barra de tarefas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover para a parte superior esquerda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover para a part superior direita"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostrar mais # app.}other{Mostrar mais # apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> e <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"A adicionar a app ao computador"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancelar"</string>
</resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 4092c06..c943da5 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -23,7 +23,7 @@
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configurações de uso do app"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"Remover tudo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recentes"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Tarefa encerrada"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
@@ -44,39 +44,45 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"O recurso \"sugestões de apps\" está ativado"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"O recurso \"sugestões de apps\" está desativado"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App previsto: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Deslize da borda direita ou esquerda."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Deslize da borda direita ou esquerda até o meio da tela e solte."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Gire o dispositivo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Gire o dispositivo para concluir o tutorial da navegação por gestos"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Deslize da borda direita ou esquerda"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Deslize da borda direita ou esquerda até o meio da tela e solte"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Você aprendeu a deslizar da direita para voltar. A seguir, aprenda a trocar de app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Você concluiu o gesto para voltar."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Não deslize perto demais da parte inferior da tela."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Você concluiu o gesto para voltar"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Não deslize perto demais da parte inferior da tela"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Mude a sensibilidade do gesto de voltar nas configurações"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Deslize para voltar"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para voltar à tela anterior, deslize da borda esquerda ou direita até o meio da tela."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para voltar à tela anterior, deslize da borda esquerda ou direita até o meio da tela com dois dedos."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Voltar"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Deslize da borda inferior da tela para cima."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Não pare antes de soltar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Deslize para cima."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Você concluiu o gesto para acessar a tela inicial. A seguir, aprenda a voltar."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Você concluiu o gesto para acessar a tela inicial."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Volte"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Deslize da borda esquerda ou direita até o meio da tela"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Deslize da borda inferior da tela para cima"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Não pare antes de soltar"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Deslize para cima em linha reta"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Você concluiu o gesto para acessar a tela inicial. Agora, aprenda a voltar."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Você concluiu o gesto para acessar a tela inicial"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Deslizar para voltar à tela inicial"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Deslize de baixo para cima na tela. Esse gesto sempre leva você para a tela inicial."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Deslize de baixo para cima na tela com dois dedos. Esse gesto sempre leva você para a tela inicial."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ir para a página inicial"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para acessar sua tela inicial a qualquer momento, deslize de baixo para cima na tela"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Deslize da borda inferior da tela para cima."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Mantenha a janela pressionada por mais tempo antes de soltar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Deslize para cima e pare."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Vá para a página inicial"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Deslize de baixo para cima na tela"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Muito bem!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Deslize da borda inferior da tela para cima"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Mantenha a janela pressionada por mais tempo antes de soltar"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Deslize para cima e pare"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Você aprendeu. Para desativar os gestos, acesse as Configurações."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Você concluiu o gesto para trocar de app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Você concluiu o gesto para mudar de app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Deslizar para trocar de app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para mudar de app, deslize de baixo para cima, mantenha a tela pressionada por um tempo e solte."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para mudar de app, deslize de baixo para cima na tela com dois dedos, segure por um tempo e solte."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Alternar entre apps"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Mude de app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Deslize de baixo para cima na tela, segure e depois solte"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Muito bem!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tudo pronto"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Concluído"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configurações"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tentar novamente"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tente de novo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Muito bem!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Tudo pronto!"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Capturar tela"</string>
<string name="action_split" msgid="2098009717623550676">"Dividir"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Toque em outro app para usar a tela dividida"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Sair da seleção de tela dividida"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Escolha outro app para usar na tela dividida"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Essa ação não é permitida pelo app ou pela organização"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Pular o tutorial de navegação?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tarefas visível"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tarefas oculta"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegação"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Sempre mostrar a Barra de tarefas"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Mudar o modo de navegação"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Separador da Barra de tarefas"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover para cima/para a esquerda"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover para baixo/para a direita"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Mostrar mais # app.}one{Mostrar mais # app.}other{Mostrar mais # apps.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> e <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Adicionando app ao computador"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Cancelar"</string>
</resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 003b867..5db7859 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestiile de aplicații au fost activate"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestiile de aplicații au fost dezactivate"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicația estimată: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Glisează dinspre marginea dreaptă îndepărtată sau dinspre marginea stângă îndepărtată."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Glisează dinspre marginea dreaptă sau stângă spre mijlocul ecranului și eliberează."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ai învățat cum să glisezi din dreapta pentru a reveni. Acum află cum să comuți aplicațiile."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ai finalizat gestul „înapoi”."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nu glisa prea aproape de partea de jos a ecranului."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotește dispozitivul"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotește dispozitivul pentru a încheia tutorialul de navigare prin gesturi"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Glisează dinspre marginea dreaptă îndepărtată sau dinspre marginea stângă îndepărtată"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Glisează dinspre marginea dreaptă sau stângă spre mijlocul ecranului și eliberează"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ai învățat să revii la ecranul anterior glisând din dreapta. Acum învață să comuți între aplicații."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ai finalizat gestul „înapoi”"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Nu glisa prea aproape de partea de jos a ecranului"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Schimbă sensibilitatea gestului „Înapoi” accesând Setările"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Glisează pentru a reveni"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pentru a reveni la ultimul ecran, glisează de la marginea stângă sau dreaptă spre mijlocul ecranului."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Pentru a reveni la ultimul ecran, glisează cu două degete dinspre marginea stângă sau dreaptă spre mijlocul ecranului."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Înapoi"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Glisează în sus dinspre marginea de jos a ecranului."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nu întrerupe gestul înainte de a elibera."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Glisează direct în sus."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ai finalizat gestul „accesează ecranul de pornire”. Acum află cum să revii."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ai finalizat gestul „accesează ecranul de pornire”."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Glisează dinspre marginea stângă sau dreaptă până la jumătatea ecranului"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Glisează în sus dinspre marginea de jos a ecranului"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Nu întrerupe gestul înainte de a elibera"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Glisează direct în sus"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ai finalizat gestul „accesează ecranul de pornire”. În continuare, află cum să revii."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ai finalizat gestul „accesează ecranul de pornire”"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Glisează pentru a accesa ecranul de pornire"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Glisează în sus din partea de jos a ecranului. Cu acest gest accesezi mereu ecranul de pornire."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Glisează în sus cu două degete din partea de jos. Cu acest gest accesezi mereu ecranul de pornire."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Înapoi la ecranul de pornire"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Pentru a accesa oricând ecranul de pornire, glisează în sus din partea de jos a ecranului"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Glisează în sus dinspre marginea de jos a ecranului."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Încearcă să ții fereastra mai mult înainte s-o eliberezi."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Glisează direct în sus, apoi întrerupe."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ai învățat să folosești gesturi. Pentru a dezactiva gesturile, accesează Setările."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ai finalizat gestul „comută între aplicații”."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Glisează în sus din partea de jos a ecranului"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Excelent!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Glisează în sus dinspre marginea de jos a ecranului"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Încearcă să ții fereastra mai mult înainte s-o eliberezi"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Glisează direct în sus, apoi întrerupe"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ai învățat să folosești gesturi. Pentru a dezactiva gesturile, accesează setările."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ai finalizat gestul „comută între aplicații”"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Glisează pentru a comuta între aplicații"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ca să comuți între aplicații, glisează în sus din partea de jos a ecranului, așteaptă și eliberează."</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Ca să comuți între aplicații, glisează cu două degete de jos în sus, așteaptă și eliberează"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ca să comuți între aplicații, glisează de jos în sus, ține degetul pe ecran, apoi ridică-l."</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Ca să comuți între aplicații, glisează cu 2 degete de jos în sus, ține-le pe ecran, apoi ridică-le."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Comută între aplicații"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Glisează în sus din partea de jos a ecranului, ține apăsat, apoi eliberează"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Felicitări!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gata"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gata"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Setări"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bravo!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorialul <xliff:g id="CURRENT">%1$d</xliff:g> / <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Gata!"</string>
- <string name="allset_hint" msgid="459504134589971527">"Glisați în sus pentru a accesa pagina principală"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Glisează în sus pentru a accesa ecranul principal"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Atinge butonul ecran de pornire ca să accesezi ecranul de pornire"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"Ești gata să folosești <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"dispozitivul"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Captură de ecran"</string>
<string name="action_split" msgid="2098009717623550676">"Împărțit"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Atinge altă aplicație pentru ecranul împărțit"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Ieși din selecția cu ecran împărțit"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Alege altă aplicație pentru ecranul împărțit"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Această acțiune nu este permisă de aplicație sau de organizația ta"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Omiți tutorialul de navigare?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Bara de activități este afișată"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Bara de activități este ascunsă"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Bară de navigare"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Afișează întotdeauna bara de activități"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Schimbă modul de navigare"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Separator pentru bara de activități"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mută în stânga sus"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mută în dreapta jos"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Afișează încă # aplicație}few{Afișează încă # aplicații}other{Afișează încă # de aplicații}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> și <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Se adaugă aplicația pe computer"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Anulează"</string>
</resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 166fe7c..a11175e 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Функция \"Рекомендуемые приложения\" включена."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функция \"Рекомендуемые приложения\" отключена."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Рекомендуемое приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Проведите справа налево или слева направо от самого края экрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Проведите от правого или левого края экрана до середины дисплея и отпустите палец."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Поверните устройство"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Чтобы перейти к руководству по жестам, нужно повернуть устройство."</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Проведите справа налево или слева направо от самого края экрана."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Проведите от правого или левого края экрана к центру и отпустите палец."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Теперь вы знаете, как вернуться, проведя справа налево. Далее мы расскажем, как переключаться между приложениями."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Вы выполнили жест для перехода назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Проведите пальцем не слишком близко к нижнему краю экрана."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Вы выполнили жест для возврата на предыдущий экран."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Проведите пальцем не слишком близко к нижнему краю экрана."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Уровень чувствительности можно изменить в настройках."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Возврат к предыдущему экрану"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Чтобы вернуться к предыдущему экрану, проведите от левого или правого края дисплея к центру."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Чтобы вернуться на предыдущий экран, проведите двумя пальцами от левого или правого края экрана к центру."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Как вернуться к предыдущему экрану"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Проведите снизу вверх от самого края экрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не приостанавливайтесь перед тем, как отпустить палец."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Проведите по экрану ровно вверх."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Вы выполнили жест для перехода на главный экран. Далее мы расскажем, как вернуться назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Вы выполнили жест для перехода на главный экран."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Проведите от левого или правого края экрана к центру."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Проведите снизу вверх от самого края экрана."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Прежде чем отпустить палец, не задерживайте его в одной точке."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Проведите по экрану ровно вверх."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Вы выполнили жест для перехода на главный экран. Далее мы расскажем, как возвращаться назад."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Вы выполнили жест для перехода на главный экран."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Переход на главный экран"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Проведите вверх от нижнего края дисплея. Этот жест открывает главный экран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Проведите двумя пальцами вверх от нижнего края экрана. Этот жест открывает главный экран."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Переход на главный экран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Чтобы открыть главный экран, проведите снизу вверх по экрану."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Проведите снизу вверх от самого края экрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Прежде чем отпускать палец, задержите его на дисплее подольше."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Проведите по экрану ровно вверх, а затем задержите палец в крайнем положении."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Как перейти на главный экран"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Проведите вверх от нижнего края экрана."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"У вас получилось!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Проведите снизу вверх от самого края экрана."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Прежде чем отпустить палец, задержите его на экране немного дольше."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Проведите по экрану ровно вверх и задержите палец в конце."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Теперь вы знаете, как использовать жесты. Чтобы отключить их, перейдите в настройки."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Вы выполнили жест для переключения между приложениями."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Вы выполнили жест для переключения между приложениями."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Переключение между приложениями"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Чтобы переключиться между приложениями‚ проведите по экрану снизу вверх, задержите палец, а затем отпустите."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Чтобы сменить приложение, проведите двумя пальцами снизу вверх, задержите пальцы, а затем отпустите."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Как переключаться между приложениями"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Проведите вверх от нижнего края экрана, задержите палец в одной точке и отпустите."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Отлично!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Настройки"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="action_split" msgid="2098009717623550676">"Разделить"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Для разделения экрана выберите другое приложение."</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Выйдите из режима разделения экрана."</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Выберите другое приложение для разделения экрана."</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Это действие заблокировано приложением или организацией."</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропустить руководство по жестам?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Панель задач показана"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Панель задач скрыта"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Панель навигации"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Всегда показывать панель задач"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Изменить режим навигации"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Разделитель панели задач"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Переместить вверх или влево"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Переместить вниз или вправо"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Показать ещё # приложение}one{Показать ещё # приложение}few{Показать ещё # приложения}many{Показать ещё # приложений}other{Показать ещё # приложения}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> и <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Добавление приложения на компьютер"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Отмена"</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 1b850ef..3722b2f 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"යෙදුම් යෝජනා සබලිතයි"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"යෙදුම් යෝජනා අබල කර ඇත"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"පුරෝකථනය කළ යෙදුම: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ඔබ ඈත දකුණු හෝ ඈත වම් දාරයේ ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ඔබ දකුණු හෝ වම් දාරයේ සිට තිරයේ මැදට ස්වයිප් කර අත හරින බව සහතික කර ගන්න."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"ඔබේ උපාංගය කරකවන්න"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"අභින සංචාලන නිබන්ධනය සම්පූර්ණ කිරීම සඳහා ඔබේ උපාංගය කරකවන්න"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ඔබ ඈත දකුණු හෝ ඈත වම් දාරයේ සිට ස්වයිප් කරන බව සහතික කර ගන්න"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ඔබ දකුණු හෝ වම් දාරයේ සිට තිරයේ මැදට ස්වයිප් කර අත හරින බව සහතික කර ගන්න"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ආපසු යාමට දකුණේ සිට ස්වයිප් කරන්නේ කෙසේදැයි ඔබ දැන ගත්තේය. ඊළඟට, යෙදුම් මාරු කරන ආකාරය දැන ගන්න."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ඔබ ආපසු යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ඔබ තිරයේ පහළට ඉතාම සමීපව ස්වයිප් නොකරන බවට සහතික කර ගන්න."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"ඔබ ආපසු යාමේ ඉංගිතය සම්පූර්ණ කළා"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ඔබ තිරයේ පහළට ඉතාම සමීපව ස්වයිප් නොකරන බවට සහතික කර ගන්න"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ආපසු ඉංගිතයෙහි සංවේදීතාව වෙනස් කිරීමට, සැකසීම් වෙත යන්න"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ආපසු යාමට ස්වයිප් කරන්න"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"අවසාන තිරයට ආපසු යාමට, වම් හෝ දකුණු දාරයෙන් තිරයේ මැදට ස්වයිප් කරන්න."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"අවසාන තිරයට ආපසු යාමට, වම් හෝ දකුණු දාරයෙන් තිරයේ මැදට ඇඟිලි 2කින් ස්වයිප් කරන්න."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ආපසු යන්න"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"යාමට ඉඩ හැරීමට පෙර ඔබ විරාමයක් නොගන්නා බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ඔබ කෙලින්ම ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි. ඊළඟට, ආපසු යන ආකාරය දැන ගන්න."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"වම් හෝ දකුණු කෙළවරේ සිට තිරයේ මැදට ස්වයිප් කරන්න"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"යාමට ඉඩ හැරීමට පෙර ඔබ විරාමයක් නොගන්නා බව සහතික කර ගන්න"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ඔබ කෙලින්ම ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කළා. මීළඟට, ආපසු යන ආකාරය දැන ගන්න."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කළා"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"මුල් පිටුවට යාමට ස්වයිප් කරන්න"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ඔබගේ තිරයේ පහළින් උඩට ස්වයිප් කරන්න.මෙම ඉංගිතය සැම විටම ඔබව මුල් තිරයට ගෙන යයි."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"තිරයේ පහළම සිට ඇඟිලි 2කින් ඉහළට ස්වයිප් කරන්න. මෙම ඉංගිතය සැම විටම ඔබව මුල් තිරයට ගෙන යයි."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"මුල් පිටුවට යන්න"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ඕනෑම වේලාවක දී ඔබේ මුල් තිරයට යාම සඳහා, ඔබේ තිරයෙහි පහළ සිට ඉහළට ස්වයිප් කරන්න"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"මුදා හැරීමට පෙර කවුළුව වැඩි වේලාවක් රඳවා තබා ගැනීමට උත්සාහ කරන්න."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ඔබ කෙලින්ම ඉහළට ස්වයිප් කර, අනතුරුව විරාම කරන බව සහතික කර ගන්න."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ඔබේ තිරයේ පහළ සිට උඩට ස්වයිප් කරන්න"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"අනර්ඝ වැඩක්!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"මුදා හැරීමට පෙර කවුළුව වැඩි වේලාවක් රඳවා ගැනීමට උත්සාහ කරන්න"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ඔබ කෙළින්ම ඉහළට ස්වයිප් කර, පසුව විරාම කරන බව සහතික කර ගන්න"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ඔබ ඉංගිත භාවිත කරන ආකාරය දැන ගෙන ඇත. ඉංගිත ක්රියාවිරහිත කිරීමට, සැකසීම් වෙත යන්න."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ඔබ යෙදුම් මාරු කිරීමේ ඉංගිතය සම්පූර්ණ කර ඇත."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ඔබ යෙදුම් මාරු කිරීමේ ඉංගිතය සම්පූර්ණ කළා"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"යෙදුම් මාරු කිරීමට ස්වයිප් කරන්න"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"යෙදුම් අතර මාරු වීමට, ඔබගේ තිරයේ පහළම සිට උඩට ස්වයිප් කර, අල්ලාගෙන සිට, අනතුරුව මුදා හරින්න."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"යෙදුම් අතර මාරු වීමට, ඔබගේ තිරයේ පහළම සිට උඩට ඇඟිලි 2කින් ස්වයිප් කර, අල්ලාගෙන සිට, අනතුරුව මුදා හරින්න."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"යෙදුම් මාරු කරන්න"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ඔබේ තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න, රඳවා ගෙන සිට, පසුව මුදා හරින්න"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"හොඳින් කළා!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"සියල්ල සකසා ඇත"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"නිමයි"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"සැකසීම්"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"තිර රුව"</string>
<string name="action_split" msgid="2098009717623550676">"බෙදන්න"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"බෙදුම් තිරය භාවිතා කිරීමට තවත් යෙදුමක් තට්ටු කරන්න"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"බෙදීම් තිර තේරීමෙන් පිටවන්න"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"බෙදීම් තිරය භාවිතා කිරීමට වෙනත් යෙදුමක් තෝරා ගන්න"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"මෙම ක්රියාව යෙදුම හෝ ඔබේ සංවිධානය මගින් ඉඩ නොදේ"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"නිබන්ධනය සංචාලනය මඟ හරින්නද?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"කාර්ය තීරුව පෙන්වා ඇත"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"කාර්ය තීරුව සඟවා ඇත"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"සංචලන තීරුව"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"සෑම විටම කාර්ය තීරුව පෙන්වන්න"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"සංචාලන ප්රකාරය වෙනස් කරන්න"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"කාර්ය තීරු බෙදනය"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ඉහළ/වම වෙත ගෙන යන්න"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"පහළ/දකුණ වෙත ගෙන යන්න"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{තවත් # යෙදුමක් පෙන්වන්න.}one{තවත් යෙදුම් #ක් පෙන්වන්න.}other{තවත් යෙදුම් #ක් පෙන්වන්න.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> සහ <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ඩෙස්ක්ටොප් වෙත යෙදුම එක් කිරීම"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"අවලංගු කරන්න"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index b2dff2e..aee281c 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikácií zapnuté"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikácií vypnuté"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predpovedaná aplikácia: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Musíte potiahnuť úplne z pravého alebo ľavého okraja."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Musíte potiahnuť z pravého alebo ľavého okraja do stredu obrazovky a potom uvoľniť."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Otočte zariadenie"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Otočte zariadenie a dokončite tak návod, ako navigovať gestami"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Musíte potiahnuť úplne z pravého alebo ľavého okraja"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Musíte potiahnuť z pravého alebo ľavého okraja do stredu obrazovky a potom uvoľniť"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste sa prejsť späť potiahnutím sprava. V ďalšom kroku sa naučíte prepínať aplikácie."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dokončili ste gesto na prechod späť."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nesmiete potiahnuť príliš blízko dolnej časti obrazovky."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Dokončili ste gesto na prechod späť"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Nesmiete potiahnuť príliš blízko dolnej časti obrazovky"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Ak chcete zmeniť citlivosť gesta Späť, prejdite do Nastavení"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Prechod späť potiahnutím"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Na poslednú obrazovku prejdete potiahnutím z ľavého alebo pravého okraja do stredu obrazovky."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Na poslednú obrazovku sa vrátite potiahnutím dvoma prstami z ľavého alebo pravého okraja do stredu obrazovky."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Prechod späť"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Musíte potiahnuť nahor z dolného okraja obrazovky."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pred uvoľnením nesmiete zastať."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Musíte potiahnuť priamo hore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dokončili ste gesto na prechod na plochu. V ďalšom kroku sa naučíte, ako sa vrátiť späť."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dokončili ste gesto na prechod na plochu."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Potiahnite z ľavého alebo pravého okraja do stredu obrazovky"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Musíte potiahnuť nahor z dolného okraja obrazovky"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pred uvoľnením nesmiete zastať"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Musíte potiahnuť priamo nahor"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Dokončili ste gesto prechodu na plochu. Teraz sa naučíte, ako sa vrátiť späť."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Dokončili ste gesto prechodu na plochu"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Prechod na plochu potiahnutím"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Potiahnite nahor zdola obrazovky. Týmto gestom sa vždy vrátite na plochu."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Postiahnite dvoma prstami z dolnej časti obrazovky. Týmto gestom sa vždy vrátite na plochu."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Prejdenie na plochu"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Na plochu môžete kedykoľvek prejsť potiahnutím nahor z dolnej časti obrazovky"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Musíte potiahnuť nahor z dolného okraja obrazovky."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Skúste okno pred uvoľnením podržať dlhšie."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Musite potiahnuť priamo hore a potom zastať."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Prechod na plochu"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Potiahnite z dolnej časti obrazovky nahor"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Skvelé!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Musíte potiahnuť nahor z dolného okraja obrazovky"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Skúste okno pred uvoľnením podržať dlhšie"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Musite potiahnuť priamo nahor a potom zastať"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste sa používať gestá. Gestá môžete vypnúť v nastaveniach."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dokončili ste gesto na prepnutie aplikácií."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Dokončili ste gesto na prepnutie aplikácií"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prepínanie aplikácií potiahnutím"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aplikácie môžete prepínať potiahnutím obrazovky zdola nahor, pridržaním a následným uvoľnením."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Aplikácie prepnete potiahnutím dvoma prstami z dolnej časti obrazovky, ich pridržaním a uvoľnením."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Prepnutie aplikácií"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Potiahnite nahor z dolného okraja obrazovky, pridržte a uvoľnite"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Výborne"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Hotovo"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hotovo"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavenia"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"Zdieľať"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snímka obrazovky"</string>
<string name="action_split" msgid="2098009717623550676">"Rozdeliť"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"Rozdelenú obrazovku spustíte klep. na inú aplik."</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"Obrazovku rozdelíte klepnutím na inú aplikáciu"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Ukončite výber rozdelenej obrazovky"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Na použitie rozd. obrazovky vyberte inú aplikáciu"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikácia alebo vaša organizácia túto akciu nepovoľuje"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Chcete preskočiť návod na navigáciu?"</string>
@@ -97,7 +104,7 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskočiť"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Otočiť obrazovku"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Panel vzdelávacích aplikácií"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Ak chcete použ. dve aplikácie naraz, presuňte aplik. nabok"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Ak chcete použiť dve aplikácie naraz, presuňte aplikáciu nabok"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"Panel aplikácií zobrazíte pomalým potiahnutím nahor"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Získavajte návrhy aplikácií na základe svojich zvykov"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Ak chcete, aby sa panel aplikácií autom. skrýval, zapnite v Nastaveniach navigáciu gestami"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Panel aplikácií je zobrazený"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Panel aplikácií je skrytý"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigačný panel"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Zobrazovať panel aplikácií"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Zmeniť režim navigácie"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Rozdeľovač panela aplikácií"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Presunúť hore alebo doľava"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Presunúť dole alebo doprava"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Zobraziť # ďalšiu aplikáciu.}few{Zobraziť # ďalšie aplikácie.}many{Show # more apps.}other{Zobraziť # ďalších aplikácií.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> a <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Pridanie aplikácie na plochu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Zrušiť"</string>
</resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index e0f1f92..4787f04 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlogi aplikacij so omogočeni."</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlogi aplikacij so onemogočeni."</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predvidena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pazite, da povlečete s skrajno desnega ali skrajno levega roba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pazite, da povlečete z desnega ali levega roba do sredine zaslona in dvignete prst."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zasukajte napravo"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Zasukajte napravo, če si želite ogledati vadnico za krmarjenje s potezami"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Pazite, da povlečete s skrajno desnega ali skrajno levega roba."</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Pazite, da povlečete z desnega ali levega roba do sredine zaslona in dvignete prst."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste se, kako povlečete z desne za vrnitev. Zdaj se naučite preklapljanja med aplikacijami."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Izvedli ste potezo za pomik nazaj."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pazite, da ne povlečete preblizu dna zaslona."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Izvedli ste potezo za pomik nazaj."</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Pazite, da ne povlečete preblizu dna zaslona."</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Občutljivost poteze za nazaj lahko spremenite v nastavitvah."</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Povlecite za vrnitev"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Če se želite vrniti na prejšnji zaslon, povlecite z levega ali desnega roba do sredine zaslona."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Če se želite vrniti na zadnji prikazani zaslon, z dvema prstoma povlecite z levega ali desnega roba do sredine zaslona."</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Nazaj"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pazite, da ne zaustavite prsta, preden ga dvignete."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pazite, da povlečete naravnost navzgor."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Izvedli ste potezo za pomik na začetni zaslon. Zdaj se naučite, kako se pomaknete nazaj."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Izvedli ste potezo za pomik na začetni zaslon."</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Pomik nazaj"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Povlecite z levega ali desnega roba do sredine zaslona."</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Pazite, da ne zaustavite prsta, preden ga dvignete."</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Pazite, da povlečete naravnost navzgor."</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Izvedli ste potezo za pomik na začetni zaslon. Zdaj se naučite, kako se pomaknete nazaj."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Izvedli ste potezo za pomik na začetni zaslon."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Povlecite za pomik na začetni zaslon"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Z dna zaslona s prstom povlecite navzgor. S to potezo lahko vedno odprete začetni zaslon."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Z dvema prstoma povlecite navzgor z dna zaslona. S to potezo lahko vedno odprete začetni zaslon."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Pomik na začetni zaslon"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Za pomik na začetni zaslon lahko kadar koli povlečete navzgor z dna zaslona."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Poskusite okno pridržati dalj časa, preden ga izpustite."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pazite, da povlečete naravnost navzgor in nato zaustavite prst."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Z dna zaslona s prstom povlecite navzgor."</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Odlično!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Poskusite okno pridržati dalj časa, preden ga izpustite."</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Pazite, da povlečete naravnost navzgor in nato zaustavite prst."</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste se uporabljati poteze. Poteze lahko izklopite v nastavitvah."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Izvedli ste potezo za preklapljanje med aplikacijami."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Izvedli ste potezo za preklapljanje med aplikacijami."</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Povlecite za preklapljanje med aplikacijami"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za preklapljanje med aplikacijami povlecite navzgor z dna zaslona, pridržite in nato izpustite."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Za preklop med aplikacijami z dvema prstoma povlecite navzgor z dna zaslona, pridržite in spustite."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Preklop aplikacij"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Povlecite navzgor z dna zaslona, pridržite, nato izpustite."</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Odlično!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Zdaj znate"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Končano"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavitve"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Posnetek zaslona"</string>
<string name="action_split" msgid="2098009717623550676">"Razdeli"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Za razdeljeni zaslon se dotaknite še 1 aplikacije"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Zapri izbiro razdeljenega zaslona"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Izberite drugo aplikacijo za uporabo razdeljenega zaslona."</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ali vaša organizacija ne dovoljuje tega dejanja"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite preskočiti vadnico za krmarjenje?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Sukanje zaslona"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Poučni nasveti o opravilni vrstici"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Povlecite aplikacijo na stran za uporabo 2 aplikacij hkrati."</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Počasi povlecite navzgor za prikaz opravilne vrstice."</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Počasi povlecite navzgor za prikaz opravilne vrstice"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Prejemajte predloge aplikacij na podlagi svojih navad."</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"V nastavitvah vklopite krmarjenje s potezami, da se bo opravilna vrstica samodejno skrila."</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Naredite več z opravilno vrstico"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Opravilna vrstica je prikazana"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Opravilna vrstica je skrita"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Vrstica za krmarjenje"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Stalen prikaz opravilne vrstice"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Spreminjanje načina navigacije"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Razdelilnik opravilne vrstice"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premakni na vrh/levo"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premakni na dno/desno"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Pokaži še # aplikacijo.}one{Pokaži še # aplikacijo.}two{Pokaži še # aplikaciji.}few{Pokaži še # aplikacije.}other{Pokaži še # aplikacij.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> in <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Dodajanje aplikacije na namizje"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Prekliči"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index c0d550b..a9e8b94 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Aplikacionet e sugjeruara janë aktivizuar"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugjerimet e aplikacioneve janë çaktivizuar"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikacioni i parashikuar: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Sigurohu që të rrëshqasësh shpejt nga skaji më i djathtë ose më i majtë."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Sigurohu që të rrëshqasësh shpejt nga skaji i djathtë ose i majtë drejt mesit të ekranit dhe lëshoje."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rrotullo pajisjen"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rrotullo pajisjen për të përfunduar udhëzuesin e navigimit me gjeste"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Sigurohu që të rrëshqasësh shpejt nga skaji më i djathtë ose më i majtë"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Sigurohu që të rrëshqasësh shpejt nga skaji i djathtë ose i majtë drejt mesit të ekranit dhe lëshoje"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ke mësuar si të rrëshqasësh shpejt nga e djathta për t\'u kthyer prapa. Në vijim do të mësosh se si t\'i ndërrosh aplikacionet."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"E ke përfunduar gjestin e kthimit prapa."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Sigurohu që të mos rrëshqasësh shumë afër fundit të ekranit."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"E ke përfunduar gjestin e kthimit prapa"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Sigurohu që të mos rrëshqasësh shpejt shumë afër pjesës së poshtme të ekranit"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Për të ndryshuar ndjeshmërinë e gjestit të kthimit prapa, shko te \"Cilësimet\""</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Rrëshqit shpejt për t\'u kthyer prapa"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Për t\'u kthyer prapa tek ekrani i fundit, rrëshqit shpejt nga skaji i majtë ose i djathtë drejt mesit të ekranit"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Për t\'u kthyer prapa tek ekrani i fundit, rrëshqit shpejt me 2 gishta nga skaji i majtë ose i djathtë drejt mesit të ekranit."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Kthehu prapa"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Sigurohu që të mos ndalosh para se ta lëshosh."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Sigurohu që të rrëshqasësh shpejt drejt lart."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"E ke përfunduar gjestin e kalimit tek ekrani bazë. Në vijim do të mësosh si të kthehesh prapa."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"E ke përfunduar gjestin e kalimit tek ekrani bazë."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Rrëshqit shpejt nga skaji i majtë ose i djathtë drejt mesit të ekranit"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Sigurohu që të mos ndalosh para se ta lëshosh"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Sigurohu që të rrëshqasësh shpejt drejt lart"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"E ke përfunduar gjestin e kalimit tek ekrani bazë. Në vijim, mëso si të kthehesh prapa."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"E ke përfunduar gjestin e kalimit tek ekrani bazë"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Rrëshqit shpejt për të kaluar tek ekrani bazë"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Rrëshqit shpejt lart nga fundi i ekranit tënd. Ky gjest të dërgon gjithmonë tek ekrani bazë."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Rrëshqit shpejt lart me 2 gishta nga fundi i ekranit. Ky gjest të dërgon gjithmonë tek ekrani bazë."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Shko tek ekrani bazë"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Për të shkuar tek ekrani bazë në çdo kohë, rrëshqit shpejt lart nga fundi i ekranit"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Provo ta mbash shtypur dritaren për një kohë më të gjatë para se ta lëshosh."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sigurohu që të rrëshqasësh shpejt drejt lart dhe më pas ndalo."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Rrëshqit shpejt lart nga pjesa e poshtme e ekranit"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Punë e shkëlqyer!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Provo ta mbash shtypur dritaren për një kohë më të gjatë para se ta lëshosh"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Sigurohu që të rrëshqasësh shpejt drejt lart dhe më pas ndalo"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ke mësuar si të përdorësh gjestet. Për t\'i çaktivizuar gjestet, shko te \"Cilësimet\"."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"E ke përfunduar gjestin e ndërrimit të aplikacioneve."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"E ke përfunduar gjestin e ndërrimit të aplikacioneve"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Rrëshqit shpejt për të ndërruar aplikacionet"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Për të ndërruar mes aplikacioneve, rrëshqit shpejt lart nga fundi i ekranit tënd, mbaj dhe pastaj lësho."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Për të ndërruar mes aplikacioneve, rrëshqit lart me 2 gishta nga fundi i ekranit, mbaje dhe lëshoje."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Ndërro aplikacionet"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Rrëshqit shpejt lart nga fundi i ekranit, mbaje të shtypur dhe më pas lëshoje"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Shumë mirë!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Plotësisht gati"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"U krye"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Cilësimet"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Plotësisht gati!"</string>
<string name="allset_hint" msgid="459504134589971527">"Rrëshqit shpejt lart për të shkuar në ekranin bazë"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Trokit te butoni \"kreu\" për të shkuar tek ekrani bazë"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Je gati që të fillosh të përdorësh <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Je gati që të fillosh ta përdorësh këtë <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"pajisje"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Cilësimet e navigimit të sistemit"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Ndaj"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Pamja e ekranit"</string>
<string name="action_split" msgid="2098009717623550676">"Ndaj"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Trokit një apl. tjetër; përdor ekranin e ndarë"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Dil nga zgjedhja e ekranit të ndarë"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Zgjidh një aplikacion tjetër për të përdorur ekranin e ndarë"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ky veprim nuk lejohet nga aplikacioni ose organizata jote"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Të kapërcehet udhëzuesi i navigimit?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Shiriti i detyrave i shfaqur"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Shiriti i detyrave i fshehur"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Shiriti i navigimit"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Shfaq gjithmonë shiritin e detyrave"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Ndrysho modalitetin e navigimit"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Ndarësi i shiritit të detyrave"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Lëviz në krye/majtas"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Lëviz në fund/djathtas"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Shfaq # aplikacion tjetër.}other{Shfaq # aplikacione të tjera.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> dhe <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Shtimi i aplikacionit te desktopi"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Anulo"</string>
</resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 1780283..da057d8 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлози апликација су омогућени"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлози апликација су онемогућени"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвиђамо апликацију: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Обавезно превуците од саме десне или леве ивице."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Обавезно превуците од десне или леве ивице до средине екрана и отпустите."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Ротирајте уређај"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ротирајте уређај да бисте довршили водич за навигацију помоћу покрета"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Обавезно превуците од саме десне или леве ивице"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Обавезно превуците од десне или леве ивице до средине екрана и отпустите"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научили сте како да превлачите здесна да бисте се вратили уназад. Сада научите да замените апликације."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Довршили сте покрет за повратак."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Никако не превлачите превише близу дна екрана."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Довршили сте покрет за повратак"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Никако не превлачите превише близу дна екрана"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Осетљивост пок. за назад можете да промените у Подешавањима"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Превуците да бисте се вратили уназад"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Да бисте се вратили на последњи екран, превуците од леве или десне ивице до средине екрана."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Да бисте се вратили на последњи екран, превуците помоћу два прста од леве или десне ивице до средине екрана."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Назад"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Обавезно превуците нагоре од доње ивице екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Никако не стајте пре отпуштања."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Обавезно превуците право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Довршили сте покрет за повратак на почетну страницу. Сада сазнајте како да се вратите."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Довршили сте покрет за повратак на почетну страницу."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Превуците од леве или десне ивице до средине екрана"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Обавезно превуците нагоре од доње ивице екрана"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Никако не стајте пре отпуштања"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Обавезно превуците право нагоре"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Довршили сте покрет за повратак на почетну страницу. Сада сазнајте како да се вратите."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Довршили сте покрет за повратак на почетну страницу."</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Превуците да бисте отишли на почетну страницу"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Превуците нагоре од дна екрана. Овај покрет вас увек води на почетни екран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Превуците помоћу два прста нагоре од дна екрана. Овим покретом увек отварате почетни екран."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Идите на почетни екран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Да бисте отишли на почетни екран у било ком тренутку, превуците нагоре од дна екрана."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Обавезно превуците нагоре од доње ивице екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Пробајте да држите прозор дуже пре отпуштања."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Обавезно превуците право нагоре, па застаните."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Превуците нагоре са доњег дела екрана"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Одлично!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Обавезно превуците нагоре од доње ивице екрана"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Пробајте да држите прозор дуже пре отпуштања"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Обавезно превуците право нагоре, па застаните"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Научили сте како да користите покрете. Да бисте искључили покрете, идите на подешавања."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Довршили сте покрет за промену апликација."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Довршили сте покрет за промену апликација"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Превуците да бисте заменили апликације"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За прелазак са једне апликације на другу превуците нагоре од дна екрана, задржите, па пустите."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"За прелазак између апликација превуците помоћу два прста нагоре од дна екрана, задржите, па пустите."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Пређите на другу апликацију"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Превуците нагоре од дна екрана, задржите, па пустите"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Одлично!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"То је то"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Подешавања"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Снимак екрана"</string>
<string name="action_split" msgid="2098009717623550676">"Подели"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Додирните другу апликацију за подељени екран"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Излазак из бирања подељеног екрана"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Одаберите другу апликацију за подељени екран"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Апликација или организација не дозвољавају ову радњу"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Желите да прескочите водич за кретање?"</string>
@@ -98,7 +105,7 @@
<string name="accessibility_rotate_button" msgid="4771825231336502943">"Ротирајте екран"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Упутства на траци задатака"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Превуците на страну да бисте користили 2 апликације одједном"</string>
- <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Накратко превуците нагоре да бисте приказали траку задатака"</string>
+ <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Споро превуците нагоре да бисте приказали траку задатака"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Добијајте предлоге апликација на основу рутине"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"Укључите навигацију помоћу покрета у Подешавањима ради аутоматског скривања траке задатака"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"Урадите више помоћу траке задатака"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Трака задатака је приказана"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Трака задатака је скривена"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Трака за навигацију"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Увек приказуј траку задатака"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Промени режим навигације"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Разделник траке задатака"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Премести горе лево"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Премести доле десно"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Прикажи још # апликацију.}one{Прикажи још # апликацију.}few{Прикажи још # апликације.}other{Прикажи још # апликација.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> и <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Додаје се апликација на радну поврршину"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Откажи"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 5e84675..31853f9 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -21,7 +21,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fäst"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
- <string name="recents_empty_message" msgid="7040467240571714191">"Listan med de senaste åtgärderna är tom"</string>
+ <string name="recents_empty_message" msgid="7040467240571714191">"Listan är tom"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Senaste apparna"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appförslag har aktiverats"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appförslag har inaktiverats"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Appförslag: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Se till att du sveper ända från högerkanten eller vänsterkanten."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Se till att du sveper från den högra eller vänstra kanten till mitten av skärmen och sedan släpper."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Rotera enheten"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Rotera enheten för att slutföra guiden för navigering med rörelser"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Se till att du sveper ända från högerkanten eller vänsterkanten"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Se till att du sveper från den högra eller vänstra kanten till mitten av skärmen och sedan släpper"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Nu kan du svepa från höger för att gå tillbaka. Nu ska du få lära dig hur du byter mellan appar."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du är klar med rörelsen för att gå tillbaka."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Se till att du inte sveper för nära skärmens nederkant."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Du är klar med rörelsen för att gå tillbaka"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Se till att du inte sveper för nära skärmens nederkant"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Öppna inställningarna om du vill ändra rörelsens känslighet"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Svep för att återgå"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Återgå till den senaste skärmen genom att svepa från skärmens vänster- eller högerkant till mitten."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Gå tillbaka till den senaste skärmen genom att med två fingrar svepa mot mitten av skärmen från vänster eller höger kant."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Tillbaka"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Se till att du sveper från nederkanten på skärmen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Se till att du sveper i en jämn rörelse innan du släpper."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Se till att du sveper rakt uppåt."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du är klar med rörelsen för att öppna startskärmen. Nu ska du få lära dig hur du går tillbaka."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du är klar med rörelsen för att öppna startskärmen."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Svep från den högra eller vänstra kanten till mitten av skärmen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Se till att du sveper uppåt från nederkanten av skärmen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Se till att du sveper i en jämn rörelse innan du släpper"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Se till att du sveper rakt uppåt"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Du är klar med rörelsen för att öppna startskärmen. Nu ska du få lära dig hur du går tillbaka."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Du är klar med rörelsen för att öppna startskärmen"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Svep för att öppna startskärmen"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Svep uppåt från skärmens nederkant. Du kan alltid återgå till startskärmen med den här rörelsen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Svep uppåt med två fingrar från skärmens nederkant. Så kommer du alltid tillbaka till startskärmen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Öppna startskärmen"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Öppna startskärmen när som helst genom att svepa uppåt från skärmens nederkant"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Se till att du sveper från nederkanten på skärmen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Testa att trycka längre på fönstret innan du släpper."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Se till att du sveper rakt uppåt och sedan pausar."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Svep uppåt från skärmens nederkant"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Bra jobbat!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Se till att du sveper uppåt från nederkanten av skärmen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Testa att trycka längre på fönstret innan du släpper"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Se till att du sveper rakt uppåt och sedan pausar"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lärt dig hur du använder rörelser. Om du vill inaktivera rörelser öppnar du inställningarna."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du är klar med rörelsen för att byta mellan appar."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Du är klar med rörelsen för att byta mellan appar"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Svep för att byta mellan appar"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Byt mellan appar genom att svepa uppåt från skärmens nederkant. Håll fingret nedtryckt och släpp."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Byta mellan appar: Svep uppåt med två fingrar från skärmens nederkant, håll kvar och släpp sedan."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Byt app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Svep uppåt från skärmens nederkant. Håll fingret nedtryckt och släpp sedan"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Bra gjort!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Klart"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klar"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Inställningar"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skärmbild"</string>
<string name="action_split" msgid="2098009717623550676">"Delat"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Tryck på en annan app för att använda delad skärm"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Avsluta val av delad skärm"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Välj en annan app för att använda delad skärm"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisationen tillåter inte den här åtgärden"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vill du hoppa över självstudierna?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Aktivitetsfältet visas"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Aktivitetsfältet är dolt"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigeringsfält"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Visa alltid aktivitetsfältet"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Ändra navigeringsläge"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Avdelare för aktivitetsfältet"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytta högst upp/till vänster"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytta längst ned/till höger"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Visa # app till.}other{Visa # appar till.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> och <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Lägger till appen på skrivbordet"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Avbryt"</string>
</resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index bc7cfb8..8c438f4 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Mapendekezo ya programu yamewashwa"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Umezima mapendekezo ya programu"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Programu iliyotabiriwa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Hakikisha unatelezesha kidole kuanzia ukingo wa kulia kabisa au ukingo wa kushoto kabisa."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Hakikisha unatelezesha kidole kuanzia ukingo wa kulia au kushoto kuelekea katikati ya skrini na uachilie."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zungusha kifaa chako"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Tafadhali zungusha kifaa chako ili ukamilishe mafunzo ya usogezaji kwa kutumia ishara"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Hakikisha unatelezesha kidole kutoka ukingo wa kulia au kushoto kabisa"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Hakikisha unatelezesha kidole kutoka ukingo wa kulia au kushoto hadi katikati ya skrini na uachilie"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Umejifunza jinsi ya kutelezesha kidole kuanzia kulia ili kurudi nyuma. Sasa jifunze jinsi ya kubadilisha programu."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Umekamilisha ishara ya kurudi nyuma."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Hakikisha hutelezeshi kidole karibu sana na sehemu ya chini ya skrini."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Umeweka ishara ya kurudi nyuma"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Hakikisha hutelezeshi kidole karibu sana na sehemu ya chini ya skrini"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Kubadilisha hisi ya ishara ya nyuma, nenda kwenye Mipangilio"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Telezesha kidole ili urudi nyuma"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ili urudi kwenye skrini iliyotangulia, telezesha kidole kuanzia ukingo wa kushoto au wa kulia kuelekea katikati ya skrini."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Ili urudi kwenye skrini iliyopita, telezesha vidole viwili kuanzia ukingo wa kushoto au wa kulia kuelekea katikati ya skrini."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Rudi nyuma"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Hakikisha kuwa husimamishi kabla ya kuachilia."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Hakikisha unatelezesha kidole kuelekea juu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Umekamilisha ishara ya kwenda kwenye Skrini ya kwanza. Sasa jifunze jinsi ya kurudi nyuma."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Umekamilisha ishara ya kwenda kwenye Skrini ya kwanza."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Telezesha kidole kutoka ukingo wa kushoto au kulia hadi katikati ya skrini"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Hakikisha husitishi kabla ya kuachilia"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Hakikisha unatelezesha kidole juu"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Umeweka ishara ya kwenda kwenye Skrini ya kwanza. Inayofuata, jifunze jinsi ya kurudi nyuma."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Umeweka ishara ya kwenda kwenye skrini ya kwanza"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Telezesha kidole ili uende kwenye skrini ya kwanza"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Telezesha kidole juu kuanzia chini ya skrini yako. Ishara hii kila wakati hukupeleka kwenye Skrini ya kwanza."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Telezesha vidole viwili kuelekea juu kuanzia sehemu ya chini ya skrini. Ishara hii kila wakati hukupeleka kwenye Skrini ya kwanza."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Nenda kwenye ukurasa wa mwanzo"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Ili uende kwenye skrini ya kwanza muda wowote, telezesha kidole juu kutoka sehemu ya chini ya skrini"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Jaribu kushikilia dirisha kwa muda mrefu kabla ya kuachilia."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Hakikisha unatelezesha kidole kuelekea juu, kisha usimamishe."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Telezesha kidole juu kutoka sehemu ya chini ya skrini yako"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Kazi nzuri!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Jaribu kushikilia dirisha kwa muda mrefu kabla ya kuachilia"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Hakikisha unatelezesha kidole juu, kisha usitishe"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Umejifunza jinsi ya kutumia ishara. Ili uzime ishara, nenda kwenye Mipangilio."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Umekamilisha ishara ya kubadilisha programu."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Umeweka ishara ya kubadilisha programu"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Telezesha kidole ili ubadilishe programu"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ili ubadili kati ya programu, telezesha kidole juu kuanzia sehemu ya chini ya skrini yako, ushikilie, kisha uachilie."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Ili ubadilishe kati ya programu, telezesha vidole viwili kuelekea juu kuanzia sehemu ya chini ya skrini yako, ushikilie, kisha uachilie."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Badilisha programu"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Telezesha kidole juu kutoka sehemu ya chini ya skrini yako, shikilia kisha uachilie"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Hongera!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Kila kitu kiko tayari"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Nimemaliza"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Mipangilio"</string>
@@ -82,13 +88,14 @@
<string name="allset_title" msgid="5021126669778966707">"Tayari!"</string>
<string name="allset_hint" msgid="459504134589971527">"Telezesha kidole juu ili uende kwenye skrini ya kwanza"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Gusa kitufe cha ukurasa wa mwanzo ili uende kwenye skrini ya kwanza"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Uko tayari kuanza kutumia <xliff:g id="DEVICE">%1$s</xliff:g> yako"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Uko tayari kuanza kutumia <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"kifaa"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Mipangilio ya usogezaji kwenye mfumo"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Shiriki"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Picha ya skrini"</string>
<string name="action_split" msgid="2098009717623550676">"Iliyogawanywa"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Gusa programu nyingine ili utumie kipengele cha kugawa skrini"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Ondoka kwenye hali ya skrini iliyogawanywa"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Chagua programu nyingine ili utumie hali ya kugawa skrini"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Kitendo hiki hakiruhusiwi na programu au shirika lako"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ungependa kuruka mafunzo ya usogezaji?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Upauzana umeonyeshwa"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Upauzana umefichwa"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Sehemu ya viungo muhimu"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Onyesha Upauzana kila wakati"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Badilisha hali ya usogezaji"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Kitenganishi cha Upauzana"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sogeza juu/kushoto"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sogeza chini/kulia"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Onyesha programu # zaidi.}other{Onyesha programu # zaidi.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> na <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Kuweka programu kwenye Eneo-kazi"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Ghairi"</string>
</resources>
diff --git a/quickstep/res/values-sw600dp-land/dimens.xml b/quickstep/res/values-sw600dp-land/dimens.xml
index 9cb3fec..5e9a177 100644
--- a/quickstep/res/values-sw600dp-land/dimens.xml
+++ b/quickstep/res/values-sw600dp-land/dimens.xml
@@ -27,4 +27,10 @@
<dimen name="gesture_tutorial_menu_done_button_top_spacing">40dp</dimen>
<dimen name="gesture_tutorial_menu_back_shape_bottom_margin">49dp</dimen>
+ <!-- Grid Only Overview -->
+ <!-- The top margin above the top row of tasks in grid only overview -->
+ <dimen name="overview_top_margin_grid_only">24dp</dimen>
+ <!-- The bottom margin above the bottom row of tasks in grid only overview -->
+ <dimen name="overview_bottom_margin_grid_only">40dp</dimen>
+
</resources>
diff --git a/res/layout/popup_container_material_u.xml b/quickstep/res/values-sw600dp/config.xml
similarity index 60%
copy from res/layout/popup_container_material_u.xml
copy to quickstep/res/values-sw600dp/config.xml
index d34c500..b22cfc5 100644
--- a/res/layout/popup_container_material_u.xml
+++ b/quickstep/res/values-sw600dp/config.xml
@@ -5,7 +5,7 @@
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,11 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.popup.PopupContainerWithArrow
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/popup_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical"/>
\ No newline at end of file
+<resources>
+ <!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
+ determines how many thumbnails will be fetched in the background. -->
+ <integer name="recentsThumbnailCacheSize">8</integer>
+</resources>
diff --git a/quickstep/res/values-sw600dp/dimens.xml b/quickstep/res/values-sw600dp/dimens.xml
index daf1f63..f9528b3 100644
--- a/quickstep/res/values-sw600dp/dimens.xml
+++ b/quickstep/res/values-sw600dp/dimens.xml
@@ -33,6 +33,10 @@
<dimen name="overview_page_spacing">36dp</dimen>
<!-- The space to the left and to the right of the "Clear all" button -->
<dimen name="overview_grid_side_margin">64dp</dimen>
+ <!-- The top margin above the top row of tasks in grid only overview -->
+ <dimen name="overview_top_margin_grid_only">80dp</dimen>
+ <!-- The bottom margin above the bottom row of tasks in grid only overview -->
+ <dimen name="overview_bottom_margin_grid_only">80dp</dimen>
<!-- Overview actions -->
<dimen name="overview_actions_top_margin">24dp</dimen>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 5ccbc17..ef5bd3f 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ஆப்ஸ் பரிந்துரைகள் இயக்கப்பட்டுள்ளன"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ஆப்ஸ் பரிந்துரைகள் முடக்கப்பட்டுள்ளன"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"கணித்த ஆப்ஸ்: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"வலது அல்லது இடது ஓரத்தின் விளிம்பிலிருந்து ஸ்வைப் செய்வதை உறுதிசெய்க."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"வலது அல்லது இடது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்தபிறகு விடுவிப்பதை உறுதிசெய்க."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"உங்கள் சாதனத்தைச் சுழற்றுங்கள்"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"சைகை வழிசெலுத்தல் பயிற்சியை நிறைவுசெய்ய உங்கள் சாதனத்தைச் சுழற்றுங்கள்"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"வலது அல்லது இடது ஓரத்தின் விளிம்பிலிருந்து ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"வலது அல்லது இடது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்தபிறகு விடுவிப்பதை உறுதிசெய்க"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"பின்செல்வதற்கு எப்படி வலதுபுறத்திலிருந்து ஸ்வைப் செய்வதென்று கற்றுக்கொண்டீர்கள். அடுத்து ஆப்ஸுக்கிடையே எப்படி மாறுவது என்பதை அறிக."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"பின்செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"திரையின் கீழ்பகுதிக்கு மிக நெருக்கமாக ஸ்வைப் செய்யவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"பின்செல் சைகைப் பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"திரையின் கீழ்ப்பகுதிக்கு மிக நெருக்கமாக ஸ்வைப் செய்யவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"பின்செல் சைகையின் உணர்திறனை மாற்ற அமைப்புகளுக்குச் செல்க"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"பின்செல்ல ஸ்வைப் செய்யுங்கள்"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"முந்தைய திரைக்கு மீண்டும் செல்ல, இடது/வலது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்க."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"முந்தைய திரைக்கு மீண்டும் செல்ல, 2 விரல்களால் இடது அல்லது வலது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்யுங்கள்."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"பின்செல்லுதல்"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"விடுவிப்பதற்கு முன்பாக இடைநிறுத்தவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"மேல்நோக்கி நேராக ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"முகப்புக்குச் செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள். அடுத்து, பின்செல்வது எப்படி என்பதை அறிக."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"முகப்புக்குச் செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"வலது அல்லது இடது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்யுங்கள்"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"விடுவிப்பதற்கு முன்பாக இடைநிறுத்தவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"மேல்நோக்கி நேராக ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"முகப்புக்குச் செல் சைகைப் பயிற்சியை நிறைவுசெய்துவிட்டீர்கள். அடுத்து பின்செல்வது எப்படி என்பதை அறிக."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"முகப்புக்குச் செல் சைகைப் பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"முகப்புக்குச் செல்ல ஸ்வைப் செய்யுங்கள்"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"திரையின் கீழிருந்து மேலாக ஸ்வைப் செய்க. இந்தச் சைகை எப்போதும் முகப்புத் திரைக்கு அழைத்துச் செல்லும்."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 விரலால் திரையின் கீழிருந்து மேலாக ஸ்வைப் செய்க. இந்தச் சைகை முகப்புத் திரைக்கு அழைத்துச் செல்லும்."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"முகப்புக்குச் செல்லுதல்"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"எந்தத் திரையிலிருந்தும் முகப்புத் திரைக்குச் செல்ல திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யுங்கள்"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"விடுவிப்பதற்கு முன்பாக நீண்டநேரம் சாளரத்தை அழுத்திப் பிடித்திருங்கள்."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"மேல்நோக்கி நேராக ஸ்வைப் செய்தபிறகு இடைநிறுத்துவதை உறுதிசெய்துகொள்ளுங்கள்."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்யுங்கள்"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"அருமை!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"விடுவிப்பதற்கு முன்பாக நீண்டநேரம் சாளரத்தை அழுத்திப் பிடித்திருங்கள்"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"மேல்நோக்கி நேராக ஸ்வைப் செய்தபிறகு இடைநிறுத்துவதை உறுதிசெய்துகொள்ளுங்கள்"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"சைகைகளை எப்படி உபயோகிப்பது என்று கற்றுக்கொண்டீர்கள். சைகைகளை முடக்க அமைப்புகளுக்குச் செல்லுங்கள்."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ஆப்ஸுக்கிடையே மாறும் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"ஆப்ஸுக்கிடையே மாறும் சைகைப் பயிற்சியை நிறைவுசெய்துவிட்டீர்கள்"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ஆப்ஸுக்கிடையே மாற ஸ்வைப் செய்யுங்கள்"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ஆப்ஸுக்கு இடையே மாற, திரையின் கீழிலிருந்து மேலாக ஸ்வைப் செய்து, பிடித்திருந்து, பிறகு விடுவிக்கவும்."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ஆப்ஸுக்கிடையே மாற, திரையின் கீழிருந்து மேலாக 2 விரலால் ஸ்வைப் செய்து, பிடித்து, பிறகு விடுவிக்கவும்."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ஆப்ஸுக்கிடையே மாறுதல்"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"உங்கள் திரையின் கீழ்ப்பகுதியில் இருந்து மேலே ஸ்வைப் செய்து, பிடித்து, பிறகு விடுவியுங்கள்"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"அருமை!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"எல்லாம் தயார்"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"முடிந்தது"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"அமைப்புகள்"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ஸ்கிரீன்ஷாட்"</string>
<string name="action_split" msgid="2098009717623550676">"பிரி"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"திரைப் பிரிப்பைப் பயன்படுத்த வேறு ஆப்ஸைத் தட்டவும்"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"திரைப் பிரிப்பு தேர்வில் இருந்து வெளியேறும்"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"திரைப் பிரிப்பை பயன்படுத்த வேறு ஆப்ஸை தேர்வுசெய்க"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ஆப்ஸோ உங்கள் நிறுவனமோ இந்த செயலை அனுமதிப்பதில்லை"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"வழிகாட்டுதல் பயிற்சியைத் தவிர்க்கவா?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"செயல் பட்டி காட்டப்படுகிறது"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"செயல் பட்டி மறைக்கப்பட்டுள்ளது"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"வழிசெலுத்தல் பட்டி"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"செயல் பட்டியை எப்போதும் காட்டு"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"வழிசெலுத்தல் பயன்முறையை மாற்று"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"செயல் பட்டிப் பிரிப்பான்"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"மேலே/இடதுபுறம் நகர்த்தும்"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"கீழே/வலதுபுறம் நகர்த்தும்"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{மேலும் # ஆப்ஸைக் காட்டு.}other{மேலும் # ஆப்ஸைக் காட்டு.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> மற்றும் <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ஆப்ஸை டெஸ்க்டாப்பில் சேர்க்கிறது"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ரத்துசெய்"</string>
</resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index ad0c851..a2adfe1 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"పిన్ చేయి"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"పిన్ చేయండి"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"సంప్రదాయేతర"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ఇటీవలి అంశాలు ఏవీ లేవు"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"యాప్ వినియోగ సెట్టింగ్లు"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"యాప్ సూచనలు డిజేబుల్ చేయబడ్డాయి"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"సూచించబడిన యాప్: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"కుడి వైపు చిట్ట చివరి లేదా ఎడమ వైపు చిట్ట చివరి అంచు నుండి స్వైప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"మీరు కుడి లేదా ఎడమ అంచు నుండి స్క్రీన్ మధ్యలోకి స్వైప్ చేశారని నిర్ధారించుకోని, మీ వేలిని ఎత్తండి."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"మీ పరికరాన్ని రొటేట్ చేయండి"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"సంజ్ఞ నావిగేషన్ ట్యుటోరియల్ను పూర్తి చేయడానికి దయచేసి మీ పరికరాన్ని రొటేట్ చేయండి"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"కుడి వైపు చిట్ట చివరి లేదా ఎడమ వైపు చిట్ట చివరి అంచు నుండి స్వైప్ చేస్తున్నారని నిర్ధారించుకోండి"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"మీరు కుడి లేదా ఎడమ అంచు నుండి స్క్రీన్ మధ్యలోకి స్వైప్ చేశారని నిర్ధారించుకుని, మీ వేలిని ఎత్తండి"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"వెనుకకు వెళ్లడానికి కుడి నుండి స్వైప్ ఎలానో మీకు తెలుసు. తర్వాత, యాప్ల మధ్య ఎలా మారాలో తెలుసుకోండి."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"మీరు తిరిగి వెనక్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"మీరు స్క్రీన్ దిగువకు చాలా దగ్గరగా స్వైప్ చేయలేదని నిర్ధారించుకోండి."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"మీరు పేజీ నుండి వెనుకకు వెళ్లే సంజ్ఞను పూర్తి చేశారు"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"మీరు స్క్రీన్ దిగువకు చాలా దగ్గరగా స్వైప్ చేయకుండా చూసుకోండి"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"వెనుక సంజ్ఞ సున్నితత్వం మార్చడానికి, సెట్టింగ్లకు వెళ్లండి"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"వెనుకకు వెళ్ళడం కోసం స్వైప్ చేయండి"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"మునుపటి స్క్రీన్కు తిరిగి వెళ్లడానికి, ఎడమ లేదా కుడి అంచు నుండి స్క్రీన్ మధ్యలోకి స్వైప్ చేయండి."</string>
+ <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"మునుపటి స్క్రీన్కు తిరిగి వెళ్లడానికి, ఎడమ లేదా కుడి అంచు నుండి స్క్రీన్ మధ్యలోకి స్వయిప్ చేయండి."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"గత స్క్రీన్కు తిరిగి వెళ్లడానికి, ఎడమ లేదా కుడి అంచు నుండి స్క్రీన్ మధ్యలోకి 2 వేళ్లతో స్వైప్ చేయండి."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"వెనుకకు వెళ్లండి"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వయిప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"బయలుదేరే ముందు మీరు పాజ్ చేయకుండా చూసుకోండి."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"మీరు నేరుగా పైకి స్వైప్ చేశారని నిర్ధారించుకోండి."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"మీరు మొదటి స్క్రీన్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు. తర్వాత, వెనుకకు ఎలా వెళ్లాలో తెలుసుకోండి."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"మీరు మొదటి ట్యాబ్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ఎడమ లేదా కుడి అంచు నుండి స్క్రీన్ మధ్యకు స్వైప్ చేయండి"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వైప్ చేశారని నిర్ధారించుకోండి"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"మీరు స్క్రీన్పై మీ వేలిని ఎత్తే ముందు స్వైపింగ్ను ఆపకుండా చూసుకోండి"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"మీరు నేరుగా పైకి స్వైప్ చేశారని నిర్ధారించుకోండి"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"మీరు మొదటి స్క్రీన్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు. తర్వాత, వెనుకకు ఎలా వెళ్లాలో తెలుసుకోండి."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"మీరు మొదటి స్క్రీన్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"మొదటి స్క్రీన్కు వెళ్లడానికి స్వైప్ చేయండి"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"స్క్రీన్ కింది నుండి పైకి స్వైప్ చేయండి. ఈ సంజ్ఞ ఎప్పుడూ మిమ్మల్ని మొదటి స్క్రీన్కు తీసుకెళ్తుంది."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"స్క్రీన్ కింది నుండి 2 వేళ్లతో పైకి స్వైప్ చేయండి. సంజ్ఞ ఎల్లప్పుడూ మొదటి స్క్రీన్కు తీసుకెళ్తుంది."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"మొదటి ట్యాబ్కు వెళ్లండి"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ఎప్పుడైనా మీ మొదటి స్క్రీన్కు వెళ్లడానికి, మీ స్క్రీన్ దిగువ భాగం నుండి పైకి స్వైప్ చేయండి"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వయిప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"రిలీజ్ చేయడానికి ముందు విండోను ఎక్కువసేపు పట్టుకోడానికి ట్రై చేయండి."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"మీరు నేరుగా స్వైప్ చేశారని నిర్ధారించుకోండి, ఆపై పాజ్ చేయండి."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"స్క్రీన్ కింది భాగం నుండి పైకి స్వైప్ చేయండి"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"బాగా చేశారు!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వైప్ చేశారని నిర్ధారించుకోండి"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"వేలిని రిలీజ్ చేయడానికి ముందు విండోను ఎక్కువసేపు నొక్కి, పట్టుకోవడానికి ట్రై చేయండి"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"స్క్రీన్పై నేరుగా పైకి స్వైప్ చేసి, ఆపై పాజ్ చేయండి"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"మీరు సంజ్ఞలను ఎలా ఉపయోగించాలో నేర్చుకున్నారు. సంజ్ఞలను ఆఫ్ చేయడానికి, సెట్టింగ్లకు వెళ్లండి."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"మీరు \'యాప్ల మధ్య మార్పు\' సంజ్ఞను పూర్తి చేశారు."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"మీరు \'యాప్ల మధ్య మార్పు\' సంజ్ఞను పూర్తి చేశారు"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"యాప్ల మధ్య మార్చడం కోసం స్వైప్ చేయండి"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"యాప్ల మధ్య మారడానికి, మీ స్క్రీన్ కింది వైపు నుండి పైకి స్వైప్ చేసి, పట్టుకుని, తర్వాత వదలండి."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"యాప్ల మధ్య మారడానికి, మీ స్క్రీన్ కింది నుండి 2 వేళ్లతో పైకి స్వైప్ చేసి, నొక్కి పట్టి, వదలండి."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"యాప్ల మధ్య మారండి"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"యాప్ల మధ్య స్విచ్ అవ్వండి"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"మీ స్క్రీన్ కింది వైపు నుండి పైకి స్వైప్ చేసి, పట్టుకుని, తర్వాత వదలండి"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"చాలా బాగా చేశారు!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"అంతా సిద్ధంగా ఉంది"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"పూర్తయింది"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"సెట్టింగ్లు"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"పనితీరు బాగుంది!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ట్యుటోరియల్ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"అంతా సెట్ అయింది!"</string>
- <string name="allset_hint" msgid="459504134589971527">"హోమ్కు వెళ్లడానికి పైకి స్వైప్ చేయండి"</string>
+ <string name="allset_hint" msgid="459504134589971527">"వర్చువల్ హోమ్కు వెళ్లడానికి పైకి స్వైప్ చేయండి"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"మీ మొదటి స్క్రీన్కు వెళ్లడానికి హోమ్ బటన్ను ట్యాప్ చేయండి"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"మీరు ఇప్పుడు మీ <xliff:g id="DEVICE">%1$s</xliff:g>ను ఉపయోగించడం ప్రారంభించవచ్చు"</string>
<string name="default_device_name" msgid="6660656727127422487">"పరికరం"</string>
@@ -88,7 +94,8 @@
<string name="action_share" msgid="2648470652637092375">"షేర్ చేయండి"</string>
<string name="action_screenshot" msgid="8171125848358142917">"స్క్రీన్షాట్"</string>
<string name="action_split" msgid="2098009717623550676">"స్ప్లిట్ చేయండి"</string>
- <string name="toast_split_select_app" msgid="8464310533320556058">"మరొక యాప్ను ట్యాప్ చేసి, స్ప్లిట్ స్క్రీన్ వాడండి"</string>
+ <string name="toast_split_select_app" msgid="8464310533320556058">"స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్ను ట్యాప్ చేయండి"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"స్ప్లిట్ స్క్రీన్ ఎంపిక నుండి ఎగ్జిట్ అవ్వండి"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"స్ప్లిట్ స్క్రీన్ ఉపయోగానికి మరొక యాప్ ఎంచుకోండి"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ఈ చర్యను యాప్ గానీ, మీ సంస్థ గానీ అనుమతించవు"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"నావిగేషన్ ట్యుటోరియల్ను స్కిప్ చేయాలా?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"టాస్క్బార్ చూపబడింది"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"టాస్క్బార్ దాచబడింది"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"నావిగేషన్ బార్"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ఎప్పుడూ టాస్క్బార్ చూపించండి"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"నావిగేషన్ మోడ్ను మార్చండి"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"టాస్క్బార్ డివైడర్"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ఎగువ/ఎడమ వైపునకు తరలించండి"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"దిగువ/కుడి వైపునకు తరలించండి"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{మరో # యాప్ను చూడండి.}other{మరో # యాప్లను చూడండి.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g>, <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"డెస్క్టాప్నకు యాప్ను జోడిస్తోంది"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"రద్దు చేయండి"</string>
</resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 8cba9b9..0339046 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"เปิดใช้แอปแนะนำแล้ว"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ปิดใช้คำแนะนำเกี่ยวกับแอปอยู่"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"แอปที่คาดว่าจะใช้: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ตรวจสอบว่าปัดจากขอบด้านขวาสุดหรือซ้ายสุด"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ตรวจสอบว่าปัดจากขอบด้านขวาหรือซ้ายไปตรงกลางหน้าจอ แล้วยกนิ้วขึ้น"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"หมุนอุปกรณ์ของคุณ"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"โปรดหมุนอุปกรณ์เพื่อทำตามบทแนะนำการนำทางด้วยท่าทางสัมผัสให้เสร็จสมบูรณ์"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"ตรวจสอบว่าปัดจากขอบด้านขวาสุดหรือซ้ายสุด"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"ตรวจสอบว่าปัดจากขอบด้านขวาหรือซ้ายไปตรงกลางหน้าจอ แล้วยกนิ้วขึ้น"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"คุณรู้วิธีปัดจากด้านขวาเพื่อย้อนกลับแล้ว ต่อไปดูวิธีสลับแอป"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ตรวจสอบว่าไม่ได้ปัดใกล้กับด้านล่างของหน้าจอมากเกินไป"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"ไม่ปัดใกล้กับด้านล่างของหน้าจอมากเกินไป"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"เปลี่ยนความไวของท่าทางสัมผัสเพื่อย้อนกลับได้ที่การตั้งค่า"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"ปัดเพื่อย้อนกลับ"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"หากต้องการย้อนกลับไปที่หน้าจอล่าสุด ให้ปัดจากขอบด้านซ้ายหรือขวาไปตรงกลางหน้าจอ"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"หากต้องการย้อนกลับไปที่หน้าจอล่าสุด ให้ใช้ 2 นิ้วปัดจากขอบด้านซ้ายหรือขวาไปตรงกลางหน้าจอ"</string>
- <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"กลับ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ตรวจสอบว่าไม่มีการหยุดชั่วคราวก่อนยกนิ้วขึ้น"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ตรวจสอบว่าปัดขึ้นในแนวตรง"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว ต่อไปดูวิธีย้อนกลับ"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว"</string>
+ <string name="back_gesture_tutorial_title" msgid="1944737946101059789">"ย้อนกลับ"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"ปัดจากขอบด้านซ้ายหรือขวาไปตรงกลางหน้าจอ"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"ไม่ต้องหยุดชั่วคราวก่อนยกนิ้วขึ้น"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"ปัดขึ้นในแนวตรง"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว ต่อไปดูวิธีย้อนกลับ"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ปัดเพื่อไปที่หน้าแรก"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ปัดขึ้นจากด้านล่างของหน้าจอ ท่าทางสัมผัสนี้จะนำคุณไปที่หน้าจอหลักเสมอ"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอ ท่าทางสัมผัสนี้จะนำคุณไปที่หน้าจอหลักเสมอ"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ไปที่หน้าแรก"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"ปัดขึ้นจากด้านล่างของหน้าจอเพื่อไปที่หน้าจอหลักได้ทุกเมื่อ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ลองแตะหน้าต่างค้างไว้นานขึ้นก่อนปล่อยนิ้ว"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ตรวจสอบว่าปัดขึ้นในแนวตรง แล้วหยุดชั่วคราว"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ไปที่หน้าจอหลัก"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"ปัดขึ้นจากด้านล่างของหน้าจอ"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"เก่งมาก"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"ลองแตะหน้าต่างค้างไว้นานขึ้นก่อนปล่อยนิ้ว"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"ตรวจสอบว่าปัดขึ้นในแนวตรง แล้วหยุดชั่วคราว"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"คุณรู้วิธีใช้ท่าทางสัมผัสแล้ว หากต้องการปิดท่าทางสัมผัส ให้ไปที่การตั้งค่า"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"คุณทำท่าทางสัมผัสเพื่อสลับแอปเสร็จแล้ว"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"คุณทำท่าทางสัมผัสเพื่อสลับแอปเสร็จแล้ว"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ปัดเพื่อสลับแอป"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"หากต้องการสลับระหว่างแอปต่างๆ ให้ปัดขึ้นจากด้านล่างของหน้าจอ ค้างไว้ แล้วปล่อย"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"หากต้องการสลับระหว่างแอป ให้ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอค้างไว้แล้วปล่อย"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"เปลี่ยนแอป"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"ปัดขึ้นจากด้านล่างของหน้าจอ ค้างไว้ แล้วปล่อย"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"เยี่ยมมาก"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"เรียบร้อย"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"เสร็จสิ้น"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"การตั้งค่า"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"ภาพหน้าจอ"</string>
<string name="action_split" msgid="2098009717623550676">"แยก"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"แตะแอปอื่นเพื่อใช้การแยกหน้าจอ"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"ออกจากการเลือกโหมดแยกหน้าจอ"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"เลือกแอปอื่นเพื่อใช้การแยกหน้าจอ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"แอปหรือองค์กรของคุณไม่อนุญาตการดำเนินการนี้"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ข้ามบทแนะนำการนำทางไหม"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"แถบงานแสดงอยู่"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"แถบงานซ่อนอยู่"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"แถบนำทาง"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"แสดงแถบงานเสมอ"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"เปลี่ยนโหมดการนําทาง"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ตัวแบ่งแถบงาน"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ย้ายไปที่ด้านบนหรือด้านซ้าย"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ย้ายไปที่ด้านล่างหรือด้านขวา"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{แสดงเพิ่มเติมอีก # แอป}other{แสดงเพิ่มเติมอีก # แอป}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> และ <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"การเพิ่มแอปไปยังเดสก์ท็อป"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"ยกเลิก"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index ae6dd45..7bb38c2 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Naka-enable ang mga iminumungkahing app"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Naka-disable ang mga iminumungkahing app"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Hinulaang app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Tiyaking magsa-swipe ka mula sa dulong kanan o dulong kaliwang gilid."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Tiyaking mag-swipe mula sa kanan o kaliwang gilid papunta sa gitna ng screen at iangat ang daliri."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"I-rotate ang iyong device"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Paki-rotate ang iyong device para tapusin ang tutorial sa navigation gamit ang galaw"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Tiyaking magsa-swipe ka mula sa dulong kanan o dulong kaliwang gilid"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Tiyaking magsa-swipe mula sa kanan o kaliwang gilid papunta sa gitna ng screen at iangat ang daliri"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Natuto kang mag-swipe mula sa kanan para bumalik. Sunod, alamin kung paano magpalipat-lipat ng app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Nakumpleto mo na ang galaw para bumalik."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Tiyaking hindi ka magsa-swipe nang masyadong malapit sa ibaba ng screen."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Nakumpleto mo na ang galaw para bumalik"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Tiyaking hindi ka magsa-swipe nang masyadong malapit sa ibaba ng screen"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Pumunta sa Settings para baguhin ang sensitivity ng pagbalik"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Mag-swipe para bumalik"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para bumalik sa nakaraang screen, mag-swipe mula sa kaliwa o kanang gilid patungo sa gitna ng screen."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Para bumalik sa huling screen, mag-swipe gamit ang 2 daliri mula sa kaliwa o kanang gilid hanggang sa gitna ng screen."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Bumalik"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Tiyaking hindi ka magpo-pause bago iangat ang iyong daliri."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Tiyaking magsa-swipe ka nang diretso pataas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Nakumpleto mo na ang galaw para pumunta sa Home. Susunod, alamin kung paano bumalik."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Nakumpleto mo na ang galaw para pumunta sa Home."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Mag-swipe mula sa kaliwa o kanang gilid papunta sa gitna ng screen"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Tiyaking hindi ka magpo-pause bago iangat ang iyong daliri"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Tiyaking magsa-swipe ka nang diretso pataas"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Nakumpleto mo na ang galaw para pumunta sa home. Susunod, alamin kung paano bumalik."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Nakumpleto mo na ang galaw para pumunta sa home"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Mag-swipe para pumunta sa home"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Mag-swipe pataas mula sa ibaba ng iyong screen. Dadalhin ka palagi ng galaw na ito sa Home screen."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Mag-swipe pataas gamit ang 2 daliri mula sa ibaba ng screen. Dadalhin ka palagi nito sa Home screen."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Pumunta sa home"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Para pumunta sa iyong home screen anumang oras, mag-swipe pataas mula sa ibaba ng screen mo"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Subukang pindutin nang mas matagal ang window bago ito bitawan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Tiyaking magsa-swipe ka nang diretso pataas, pagkatapos ay mag-pause."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Mag-swipe pataas mula sa ibabang bahagi ng iyong screen"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Magaling!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Subukang pindutin nang mas matagal ang window bago ito bitawan"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Tiyaking magsa-swipe ka nang diretso pataas, pagkatapos ay mag-pause"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Alam mo na kung paano gumamit ng mga galaw. Para i-off ang mga galaw, pumunta sa Mga Setting."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Nakumpleto mo na ang galaw para magpalipat-lipat sa mga app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Nakumpleto mo na ang galaw para magpalipat-lipat sa mga app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Mag-swipe para lumipat ng app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para lumipat ng app, mag-swipe pataas mula sa ibaba ng iyong screen, mag-hold, at iangat ang daliri."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Para lumipat ng app, mag-swipe pataas gamit ang 2 daliri mula sa ibaba, mag-hold, at bumitaw."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Lumipat ng app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Mag-swipe pataas mula sa ibaba ng iyong screen, i-hold ito saka bitawan"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Magaling!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Handa na ang lahat"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Tapos na"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Mga Setting"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="action_split" msgid="2098009717623550676">"Split"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Mag-tap ng ibang app para gamitin ang split screen"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Lumabas sa pagpili ng split screen"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pumili ng ibang app para gamitin ang split screen"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Hindi pinapayagan ng app o ng iyong organisasyon ang pagkilos na ito"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Laktawan ang tutorial sa pag-navigate?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Ipinapakita ang taskbar"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Nakatago ang taskbar"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigation bar"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Palaging ipakita ang Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Magpalit ng navigation mode"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divider ng Taskbar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Ilipat sa itaas/kaliwa"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Ilipat sa ibaba/kanan"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Magpakita ng # pang app.}one{Magpakita ng # pang app.}other{Magpakita ng # pang app.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> at <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Idinaragdag ang app sa Desktop"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Kanselahin"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index e5d5b6d..905183a 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Uygulama önerileri etkinleştirildi"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Uygulama önerileri devre dışı bırakıldı"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tahmin edilen uygulama: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"En sağ veya en sol kenardan kaydırdığınızdan emin olun."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranın sağ veya sol kenarından ortasına doğru sürükleyip bıraktığınızdan emin olun."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Cihazınızı döndürün"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Hareketle gezinme eğitimini tamamlamak için lütfen cihazınızı döndürün"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"En sağ veya en sol kenardan kaydırdığınızdan emin olun"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Ekranın sağ veya sol kenarından ortasına doğru sürükleyip bıraktığınızdan emin olun."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Geri dönmek için sağdan kaydırmayı öğrendiniz. Sırada uygulamalar arasında geçiş yapma var."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Geri dön hareketini tamamladınız."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ekranın alt kısmına çok yakın bir şekilde kaydırmadığınızdan emin olun."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Geri dön hareketini tamamladınız"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Ekranın alt kısmına çok yakın bir şekilde kaydırmadığınızdan emin olun"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Geri hareketinin hassasiyetini değiştirmek için Ayarlar\'a gidin"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Geri dönmek için kaydırma"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Son ekrana geri gitmek için sol veya sağ kenardan ekranın ortasına doğru kaydırın."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Son ekrana geri gitmek için sol veya sağ kenardan ekranın ortasına doğru 2 parmağınızla kaydırın."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Geri dönme"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Bırakmadan önce parmağınızı duraklatmadığınızdan emin olun."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Düz bir şekilde yukarı kaydırdığınızdan emin olun."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ana ekrana git hareketini tamamladınız. Şimdi nasıl geri döneceğinizi öğreneceksiniz."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ana ekrana git hareketini tamamladınız."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Sol veya sağ kenardan ekranın ortasına doğru kaydırın"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Bırakmadan önce parmağınızı duraklatmadığınızdan emin olun"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Düz bir şekilde yukarı kaydırdığınızdan emin olun"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ana ekrana git hareketini tamamladınız. Şimdi ana ekrana nasıl gideceğinizi öğreneceksiniz."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ana ekrana git hareketini tamamladınız"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Ana ekrana gitmek için kaydırma"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranın alt kısmından yukarıya doğru kaydırın. Bu hareket sizi her zaman Ana ekrana götürür."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Ekranın alt kısmından 2 parmağınızla yukarı kaydırın. Bu hareket sizi her zaman Ana ekrana götürür."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ana sayfaya gidin"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"İstediğiniz zaman ana ekrana gitmek için ekranınızın altından yukarı doğru kaydırın"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Bırakmadan önce pencereyi daha uzun süre tutmayı deneyin."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Düz bir şekilde yukarı kaydırıp ardından parmağınızı duraklattığınızdan emin olun."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Ana sayfaya gitme"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Parmağınızı ekranın alt kısmından yukarıya doğru kaydırın"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Tebrikler!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Bırakmadan önce pencereyi daha uzun süre tutmayı deneyin"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Düz bir şekilde yukarı kaydırıp ardından parmağınızı duraklattığınızdan emin olun"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Hareketleri nasıl kullanacağınızı öğrendiniz. Hareketleri kapatmak için Ayarlar\'a gidin."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Uygulamalar arasında geçiş yapma hareketini tamamladınız."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Uygulamalar arasında geçiş yapma hareketini tamamladınız"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Uygulamalar arasında geçiş yapmak için kaydırma"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Uygulamalar arasında geçiş yapmak için ekranınızın altından yukarı kaydırıp basılı tutun ve sonra bırakın."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Uygulamalara geçiş yapmak için ekranın altından 2 parmakla yukarı kaydırıp basılı tutun ve bırakın."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Uygulamalar arasında geçiş yapma"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Ekranınızın alt tarafından yukarı doğru kaydırın, tutun ve sonra bırakın"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Tebrikler!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Hepsi bu kadar"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Bitti"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ayarlar"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Ekran görüntüsü"</string>
<string name="action_split" msgid="2098009717623550676">"Böl"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Bölünmüş ekran için başka bir uygulamaya dokunun"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Bölünmüş ekran seçiminden çıkın"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Bölünmüş ekran kullanmak için başka bir uygulama seçin"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Uygulamanız veya kuruluşunuz bu işleme izin vermiyor"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Gezinme eğitimi atlansın mı?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Görev çubuğu gösteriliyor"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Görev çubuğu gizlendi"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Gezinme çubuğu"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Görev çubuğunu daima göster"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Gezinme modunu değiştir"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Görev Çubuğu Ayırıcısı"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sol üste taşı"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sağ alta taşı"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# uygulama daha göster.}other{# uygulama daha göster}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> ve <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Uygulama Masaüstü\'ne ekleniyor"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"İptal"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 36c5bbb..6cbf71f 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -44,51 +44,58 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Рекомендовані додатки ввімкнено"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Рекомендовані додатки вимкнено"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Передбачений додаток: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Проведіть пальцем саме від правого або лівого краю екрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Проведіть пальцем від правого або лівого краю до середини екрана й підніміть палець."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Оберніть пристрій"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Обертайте пристрій, щоб ознайомитися з посібником із навігації за допомогою жестів"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Проведіть пальцем від самого краю екрана (правого або лівого)"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Проведіть пальцем від правого або лівого краю до середини екрана й підніміть палець"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Тепер ви знаєте, як повернутися на попередній екран, провівши пальцем справа наліво. Дізнайтеся, як переключатися між додатками."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ви виконали жест \"Назад\"."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не проводьте пальцем надто близько до нижнього краю екрана."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ви виконали жест \"Назад\""</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Не проводьте пальцем надто близько до нижнього краю екрана"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Щоб змінити чутливість жесту \"Назад\", відкрийте налаштування"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Щоб повернутися, проведіть пальцем по екрану"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Щоб перейти на попередній екран, проведіть пальцем від лівого чи правого краю до середини екрана."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Щоб перейти на попередній екран, проведіть двома пальцями від лівого чи правого краю до середини екрана."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Повернення на попередній екран"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Проведіть пальцем угору від нижнього краю екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не робіть паузу перед тим, як відірвати палець від екрана."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Проводьте пальцем вертикально вгору."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ви виконали жест переходу на головний екран. Тепер дізнайтеся, як повернутися."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ви виконали жест переходу на головний екран."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Проведіть пальцем від лівого чи правого краю до середини екрана"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Проведіть пальцем угору від нижнього краю екрана"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Не робіть паузу перед тим, як відірвати палець від екрана"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Проводьте пальцем вертикально вгору"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ви виконали жест переходу на головний екран. Тепер дізнайтеся, як повернутися."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ви виконали жест переходу на головний екран"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Проведіть пальцем, щоб перейти на головний екран"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Проведіть пальцем по екрану знизу вгору. Цей жест завжди повертатиме вас на головний екран."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Проведіть двома пальцями вгору від низу екрана. Цей жест завжди спрямовує вас на головний екран."</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Перейти на головний екран"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Щоб будь-коли перейти на головний екран, проведіть пальцем вгору від низу екрана"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Проведіть пальцем угору від нижнього краю екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Спробуйте втримувати вікно довше, перш ніж відпустити."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Проведіть пальцем вертикально вгору, а тоді зробіть паузу."</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Перехід на головний екран"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Проведіть пальцем угору від низу екрана"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Чудово!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Проведіть пальцем угору від нижнього краю екрана"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Спробуйте втримувати вікно довше, перш ніж відпустити"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Проведіть пальцем вертикально вгору, а тоді зробіть паузу"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ви вивчили жести. Щоб вимкнути їх, перейдіть у налаштування."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ви виконали жест переходу в інший додаток."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ви виконали жест переходу в інший додаток"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Проведіть пальцем, щоб перейти в інший додаток"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Щоб переключатися між додатками, проведіть знизу вгору по екрану, утримуйте палець, а потім відпустіть."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Щоб перейти в інший додаток, проведіть 2 пальцями від низу екрана, потримайте й відпустіть палець."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Перемикання між додатками"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Проведіть пальцем знизу вгору, утримуйте палець на екрані, а потім відпустіть"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Чудово!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Усе готово!"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Налаштування"</string>
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Спробуйте ще"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудово!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Навчальний посібник <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово."</string>
+ <string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
<string name="allset_hint" msgid="459504134589971527">"Щоб перейти на головний екран, проведіть пальцем угору"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"Натисніть кнопку головного екрана, щоб відкрити його"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"Тепер ви можете користуватися цим пристроєм: <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"Тепер ви можете використовувати <xliff:g id="DEVICE">%1$s</xliff:g>"</string>
<string name="default_device_name" msgid="6660656727127422487">"пристрій"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Системні налаштування навігації"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Поділитися"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Знімок екрана"</string>
<string name="action_split" msgid="2098009717623550676">"Розділити"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Щоб розділити екран, виберіть ще один додаток"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Вийти з режиму розділення екрана"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Щоб розділити екран, виберіть ще один додаток"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ця дія заборонена додатком або адміністратором організації"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропустити посібник із навігації?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Панель завдань показано"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Панель завдань приховано"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Панель навігації"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Завжди показув. панель завдань"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Змінити режим навігації"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Розділювач панелі завдань"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перемістити вгору або вліво"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перемістити вниз або вправо"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Показати ще # додаток.}one{Показати ще # додаток.}few{Показати ще # додатки.}many{Показати ще # додатків.}other{Показати ще # додатка.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> та <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Встановлення додатка на комп’ютер"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Скасувати"</string>
</resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 9d1efe4..2392c6c 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ایپ کی تجاویز فعال ہیں"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ایپ کی تجاویز غیر فعال ہیں"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"پیشن گوئی کردہ ایپ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے دور سے سوئپ کریں۔"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے اسکرین کے وسط تک سوائپ کریں اور پھر اپنی انگلی اٹھا لیں۔"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"اپنا آلہ گھمائیں"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"براہ کرم اشاروں والی نیویگیشن کا ٹیوٹوریل مکمل کرنے کے لیے اپنا آلہ گھمائیں"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے دور سے سوائپ کریں"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے اسکرین کے وسط تک سوائپ کریں اور پھر اپنی انگلی اٹھا لیں"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"آپ نے واپس جانے کے لیے دائیں کنارے سے سوائپ کرنے کا طریقہ سیکھ لیا۔ اس کے بعد ایپس سوئچ کرنے کا طریقہ جانیں۔"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"آپ نے واپس جائیں اشارے کو مکمل کر لیا۔"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے حصے سے زیادہ قریب سے سوائپ نہ کریں۔"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"آپ نے واپس جائیں اشارے کو مکمل کر لیا"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے حصے سے زیادہ قریب سے سوائپ نہ کریں"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"پچھلے اشارے کی حساسیت تبدیل کرنے کے لیے ترتیبات پر جائیں"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"واپس جانے کے لیے سوائپ کریں"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"پچھلی اسکرین پر واپس جانے کے لیے بائیں یا دائیں کنارے سے اسکرین کے وسط تک سوائپ کریں۔"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"آخری اسکرین پر واپس جانے کے لیے، 2 انگلیوں سے بائیں یا دائیں کنارے سے اسکرین کے وسط تک سوائپ کریں۔"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"واپس جائیں"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں۔"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"اس بات کو یقینی بنائیں کہ آپ اپنی انگلی اوپر اٹھانے سے پہلے موقوف نہ کریں۔"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں۔"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔ اس کے بعد واپس جانے کا طریقہ جانیں۔"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"دائیں یا بائیں کنارے سے اسکرین کے وسط تک سوائپ کریں"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"اس بات کو یقینی بنائیں کہ آپ اپنی انگلی اوپر اٹھانے سے پہلے موقوف نہ کریں"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔ اس کے بعد، واپس جانے کا طریقہ جانیں۔"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"ہوم پر جانے کے لیے سوائپ کریں"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"اپنی اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں۔ یہ اشارہ آپ کو ہمیشہ ہوم اسکرین پر لے جاتا ہے۔"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"اسکرین کے نیچے سے 2 انگلیوں سے اوپر سوائپ کریں۔ یہ اشارہ آپ کو ہمیشہ ہوم اسکرین پر لے جاتا ہے۔"</string>
- <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"گھر جائیں"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"کسی بھی وقت اپنی ہوم اسکرین پر جانے کے لیے، اپنی اسکرین کے نیچے سے اوپر سوائپ کریں"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں۔"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"انگلی اٹھانے سے پہلے ونڈو کو زیادہ دیر تک پکڑنے کی کوشش کریں۔"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں، پھر موقوف کریں۔"</string>
+ <string name="home_gesture_tutorial_title" msgid="3126834347496917376">"ہوم پر جائیں"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"اپنی اسکرین کے نچلے حصے سے اوپر کی طرف سوائپ کریں"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"بہترین!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"انگلی اٹھانے سے پہلے ونڈو کو زیادہ دیر تک پکڑنے کی کوشش کریں"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں، پھر موقوف کریں"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"آپ نے اشاروں کو استعمال کرنے کا طریقہ سیکھ لیا۔ اشاروں کو آف کرنے کے لیے ترتیبات پر جائیں۔"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"آپ نے ایپس کو سوئچ کرنے کا اشارہ مکمل کر لیا۔"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"آپ نے ایپس کو سوئچ کرنے کا اشارہ مکمل کر لیا"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"ایپس سوئچ کرنے کے لیے سوائپ کریں"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ایپس کے مابین سوئچ کرنے کے لیے، اپنی اسکرین کے نچلے حصے سے اوپر کی جانب سوائپ کریں، پکڑے رکھیں، پھر چھوڑ دیں۔"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"ایپس کے مابین سوئچ کرنے کیلئے، اپنی اسکرین کے نیچے سے 2 انگلیوں سے اوپر سوائپ کریں، دبائے رکھیں پھر چھوڑ دیں۔"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ایپس سوئچ کریں"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"اپنی اسکرین کے نچلے حصے سے اوپر کی جانب سوائپ کریں، دبائے رکھیں، پھر چھوڑ دیں"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"بہت خوب!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"سب ہو گیا"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ہو گیا"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ترتیبات"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"اسکرین شاٹ"</string>
<string name="action_split" msgid="2098009717623550676">"اسپلٹ"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"اسپلٹ اسکرین کا استعمال کرنے کیلئے دوسری ایپ پر تھپتھپائیں"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"اسپلٹ اسکرین کے انتخاب سے باہر نکلیں"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"اسپلٹ اسکرین کے استعمال کیلئے دوسری ایپ منتخب کریں"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ایپ یا آپ کی تنظیم کی جانب سے اس کارروائی کی اجازت نہیں ہے"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"نیویگیشن کا ٹیوٹوریل نظر انداز کریں؟"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"ٹاشک بار دکھایا گیا"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"ٹاسک بار چھپایا گیا"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"نیویگیشن بار"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"ہمیشہ ٹاسک بار دکھائیں"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"نیویگیشن موڈ تبدیل کریں"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"ٹاسک بار ڈیوائیڈر"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"اوپر/بائیں طرف منتقل کریں"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"نیچے/دائیں طرف منتقل کریں"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{# مزید ایپ دکھائیں۔}other{# مزید ایپس دکھائیں۔}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> اور <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"ڈیسک ٹاپ پر ایپ شامل کرنا"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"منسوخ کریں"</string>
</resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index cf70ebd..da2d363 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ilova tavsiyalari yoqildi"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Endi ilova takliflari chiqmaydi"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Taklif etilgan ilova: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ekran chetidan boshlab oʻngdan yoki chapdan suring."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranning oʻng yoki chap chetidan oʻrtasiga suring va qoʻyib yuboring."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Qurilmangizni buring"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Ishorali navigatsiya darsligini tugatish uchun qurilmani buring"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Ekran chetidan boshlab oʻngdan yoki chapdan suring"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Ekranning oʻng yoki chap chetidan oʻrtasigacha suring va qoʻyib yuboring"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ortga qaytish uchun oʻngdan surishni oʻrgandingiz. Endi ilovalarni almashtirishni oʻrganamiz."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ortga qaytish ishorasi darsini tamomladingiz."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Barmoqni ekran pastiga yaqin surmaslikka harakat qiling."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ortga qaytish ishorasi darsini tamomladingiz"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Barmoqni ekran pastiga yaqin surmaslikka harakat qiling"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Orqaga ishorasi sezuvchanligi Sozlamalardan oʻzgartiriladi"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Orqaga qaytish"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ortga qaytish uchun barmoqni ekranning yon chekkalaridan oʻrtasigacha suring."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Oxirgi ekranga qaytish uchun 2 barmoq bilan ekranning chap yoki oʻng chekkasidan oʻrtasigacha suring."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Orqaga"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Barmoqni ekrandan pauzasiz qoʻyib uzing."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Barmoqni tik tepaga suring."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Bosh ekranni ochish ishorasi darsini tamomladingiz. Endi orqaga qaytishni oʻrganamiz."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Bosh ekranni ochish ishorasi darsini tamomladingiz."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Chap yoki oʻng chetidan ekranning oʻrtasiga suring"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Barmoqni ekrandan pauzasiz qoʻyib uzing"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Barmoqni tik tepaga suring"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Bosh ekranni ochish ishorasi darsini tamomladingiz. Endi orqaga qaytishni oʻrganamiz."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Bosh ekranni ochish ishorasi darsini tamomladingiz"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Svayp bilan bosh ekranni ochish"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranning pastidan tepaga qarab suring. Bu ishora doim Bosh ekranni ochadi."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"2 barmoq bilan ekranning quyidan tepasiga suring. Bu ishora har doim Bosh ekranni ochadi."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Boshiga"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Istalgan vaqtda bosh ekranga oʻtish uchun ekranning pastidan tepaga suring"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Barmoqni uzishdan oldin oynani biroz bosib turing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Avval tik tepaga surib, keyin pauza qiling."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Ekranning quyi qismidan tepaga torting"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Barakalla!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Barmoqni uzishdan oldin oynani biroz bosib turing"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Avval tik tepaga surib, keyin pauza qiling"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ishoralardan qanday foydalanishni oʻrganib oldingiz. Ishoralarni oʻchirish uchun Sozlamalarga kiring."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ilovalarni almashtirish darsini tamomladingiz."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ilovalarni almashtirish darsini tamomladingiz"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Ilovalar orasida almashish"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ilovalarni ochish uchun ekranning pastidan tepaga qarab suring, biroz ushlab turing va qoʻyib yuboring"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Ilovalarni almashtirish uchun 2 barmoq bilan ekranning quyidan tepasiga surib turib, qoʻyib yuboring"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Ilovalarni almashtirish"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Ekranning pastidan tepaga qarab suring, biroz ushlab turing va qoʻyib yuboring"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Juda soz!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tayyor"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Tayyor"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Sozlamalar"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Skrinshot"</string>
<string name="action_split" msgid="2098009717623550676">"Ajratish"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Ekranni ikkiga ajratish uchun boshqa ilovani bosing"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Ekranni ikkiga ajratish tanlovidan chiqish"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Ekranni ikkiga ajratish uchun boshqa ilovani tanlang"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Bu amal ilova yoki tashkilotingiz tomonidan taqiqlangan"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Navigatsiya darsi yopilsinmi?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Vazifalar paneli ochiq"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Vazifalar paneli yopiq"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigatsiya paneli"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Doim vazifalar paneli chiqsin"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Navigatsiya rejimini oʻzgartirish"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Vazifalar panelini ajratkich"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Yuqoriga yoki chapga oʻtkazish"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pastga yoki oʻngga oʻtkazish"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Yana # ta ilovani chiqarish}other{Yana # ta ilovani chiqarish}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> va <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Ilova kompyuterga qoʻshilmoqda"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Bekor qilish"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index ada07bd..dae4212 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Đã bật tính năng Ứng dụng đề xuất"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tính năng Ứng dụng đề xuất bị tắt"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ứng dụng dự đoán: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Hãy vuốt từ mép ngoài cùng bên phải hoặc ngoài cùng bên trái."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Hãy vuốt từ mép phải hoặc mép trái tới giữa màn hình rồi thả tay ra."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Xoay thiết bị của bạn"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Vui lòng xoay thiết bị của bạn để hoàn tất hướng dẫn thao tác bằng cử chỉ"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Hãy vuốt từ mép ngoài cùng bên phải hoặc ngoài cùng bên trái"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Hãy vuốt từ mép phải hoặc mép trái tới giữa màn hình rồi nhấc ngón tay ra"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Bạn đã học được cách vuốt từ mép phải để quay lại. Tiếp theo, hãy tìm hiểu cách chuyển đổi ứng dụng."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Bạn đã thực hiện xong cử chỉ quay lại."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Hãy nhớ không được vuốt quá gần phần cuối màn hình."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Bạn đã thực hiện xong cử chỉ quay lại"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Hãy nhớ không được vuốt quá gần phần dưới cùng của màn hình"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Để thay đổi độ nhạy của cử chỉ quay lại, hãy vào mục Cài đặt"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Vuốt để quay lại"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Để quay lại màn hình gần đây nhất, hãy vuốt từ mép trái hoặc mép phải tới chính giữa màn hình."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Để quay lại màn hình trước đó, hãy vuốt 2 ngón tay từ cạnh trái hoặc phải vào giữa màn hình."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Quay lại"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Hãy vuốt lên từ mép dưới cùng của màn hình."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Hãy nhớ không được tạm dừng trước khi nhấc ngón tay."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Hãy vuốt thẳng lên."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính. Tiếp theo, hãy tìm hiểu cách quay lại."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Hãy vuốt từ mép trái hoặc mép phải tới giữa màn hình"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Hãy vuốt lên từ mép dưới cùng của màn hình"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Hãy nhớ không được dừng trước khi nhấc ngón tay"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Hãy vuốt thẳng lên"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính. Tiếp theo, hãy tìm hiểu cách quay lại."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Vuốt để chuyển đến Màn hình chính"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Vuốt lên từ cuối màn hình. Cử chỉ này luôn đưa bạn đến Màn hình chính."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Vuốt 2 ngón tay lên từ cuối màn hình. Cử chỉ này luôn đưa bạn về Màn hình chính."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Chuyển đến màn hình chính"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Để chuyển đến màn hình chính bất cứ lúc nào, hãy vuốt lên từ cuối màn hình"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Hãy vuốt lên từ mép dưới cùng của màn hình."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Hãy thử giữ cửa sổ lâu hơn trước khi thả tay ra."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Hãy vuốt thẳng lên, sau đó tạm dừng."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Vuốt lên từ mép dưới cùng của màn hình"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Tuyệt vời!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Hãy vuốt lên từ mép dưới cùng của màn hình"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Hãy thử giữ cửa sổ lâu hơn trước khi nhấc ngón tay ra"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Hãy vuốt thẳng lên rồi tạm dừng"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Bạn đã tìm hiểu cách sử dụng cử chỉ. Để tắt cử chỉ, hãy chuyển đến phần Cài đặt."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Bạn đã thực hiện xong cử chỉ chuyển đổi ứng dụng."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Bạn đã thực hiện xong cử chỉ chuyển đổi ứng dụng"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vuốt để chuyển đổi ứng dụng"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Để chuyển đổi giữa các ứng dụng, hãy vuốt lên từ cuối màn hình, giữ rồi thả ra."</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Để chuyển đổi ứng dụng, hãy vuốt lên từ cuối màn hình, giữ rồi thả ra."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Để chuyển đổi giữa các ứng dụng, hãy vuốt 2 ngón tay lên từ cuối màn hình, giữ rồi thả ra."</string>
- <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Chuyển đổi giữa các ứng dụng"</string>
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Chuyển đổi ứng dụng"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Vuốt lên từ mép dưới cùng của màn hình, giữ rồi nhấc ngón tay ra"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Rất tốt!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Đã hoàn tất"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Xong"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Cài đặt"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Chụp ảnh màn hình"</string>
<string name="action_split" msgid="2098009717623550676">"Chia đôi màn hình"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Nhấn vào ứng dụng khác để chia đôi màn hình"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Thoát khỏi lựa chọn chia đôi màn hình"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Chọn một ứng dụng khác để dùng chế độ chia đôi màn hình"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ứng dụng hoặc tổ chức của bạn không cho phép thực hiện hành động này"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Bỏ qua phần hướng dẫn thao tác?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Đã hiện thanh thao tác"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Đã ẩn thanh thao tác"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Thanh điều hướng"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Luôn hiển thị Taskbar"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Thay đổi chế độ điều hướng"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Đường phân chia Taskbar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Chuyển lên trên cùng/sang bên trái"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Chuyển xuống dưới cùng/sang bên phải"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Hiện thêm # ứng dụng.}other{Hiện thêm # ứng dụng.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> và <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Đang thêm ứng dụng vào máy tính"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Huỷ"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 1e3c4ab..3980b21 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已启用应用建议"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用应用建议"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"预测的应用:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"请从最右侧或最左侧边缘开始滑动。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"请从右侧或左侧边缘滑动到屏幕中间位置后再松开手指。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"您已了解如何使用“从右侧向左滑动”手势返回。接下来了解如何切换应用。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"您完成了“返回”手势教程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"请确保滑动时手的位置不要太靠近屏幕底部。"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"请旋转设备"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"请旋转设备,完成手势导航教程"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"确保从最右侧或最左侧边缘开始滑动"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"确保从右侧或左侧边缘滑动到屏幕中间位置后再松开手指"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"您已了解如何使用“从右侧向左滑动”手势返回。接下来学习切换应用吧!"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"您完成了“返回”手势"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"确保滑动时手的位置不要太靠近屏幕底部"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要调节“返回”手势的灵敏度,请转到“设置”"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"滑动即可返回"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一个屏幕,请从屏幕左侧或右侧边缘往屏幕中间滑动。"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"若要返回上一个屏幕,请用两根手指从屏幕左侧或右侧边缘向中间滑动。"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"返回"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"请确保从屏幕底部边缘向上滑动。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"松开手指前,请确保不要停下来。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"请确保直接向上滑动。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"您完成了“转到主屏幕”手势教程。接下来了解如何返回。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"您完成了“转到主屏幕”手势教程。"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"从屏幕左侧或右侧边缘滑动到中间"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"确保从屏幕底部边缘向上滑动"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"松开手指前,请勿中途停顿"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"确保笔直向上滑动"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"您完成了“转到主屏幕”手势。接下来了解如何返回。"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"您完成了“转到主屏幕”手势"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"上滑可转到主屏幕"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"从屏幕底部向上滑动,即可随时回到主屏幕。"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"用两根手指从屏幕底部向上滑动,这个手势会一律使您回到主屏幕。"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"前往主屏幕"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"若要随时前往主屏幕,请从屏幕的底部向上滑动"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"请确保从屏幕底部边缘向上滑动。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"请尝试按住窗口较长时间,然后再松开手指。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"请确保直接向上滑动,然后停住。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"您已了解如何使用手势了。如要关闭手势,请转到“设置”。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"您完成了“切换应用”手势教程。"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"从屏幕底部向上滑动"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"太棒了!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"确保从屏幕底部边缘向上滑动"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"尝试按住窗口较长时间,然后再松开手指"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"确保笔直向上滑动,然后停住"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"您已了解如何使用手势了。如要关闭手势,请前往“设置”。"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"您完成了应用切换手势"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"滑动即可切换应用"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如需在应用之间切换,请从屏幕底部向上滑动后按住,然后松开。"</string>
- <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"若要在应用之间切换,请用两根手指从屏幕底部向上滑动并按住,然后松开。"</string>
+ <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如需在应用之间切换,请从屏幕底部向上滑动,按住,然后松开。"</string>
+ <string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"如需在应用之间切换,请从屏幕底部向上滑动,按住,然后松开。"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"切换应用"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"从屏幕底部向上滑动后按住,然后松开"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"恭喜!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"设置"</string>
@@ -80,7 +86,7 @@
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"教程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"大功告成!"</string>
- <string name="allset_hint" msgid="459504134589971527">"向上滑动可转到主屏幕"</string>
+ <string name="allset_hint" msgid="459504134589971527">"向上滑动可前往主屏幕"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"点按主屏幕按钮即可前往主屏幕"</string>
<string name="allset_description_generic" msgid="5385500062202019855">"您可以开始使用<xliff:g id="DEVICE">%1$s</xliff:g>了"</string>
<string name="default_device_name" msgid="6660656727127422487">"设备"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"屏幕截图"</string>
<string name="action_split" msgid="2098009717623550676">"拆分"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"点按另一个应用即可使用分屏"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"退出分屏选择模式"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"另外选择一个应用才可使用分屏模式"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"该应用或您所在的单位不允许执行此操作"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要跳过导航教程吗?"</string>
@@ -97,7 +104,7 @@
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"跳过"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"旋转屏幕"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"任务栏教程"</string>
- <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"将一个应用拖动到一侧,即可一次使用两个应用"</string>
+ <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"将一个应用拖到一侧,即可一次使用两个应用"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"缓慢向上滑动即可显示任务栏"</string>
<string name="taskbar_edu_suggestions" msgid="8215044496435527982">"根据您的日常安排获取应用建议"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"在设置中开启手势导航后,任务栏会自动隐藏"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"任务栏已显示"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"任务栏已隐藏"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"导航栏"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"始终显示任务栏"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"更改导航模式"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"任务栏分隔线"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到顶部/左侧"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右侧"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{显示另外 # 个应用。}other{显示另外 # 个应用。}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g>和<xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"将应用添加到桌面"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"取消"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 432352a..0532ae5 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -30,11 +30,11 @@
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"少於 1 分鐘"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"今天剩餘時間:<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"應用程式建議"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"您的預測應用程式"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"你的預測應用程式"</string>
<string name="hotseat_edu_title_migrate" msgid="306578144424489980">"在主畫面底部取得應用程式建議"</string>
<string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"在主畫面「我的最愛」列取得應用程式建議"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"在主畫面輕鬆存取常用的應用程式。系統會根據您的日常安排更改建議,並將底部的應用程式移到主畫面。"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"在主畫面輕鬆存取最常用的應用程式。系統會根據您的日常安排變更建議,「我的最愛」列中的應用程式會移至主畫面。"</string>
+ <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"在主畫面輕鬆存取常用的應用程式。系統會根據你的日常安排更改建議,並將底部的應用程式移到主畫面。"</string>
+ <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"在主畫面輕鬆存取最常用的應用程式。系統會根據你的日常安排變更建議,「我的最愛」列中的應用程式會移至主畫面。"</string>
<string name="hotseat_edu_accept" msgid="1611544083278999837">"取得應用程式建議"</string>
<string name="hotseat_edu_dismiss" msgid="2781161822780201689">"不用了,謝謝"</string>
<string name="hotseat_prediction_settings" msgid="6246554993566070818">"設定"</string>
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已啟用應用程式建議"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用應用程式建議"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"請從螢幕右側或左側邊緣滑動。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"請從螢幕右側或左側邊緣往中央滑動,然後放開手指。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"您已瞭解如何透過「由右向左滑動」手勢返回。接下來一起瞭解如何切換應用程式。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"您已完成「返回」手勢的教學課程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"滑動時,手的位置不要太接近螢幕底部。"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"旋轉裝置方向"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"請旋轉裝置方向以完成手勢導覽教學課程"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"請確保從螢幕最右側或最左側邊緣滑動"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"請確保從螢幕右側或左側邊緣往中央滑動,然後放開手指"</string>
+ <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"你已瞭解如何透過「由右向左滑動」手勢返回。接下來一起瞭解如何切換應用程式。"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"你已完成「返回」手勢的教學課程"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"滑動時,手的位置不要太接近螢幕底部"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要變更「返回」手勢的敏感度,請前往「設定」"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"滑動即可返回"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一個畫面,請從螢幕左側或右側邊緣往中央滑動。"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"如要返回上一個畫面,請用 2 隻手指從螢幕左側或右側邊緣往中央滑動。"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"返回"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"放開手指前請勿停下來。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"請向上滑動。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"您已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"您已完成「返回主畫面」手勢的教學課程。"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"從螢幕左側或右側邊緣往中央滑動"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"請確保從螢幕底部邊緣向上滑動"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"放開手指前請勿停下來"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"請確保向上滑動"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"你已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"你已完成「返回主畫面」手勢的教學課程"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"向上滑動即可返回主畫面"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"從螢幕底部向上滑動。這個手勢在所有畫面下都可讓您返回主畫面。"</string>
- <string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"請用 2 隻手指從螢幕底部向上滑動。這個手勢在所有畫面下都可讓您返回主畫面。"</string>
+ <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"從螢幕底部向上滑動。這個手勢在所有畫面下都可讓你返回主畫面。"</string>
+ <string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"請用 2 隻手指從螢幕底部向上滑動。這個手勢在所有畫面下都可讓你返回主畫面。"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"返回主畫面"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"只要從螢幕底部向上滑動,隨時可以返回主畫面"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"請嘗試按住視窗更長時間,然後再放開。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"請向上滑動,然後停住。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"您已學會如何使用手勢。如要關閉手勢,請前往「設定」。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"您已完成「切換應用程式」手勢的教學課程。"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"從螢幕底部向上滑動"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"太好了!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"請確保從螢幕底部邊緣向上滑動"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"請嘗試按住視窗更長時間,然後再放開"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"請向上滑動,然後停住"</string>
+ <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"你已學會如何使用手勢。如要關閉手勢,請前往「設定」。"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"你已完成「切換應用程式」手勢的教學課程"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"滑動即可切換應用程式"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如要切換應用程式,請從螢幕底部向上滑動並按住,然後放開。"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"如要切換應用程式,請用 2 隻手指從螢幕底部向上滑動並按住,然後放開手指。"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"切換應用程式"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"從螢幕底部向上滑動並按住,然後放開"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"做得好!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
@@ -82,26 +88,27 @@
<string name="allset_title" msgid="5021126669778966707">"設定完成!"</string>
<string name="allset_hint" msgid="459504134589971527">"向上滑動即可前往主畫面"</string>
<string name="allset_button_hint" msgid="2395219947744706291">"輕按主按鈕即可前往主畫面"</string>
- <string name="allset_description_generic" msgid="5385500062202019855">"您可以開始使用 <xliff:g id="DEVICE">%1$s</xliff:g> 了"</string>
+ <string name="allset_description_generic" msgid="5385500062202019855">"你可以開始使用<xliff:g id="DEVICE">%1$s</xliff:g>了"</string>
<string name="default_device_name" msgid="6660656727127422487">"裝置"</string>
<string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"系統導覽設定"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"分享"</string>
<string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
<string name="action_split" msgid="2098009717623550676">"分割"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"輕按其他應用程式以使用分割螢幕"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"退出分割螢幕選取頁面"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"選擇其他應用程式才能使用分割螢幕"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"應用程式或您的機構不允許此操作"</string>
+ <string name="blocked_by_policy" msgid="2071401072261365546">"應用程式或你的機構不允許此操作"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要略過手勢操作教學課程嗎?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
+ <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"你之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
<string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
<string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
<string name="accessibility_rotate_button" msgid="4771825231336502943">"旋轉螢幕"</string>
<string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"工作列教學"</string>
<string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"將應用程式拖曳到一邊,即可同時使用 2 個應用程式"</string>
<string name="taskbar_edu_stashing" msgid="5645461372669217294">"慢慢向上滑動即可顯示工作列"</string>
- <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"根據您的日常安排提供應用程式建議"</string>
+ <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"根據你的日常安排提供應用程式建議"</string>
<string name="taskbar_edu_settings_persistent" msgid="1387372982791296151">"在「設定」中啟用手勢操作後,工作列就會自動隱藏"</string>
- <string name="taskbar_edu_features" msgid="3320337287472848162">"工作列助您事半功倍"</string>
+ <string name="taskbar_edu_features" msgid="3320337287472848162">"工作列助你事半功倍"</string>
<string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"住宅"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"顯示咗工作列"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"隱藏咗工作列"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"導覽列"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"一律顯示工作列"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"變更導覽模式"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"工作列分隔線"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移至上方/左側"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移至底部/右側"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{顯示另外 # 個應用程式。}other{顯示另外 # 個應用程式。}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"「<xliff:g id="APP_NAME_1">%1$s</xliff:g>」和「<xliff:g id="APP_NAME_2">%2$s</xliff:g>」"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"正在新增應用程式至桌面"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"取消"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 6926ec5..214fcfd 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"應用程式建議功能已啟用"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"應用程式建議功能已停用"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測的應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"請從螢幕右側或左側邊緣滑動。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"請從螢幕右側或左側邊緣往中央滑動,然後放開手指。"</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"旋轉裝置螢幕方向"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"如要完成手勢操作教學課程,請旋轉裝置螢幕方向"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"請務必從螢幕最右側或最左側滑動"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"請務必從螢幕右側或左側往中央滑動,然後放開手指"</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"你已瞭解如何透過「由右向左滑動」手勢返回。接著,一起來瞭解如何切換應用程式。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"你已完成「返回」手勢的教學課程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"滑動時,手的位置不要太接近螢幕底部。"</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"你已完成「返回」手勢的教學課程"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"滑動時,手的位置不要太接近螢幕底部"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要變更「返回」手勢的敏感度,請前往「設定」"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"滑動即可返回"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一個畫面,請從螢幕左側或右側邊緣往中央滑動。"</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"如要返回上一個畫面,請用 2 指從螢幕左側或右側邊緣往中央滑動。"</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"返回"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"放開手指前請勿停下來。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"請向上滑動。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"你已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"你已完成「返回主畫面」手勢的教學課程。"</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"從螢幕右側或左側往中央滑動"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"請務必從螢幕底部向上滑動"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"放開手指前請勿停下來"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"請務必向上滑動"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"你已完成「返回主畫面」手勢教學課程,接著一起來瞭解如何返回上一個畫面。"</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"你已完成「返回主畫面」手勢的教學課程"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"使用滑動手勢返回主畫面"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"從螢幕底部向上滑動,即可返回主畫面。"</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"用 2 指從螢幕底部向上滑動,即可回到主畫面。"</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"返回主畫面"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"只要從螢幕底部向上滑動,隨時可以返回主畫面"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"請按住視窗久一點,然後再放開。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"請直直向上滑動,然後停住。"</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"從螢幕底部向上滑動"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"太棒了!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"請務必從螢幕底部向上滑動"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"請按住視窗久一點再放開"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"請務必向上滑動,然後停住"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"你已瞭解如何使用手勢了。如要關閉手勢,請前往「設定」。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"你已完成「切換應用程式」手勢的教學課程。"</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"你已完成「切換應用程式」手勢的教學課程"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"使用滑動手勢切換應用程式"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如要切換不同的應用程式,請從螢幕底部向上滑動並按住,然後放開手指。"</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"如要切換應用程式,請用 2 指從螢幕底部向上滑動並按住,然後放開手指。"</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"切換應用程式"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"從螢幕底部向上滑動並按住,然後放開手指"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"非常好!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
<string name="action_split" msgid="2098009717623550676">"分割"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"輕觸另一個應用程式即可使用分割畫面"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"退出分割畫面選擇器"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"必須選擇另一個應用程式才能使用分割畫面"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"這個應用程式或貴機構不允許執行這個動作"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要略過手勢操作教學課程嗎?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"已顯示工作列"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"已隱藏工作列"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"導覽列"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"一律顯示工作列"</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"變更操作模式"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"工作列分隔線"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到上方/左側"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右側"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{顯示另外 # 個應用程式。}other{顯示另外 # 個應用程式。}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"「<xliff:g id="APP_NAME_1">%1$s</xliff:g>」和「<xliff:g id="APP_NAME_2">%2$s</xliff:g>」"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"新增應用程式至桌面"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"取消"</string>
</resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 246b121..9655a44 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -44,35 +44,41 @@
<string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Iziphakamiso zohlelo lokusebenza zinikwe amandla"</string>
<string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Iziphakamiso zohlelo lokusebenza zikhutshaziwe"</string>
<string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Uhlelo lokusebenza olubikezelwe: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Qiniseka ukuthi uswayipha kusuka onqenqemeni olukude ngakwesokudla noma olukude ngakwesokunxele."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Qiniseka ukuthi uswayipha kusuka kunqenqema ongakwesokudla noma ongakwesokunxele kuya maphakathi nesikrini bese uyadedela."</string>
+ <string name="gesture_tutorial_rotation_prompt_title" msgid="7537946781362766964">"Zungezisa idivayisi yakho"</string>
+ <string name="gesture_tutorial_rotation_prompt" msgid="1664493449851960691">"Sicela uzungezise idivayisi yakho ukuze uqedele okokufundisa kokufuna ngokuthinta"</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="4175100312909721217">"Qinisekisa ukuthi uswayipha ukusuka onqenqemeni olukude ngakwesokudla noma olukude ngakwesokunxele"</string>
+ <string name="back_gesture_feedback_cancelled" msgid="762621530959111290">"Qinisekisa ukuthi uswayipha ukusuka kunqenqema olungakwesokudla noma olungakwesokunxele ukuya maphakathi nesikrini bese uyadedela."</string>
<string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ufunde indlela yokuswayipha kusuka kwesokudla ukuze ubuyele emuva. Ngokulandelayo, funda indlela yokushintsha ama-app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ukuqedile ukuthinta kokubuyela emuva."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Qiniseka ukuba awuswayipheli eduze kakhulu naphansi kwesikrini."</string>
+ <string name="back_gesture_feedback_complete_without_follow_up" msgid="197189945858268342">"Ukuqedile ukuthinta kokubuyela emuva"</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="9157480023651452969">"Qinisekisa ukuba awuswayipheli eduze kakhulu naphansi kwesikrini"</string>
<string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Ukuze ushintshe ukuzwela kokuthinta emuva, iya Kumasethingi"</string>
<string name="back_gesture_intro_title" msgid="19551256430224428">"Swayipha ukuze uye emuva"</string>
<string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ukuze ubuyele emuva esikrinini sokugcina, swapha kusuka emngceleni wesobunxele noma wesokudla kuya phakathi kwesikrini."</string>
<string name="back_gesture_spoken_intro_subtitle" msgid="2162043199263088592">"Ukuze ubuyele esikrinini sokugcina, swayipha ngeminwe emi-2 ukusuka kwesokunxele noma kwesokudla emphethweni uye phakathi kwesikrini."</string>
<string name="back_gesture_tutorial_title" msgid="1944737946101059789">"Iya emuva"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Qiniseka ukuthi uswayiphela phezulu kusuka emngceleni ophansi wesikrini."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Qiniseka ukuthi awumisi ngaphambi kokudedela."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Qiniseka ukuthi uswayiphela ngqo phezulu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ukuqedile ukuthinta kokuya Ekhaya. Ngokulandelayo, funda indlela yokuya emuva."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ukuqedile ukuthinta kokuya Ekhaya."</string>
+ <string name="back_gesture_tutorial_subtitle" msgid="6639993416000920142">"Swayipha ukusuka kwesokunxele noma kwesokudla ukuya phakathi kwesikrini"</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="4816365433160895458">"Qiniseka ukuthi uswayiphela phezulu ukusuka emngceleni ophansi wesikrini"</string>
+ <string name="home_gesture_feedback_overview_detected" msgid="5177627157303895077">"Qinisekisa ukuthi awumisi ngaphambi kokudedela"</string>
+ <string name="home_gesture_feedback_wrong_swipe_direction" msgid="8328465201424027148">"Qiniseka ukuthi uswayiphela ngqo phezulu"</string>
+ <string name="home_gesture_feedback_complete_with_follow_up" msgid="8766981412895888417">"Ukuqedile ukuthinta kokuya ekhaya. Ngokulandelayo, funda indlela yokuya emuva."</string>
+ <string name="home_gesture_feedback_complete_without_follow_up" msgid="2978063221383413443">"Ukuqedile ukuthinta kokuya ekhaya"</string>
<string name="home_gesture_intro_title" msgid="836590312858441830">"Swayipha ukuze uye ekhaya"</string>
<string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swayiphela phezulu kusuka phansi kwesikrini sakho.Lokhu kuthinta kuhlala kukusa esikrinini sasekhaya."</string>
<string name="home_gesture_spoken_intro_subtitle" msgid="1030987707382031750">"Swayiphela phezulu ngeminwe emi-2 kusukela phansi esikrinini. Lesi senzo sihlala sikuyisa esikrinini Sasekhaya."</string>
<string name="home_gesture_tutorial_title" msgid="3126834347496917376">"Iya ekhasini lokuqala"</string>
- <string name="home_gesture_tutorial_subtitle" msgid="8979014952569486971">"Ukuze uye esikrinini sakho sasekhaya noma kunini, swayiphela phezulu ukusuka phansi esikrinini sakho"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Qiniseka ukuthi uswayiphela phezulu kusuka emngceleni ophansi wesikrini."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Zama ukubamba iwindi isikhashana ngaphambi kokulidedela."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Qiniseka ukuthi uswayiphela ngqo phezulu bese uyamisa."</string>
+ <string name="home_gesture_tutorial_subtitle" msgid="7245995490408668778">"Swayiphela phezulu ukusuka phansi esikrinini sakho"</string>
+ <string name="home_gesture_tutorial_success" msgid="1736295017642244751">"Umsebenzi omuhle!"</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="6402349235265407385">"Qiniseka ukuthi uswayiphela phezulu ukusuka emngceleni ophansi wesikrini"</string>
+ <string name="overview_gesture_feedback_home_detected" msgid="663432226180397138">"Zama ukubamba iwindi isikhashana ngaphambi kokulidedela"</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="1191055451018584958">"Qinisekisa ukuthi uswayiphela ngqo phezulu bese uyamisa"</string>
<string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ufunde ukusebenzisa ukuthinta. Ukuze uvale ukuthinta, iya kokuthi Amasethingi."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ukuqedile ukuthinta kokushintsha ama-app."</string>
+ <string name="overview_gesture_feedback_complete_without_follow_up" msgid="2903050864432331629">"Ukuqedile ukuthinta kokushintsha ama-app"</string>
<string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swayipha ukuze ushintshe ama-app"</string>
<string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ukuze ushintshe phakathi kwama-app, swayiphela phezulu kusuka ngezansi kwesikrini sakho, bese uyadedela."</string>
<string name="overview_gesture_spoken_intro_subtitle" msgid="3853371838260201751">"Ukuze ushintshe phakathi kwama-app, swayiphela phezulu ngeminwe emi-2 kusukela phansi esikrinini sakho, ubambe, bese uyakhulula."</string>
<string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Shintsha ama-app"</string>
+ <string name="overview_gesture_tutorial_subtitle" msgid="5253549754058973071">"Swayiphela phezulu ukusuka phansi esikrinini sakho, ubambe, bese uyadedela"</string>
+ <string name="overview_gesture_tutorial_success" msgid="1910267697807973076">"Wenze kahle!"</string>
<string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Konke kusethiwe"</string>
<string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Kwenziwe"</string>
<string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Amasethingi"</string>
@@ -89,6 +95,7 @@
<string name="action_screenshot" msgid="8171125848358142917">"Isithombe-skrini"</string>
<string name="action_split" msgid="2098009717623550676">"Hlukanisa"</string>
<string name="toast_split_select_app" msgid="8464310533320556058">"Thepha enye i-app ukuze usebenzise isikrini sokuhlukanisa"</string>
+ <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Phuma ekukhetheni ukuhlukaniswa kwesikrini"</string>
<string name="toast_split_app_unsupported" msgid="2360229567007828914">"Khetha enye i-app ukuze usebenzise ukuhlukanisa isikrini"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Lesi senzo asivunyelwanga uhlelo lokusebenza noma inhlangano yakho"</string>
<string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Yeqa isifundo sokuzulazula?"</string>
@@ -115,8 +122,13 @@
<string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Ibha yomsebenzi ibonisiwe"</string>
<string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Ibha yomsebenzi ifihliwe"</string>
<string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Ibha yokufuna"</string>
+ <string name="always_show_taskbar" msgid="3608801276107751229">"Bonisa i-Taskbar njalo."</string>
+ <string name="change_navigation_mode" msgid="9088393078736808968">"Shintsha imodi yokufuna"</string>
+ <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Isihlukanisi se-Taskbar"</string>
<string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Hamba phezulu/kwesokunxele"</string>
<string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Hamba phansi/kwesokudla"</string>
<string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Bonisa i-app e-# ngaphezulu.}one{Bonisa ama-app angu-# ngaphezulu.}other{Bonisa ama-app angu-# ngaphezulu.}}"</string>
<string name="quick_switch_split_task" msgid="5598194724255333896">"I-<xliff:g id="APP_NAME_1">%1$s</xliff:g> ne-<xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
+ <string name="desktop_select_app_toast" msgid="2306057322833956910">"Yengeza i-app ku-Deskithophu"</string>
+ <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Khansela"</string>
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index b024418..22f98fa 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -44,6 +44,33 @@
<dimen name="overview_task_margin">16dp</dimen>
<!-- The horizontal space between tasks -->
<dimen name="overview_page_spacing">16dp</dimen>
+ <!-- The width of the thumbnail icon menu -->
+ <dimen name="task_thumbnail_icon_menu_min_width">132dp</dimen>
+ <!-- The width of the icon menu text -->
+ <dimen name="task_thumbnail_icon_menu_text_width">62dp</dimen>
+ <!-- The max width of the icon menu text -->
+ <dimen name="task_thumbnail_icon_menu_text_max_width">138dp</dimen>
+ <!-- The max width of the thumbnail icon menu -->
+ <dimen name="task_thumbnail_icon_menu_max_width">216dp</dimen>
+ <!-- The height of the thumbnail icon menu -->
+ <dimen name="task_thumbnail_icon_menu_min_height">36dp</dimen>
+ <!-- The max height of the thumbnail icon menu -->
+ <dimen name="task_thumbnail_icon_menu_max_height">52dp</dimen>
+ <!-- The size of the icon menu arrow -->
+ <dimen name="task_thumbnail_icon_menu_arrow_size">32dp</dimen>
+ <!-- The size of the icon menu arrow drawable -->
+ <dimen name="task_thumbnail_icon_menu_arrow_drawable_size">16dp</dimen>
+ <!-- The margin around the task icon menu -->
+ <dimen name="task_thumbnail_icon_menu_margin">12dp</dimen>
+ <!-- The space around the task icon arrow within the icon menu -->
+ <dimen name="task_thumbnail_icon_menu_arrow_margin">6dp</dimen>
+ <!-- The max space around the task icon within the icon menu -->
+ <dimen name="task_thumbnail_icon_menu_touch_max_margin">8dp</dimen>
+ <!-- The icon size for the icon menu -->
+ <dimen name="task_thumbnail_icon_menu_drawable_size">24dp</dimen>
+ <!-- The size of the icon menu's icon touch target -->
+ <dimen name="task_thumbnail_icon_menu_drawable_touch_size">36dp</dimen>
+ <dimen name="task_thumbnail_icon_menu_elevation">14dp</dimen>
<dimen name="task_icon_cache_default_icon_size">72dp</dimen>
<item name="overview_modal_max_scale" format="float" type="dimen">1.1</item>
@@ -306,7 +333,7 @@
<dimen name="taskbar_home_button_left_margin_kids">48dp</dimen>
<dimen name="taskbar_icon_size_kids">32dp</dimen>
<dimen name="taskbar_all_apps_button_translation_x_offset">6dp</dimen>
-
+ <dimen name="taskbar_all_apps_search_button_translation_x_offset">4.5dp</dimen>
<!-- Transient taskbar -->
<dimen name="transient_taskbar_padding">12dp</dimen>
@@ -317,6 +344,8 @@
<dimen name="transient_taskbar_stashed_height">32dp</dimen>
<dimen name="transient_taskbar_all_apps_button_translation_x_offset">4dp</dimen>
<dimen name="transient_taskbar_stash_spring_velocity_dp_per_s">400dp</dimen>
+ <dimen name="taskbar_tooltip_vertical_padding">8dp</dimen>
+ <dimen name="taskbar_tooltip_horizontal_padding">16dp</dimen>
<!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
<dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
@@ -357,6 +386,7 @@
<!--- Taskbar Pinning -->
<dimen name="taskbar_pinning_popup_menu_width">300dp</dimen>
+ <dimen name="taskbar_pinning_popup_menu_vertical_margin">16dp</dimen>
<!-- Recents overview -->
<dimen name="recents_filter_icon_size">30dp</dimen>
@@ -368,6 +398,7 @@
<dimen name="bubblebar_stashed_handle_height">@dimen/taskbar_stashed_handle_height</dimen>
<dimen name="bubblebar_pointer_size">8dp</dimen>
<dimen name="bubblebar_elevation">1dp</dimen>
+ <dimen name="bubblebar_hotseat_adjustment_threshold">90dp</dimen>
<dimen name="bubblebar_icon_size">50dp</dimen>
<dimen name="bubblebar_badge_size">24dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/HomeTransitionController.java b/quickstep/src/com/android/launcher3/HomeTransitionController.java
new file mode 100644
index 0000000..b264115
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/HomeTransitionController.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.quickstep.SystemUiProxy;
+import com.android.wm.shell.transition.IHomeTransitionListener;
+
+/**
+ * Controls launcher response to home activity visibility changing.
+ */
+public class HomeTransitionController {
+
+ private final QuickstepLauncher mLauncher;
+ @Nullable private IHomeTransitionListener mHomeTransitionListener;
+
+ public HomeTransitionController(QuickstepLauncher launcher) {
+ mLauncher = launcher;
+ }
+
+ public void registerHomeTransitionListener() {
+ mHomeTransitionListener = new IHomeTransitionListener.Stub() {
+ @Override
+ public void onHomeVisibilityChanged(boolean isVisible) {
+ MAIN_EXECUTOR.execute(() -> {
+ if (mLauncher.getTaskbarUIController() != null) {
+ mLauncher.getTaskbarUIController().onLauncherVisibilityChanged(isVisible);
+ }
+ });
+ }
+ };
+
+ SystemUiProxy.INSTANCE.get(mLauncher).setHomeTransitionListener(mHomeTransitionListener);
+ }
+
+ public void unregisterHomeTransitionListener() {
+ SystemUiProxy.INSTANCE.get(mLauncher).setHomeTransitionListener(null);
+ mHomeTransitionListener = null;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 741249d..e77d2c6 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -22,6 +22,8 @@
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OPEN;
@@ -54,6 +56,7 @@
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
+import static com.android.launcher3.util.Executors.ORDERED_BG_EXECUTOR;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
@@ -74,8 +77,8 @@
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
@@ -90,6 +93,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
+import android.provider.Settings.Global;
import android.util.Pair;
import android.util.Size;
import android.view.CrossWindowBlurListeners;
@@ -160,6 +164,7 @@
import com.android.wm.shell.startingsurface.IStartingWindowListener;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@@ -181,9 +186,6 @@
*/
public static final int STATUS_BAR_TRANSITION_PRE_DELAY = 96;
- private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
- "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
-
public static final long APP_LAUNCH_DURATION = 500;
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
@@ -226,7 +228,18 @@
private final float mClosingWindowTransY;
private final float mMaxShadowRadius;
- private final StartingWindowListener mStartingWindowListener = new StartingWindowListener();
+ private final StartingWindowListener mStartingWindowListener =
+ new StartingWindowListener(this);
+ private ContentObserver mAnimationRemovalObserver = new ContentObserver(
+ ORDERED_BG_EXECUTOR.getHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mAreAnimationsEnabled = Global.getFloat(mLauncher.getContentResolver(),
+ Global.ANIMATOR_DURATION_SCALE, 1f) > 0
+ || Global.getFloat(mLauncher.getContentResolver(),
+ Global.TRANSITION_ANIMATION_SCALE, 1f) > 0;
+ }
+ };;
private DeviceProfile mDeviceProfile;
@@ -238,6 +251,8 @@
private RemoteAnimationFactory mWallpaperOpenTransitionRunner;
private RemoteTransition mLauncherOpenTransition;
+ private final RemoteAnimationCoordinateTransfer mCoordinateTransfer;
+
private LauncherBackAnimationController mBackAnimationController;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
@@ -254,6 +269,7 @@
// Pairs of window starting type and starting window background color for starting tasks
// Will never be larger than MAX_NUM_TASKS
private LinkedHashMap<Integer, Pair<Integer, Integer>> mTaskStartParams;
+ private boolean mAreAnimationsEnabled = true;
private final Interpolator mOpeningXInterpolator;
private final Interpolator mOpeningInterpolator;
@@ -264,6 +280,7 @@
mHandler = new Handler(Looper.getMainLooper());
mDeviceProfile = mLauncher.getDeviceProfile();
mBackAnimationController = new LauncherBackAnimationController(mLauncher, this);
+ checkAndMonitorIfAnimationsAreEnabled();
Resources res = mLauncher.getResources();
mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
@@ -271,15 +288,14 @@
mLauncher.addOnDeviceProfileChangeListener(this);
- if (supportsSSplashScreen()) {
- mTaskStartParams = new LinkedHashMap<Integer, Pair<Integer, Integer>>(MAX_NUM_TASKS) {
+ if (ENABLE_SHELL_STARTING_SURFACE) {
+ mTaskStartParams = new LinkedHashMap<>(MAX_NUM_TASKS) {
@Override
protected boolean removeEldestEntry(Entry<Integer, Pair<Integer, Integer>> entry) {
return size() > MAX_NUM_TASKS;
}
};
- mStartingWindowListener.setTransitionManager(this);
SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
mStartingWindowListener);
}
@@ -287,6 +303,7 @@
mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
mOpeningInterpolator = AnimationUtils.loadInterpolator(context,
R.interpolator.emphasized_interpolator);
+ mCoordinateTransfer = new RemoteAnimationCoordinateTransfer(mLauncher);
}
@Override
@@ -311,8 +328,8 @@
mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
ItemInfo tag = (ItemInfo) v.getTag();
if (tag != null && tag.shouldUseBackgroundAnimation()) {
- ContainerAnimationRunner containerAnimationRunner =
- ContainerAnimationRunner.from(v, mStartingWindowListener, onEndCallback);
+ ContainerAnimationRunner containerAnimationRunner = ContainerAnimationRunner.from(
+ v, mLauncher, mStartingWindowListener, onEndCallback);
if (containerAnimationRunner != null) {
mAppLaunchRunner = containerAnimationRunner;
}
@@ -660,7 +677,7 @@
mDragLayer.getLocationOnScreen(dragLayerBounds);
final boolean hasSplashScreen;
- if (supportsSSplashScreen()) {
+ if (ENABLE_SHELL_STARTING_SURFACE) {
int taskId = openingTargets.getFirstAppTargetTaskId();
Pair<Integer, Integer> defaultParams = Pair.create(STARTING_WINDOW_TYPE_NONE, 0);
Pair<Integer, Integer> taskParams =
@@ -905,7 +922,7 @@
RemoteAnimationTarget openingTarget = openingTargets.getFirstAppTarget();
int fallbackBackgroundColor = 0;
- if (openingTarget != null && supportsSSplashScreen()) {
+ if (openingTarget != null && ENABLE_SHELL_STARTING_SURFACE) {
fallbackBackgroundColor = mTaskStartParams.containsKey(openingTarget.taskId)
? mTaskStartParams.get(openingTarget.taskId).second : 0;
mTaskStartParams.remove(openingTarget.taskId);
@@ -1081,11 +1098,9 @@
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
- if (hasControlRemoteAppTransitionPermission()) {
- RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
- addRemoteAnimations(definition);
- mLauncher.registerRemoteAnimations(definition);
- }
+ RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
+ addRemoteAnimations(definition);
+ mLauncher.registerRemoteAnimations(definition);
}
/**
@@ -1123,28 +1138,27 @@
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
- if (hasControlRemoteAppTransitionPermission()) {
- mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
- mLauncherOpenTransition = new RemoteTransition(
- new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
- false /* startAtFrontOfQueue */).toRemoteTransition(),
- mLauncher.getIApplicationThread(), "QuickstepLaunchHome");
- TransitionFilter homeCheck = new TransitionFilter();
- // No need to handle the transition that also dismisses keyguard.
- homeCheck.mNotFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
- homeCheck.mRequirements =
- new TransitionFilter.Requirement[]{new TransitionFilter.Requirement(),
- new TransitionFilter.Requirement()};
- homeCheck.mRequirements[0].mActivityType = ACTIVITY_TYPE_HOME;
- homeCheck.mRequirements[0].mTopActivity = mLauncher.getComponentName();
- homeCheck.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
- homeCheck.mRequirements[0].mOrder = CONTAINER_ORDER_TOP;
- homeCheck.mRequirements[1].mActivityType = ACTIVITY_TYPE_STANDARD;
- homeCheck.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
- SystemUiProxy.INSTANCE.get(mLauncher)
- .registerRemoteTransition(mLauncherOpenTransition, homeCheck);
- }
+ mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
+ mLauncherOpenTransition = new RemoteTransition(
+ new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
+ false /* startAtFrontOfQueue */).toRemoteTransition(),
+ mLauncher.getIApplicationThread(), "QuickstepLaunchHome");
+
+ TransitionFilter homeCheck = new TransitionFilter();
+ // No need to handle the transition that also dismisses keyguard.
+ homeCheck.mNotFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
+ homeCheck.mRequirements =
+ new TransitionFilter.Requirement[]{new TransitionFilter.Requirement(),
+ new TransitionFilter.Requirement()};
+ homeCheck.mRequirements[0].mActivityType = ACTIVITY_TYPE_HOME;
+ homeCheck.mRequirements[0].mTopActivity = mLauncher.getComponentName();
+ homeCheck.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
+ homeCheck.mRequirements[0].mOrder = CONTAINER_ORDER_TOP;
+ homeCheck.mRequirements[1].mActivityType = ACTIVITY_TYPE_STANDARD;
+ homeCheck.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
+ SystemUiProxy.INSTANCE.get(mLauncher)
+ .registerRemoteTransition(mLauncherOpenTransition, homeCheck);
if (mBackAnimationController != null) {
mBackAnimationController.registerBackCallbacks(mHandler);
}
@@ -1153,23 +1167,22 @@
public void onActivityDestroyed() {
unregisterRemoteAnimations();
unregisterRemoteTransitions();
- mStartingWindowListener.setTransitionManager(null);
SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null);
+ ORDERED_BG_EXECUTOR.execute(() -> mLauncher.getContentResolver()
+ .unregisterContentObserver(mAnimationRemovalObserver));
}
private void unregisterRemoteAnimations() {
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
- if (hasControlRemoteAppTransitionPermission()) {
- mLauncher.unregisterRemoteAnimations();
+ mLauncher.unregisterRemoteAnimations();
- // Also clear strong references to the runners registered with the remote animation
- // definition so we don't have to wait for the system gc
- mWallpaperOpenRunner = null;
- mAppLaunchRunner = null;
- mKeyguardGoingAwayRunner = null;
- }
+ // Also clear strong references to the runners registered with the remote animation
+ // definition so we don't have to wait for the system gc
+ mWallpaperOpenRunner = null;
+ mAppLaunchRunner = null;
+ mKeyguardGoingAwayRunner = null;
}
protected void unregisterRemoteTransitions() {
@@ -1179,19 +1192,28 @@
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
- if (hasControlRemoteAppTransitionPermission()) {
- if (mLauncherOpenTransition == null) return;
- SystemUiProxy.INSTANCE.get(mLauncher).unregisterRemoteTransition(
- mLauncherOpenTransition);
- mLauncherOpenTransition = null;
- mWallpaperOpenTransitionRunner = null;
- }
+ if (mLauncherOpenTransition == null) return;
+ SystemUiProxy.INSTANCE.get(mLauncher).unregisterRemoteTransition(
+ mLauncherOpenTransition);
+ mLauncherOpenTransition = null;
+ mWallpaperOpenTransitionRunner = null;
if (mBackAnimationController != null) {
mBackAnimationController.unregisterBackCallbacks();
mBackAnimationController = null;
}
}
+ private void checkAndMonitorIfAnimationsAreEnabled() {
+ ORDERED_BG_EXECUTOR.execute(() -> {
+ mAnimationRemovalObserver.onChange(true);
+ mLauncher.getContentResolver().registerContentObserver(Global.getUriFor(
+ Global.ANIMATOR_DURATION_SCALE), false, mAnimationRemovalObserver);
+ mLauncher.getContentResolver().registerContentObserver(Global.getUriFor(
+ Global.TRANSITION_ANIMATION_SCALE), false, mAnimationRemovalObserver);
+
+ });
+ }
+
private boolean launcherIsATargetWithMode(RemoteAnimationTarget[] targets, int mode) {
for (RemoteAnimationTarget target : targets) {
if (target.mode == mode && target.taskInfo != null
@@ -1370,7 +1392,7 @@
(LauncherAppWidgetHostView) launcherView, targetRect, windowSize,
mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher),
isTransluscent, fallbackBackgroundColor);
- } else if (launcherView != null) {
+ } else if (launcherView != null && mAreAnimationsEnabled) {
floatingIconView = getFloatingIconView(mLauncher, launcherView, null,
mLauncher.getTaskbarUIController() == null
? null
@@ -1389,8 +1411,9 @@
targetRect));
// Hook up floating views to the closing window animators.
- final int rotationChange = getRotationChange(targets);
- Rect windowTargetBounds = getWindowTargetBounds(targets, rotationChange);
+ // note the coordinate of closingWindowStartRect is based on launcher
+ Rect windowTargetBounds = new Rect();
+ closingWindowStartRect.round(windowTargetBounds);
if (floatingIconView != null) {
anim.addAnimatorListener(floatingIconView);
floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
@@ -1519,20 +1542,6 @@
return closingAnimator;
}
- private boolean supportsSSplashScreen() {
- return hasControlRemoteAppTransitionPermission()
- && Utilities.ATLEAST_S
- && ENABLE_SHELL_STARTING_SURFACE;
- }
-
- /**
- * Returns true if we have permission to control remote app transisions
- */
- public boolean hasControlRemoteAppTransitionPermission() {
- return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
- == PackageManager.PERMISSION_GRANTED;
- }
-
private void addCujInstrumentation(Animator anim, int cuj) {
anim.addListener(new AnimationSuccessListener() {
@Override
@@ -1694,8 +1703,18 @@
RectF windowTargetBounds =
new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets)));
+
+ final RectF resolveRectF = new RectF(windowTargetBounds);
+ for (RemoteAnimationTarget t : appTargets) {
+ if (t.mode == MODE_CLOSING) {
+ transferRectToTargetCoordinate(
+ t, windowTargetBounds, true, resolveRectF);
+ break;
+ }
+ }
+
Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds,
+ appTargets, wallpaperTargets, mFromUnlock, resolveRectF,
QuickStepContract.getWindowCornerRadius(mLauncher),
false /* fromPredictiveBack */);
@@ -1776,11 +1795,11 @@
}
@Nullable
- private static ContainerAnimationRunner from(
- View v, StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
+ private static ContainerAnimationRunner from(View v, Launcher launcher,
+ StartingWindowListener startingWindowListener, RunnableList onEndCallback) {
View viewToUse = findLaunchableViewWithBackground(v);
if (viewToUse == null) {
- viewToUse = v;
+ return null;
}
// The CUJ is logged by the click handler, so we don't log it inside the animation
@@ -1802,8 +1821,13 @@
}
};
- ActivityLaunchAnimator.Callback callback = task -> ColorUtils.setAlphaComponent(
- startingWindowListener.getBackgroundColor(), 255);
+ ActivityLaunchAnimator.Callback callback = task -> {
+ final int backgroundColor =
+ startingWindowListener.mBackgroundColor == Color.TRANSPARENT
+ ? launcher.getScrimView().getBackgroundColor()
+ : startingWindowListener.mBackgroundColor;
+ return ColorUtils.setAlphaComponent(backgroundColor, 255);
+ };
ActivityLaunchAnimator.Listener listener = new ActivityLaunchAnimator.Listener() {
@Override
@@ -1917,24 +1941,67 @@
}
}
- private class StartingWindowListener extends IStartingWindowListener.Stub {
- private QuickstepTransitionManager mTransitionManager;
+ private static class StartingWindowListener extends IStartingWindowListener.Stub {
+ private final WeakReference<QuickstepTransitionManager> mTransitionManagerRef;
private int mBackgroundColor;
- public void setTransitionManager(QuickstepTransitionManager transitionManager) {
- mTransitionManager = transitionManager;
+ private StartingWindowListener(QuickstepTransitionManager transitionManager) {
+ mTransitionManagerRef = new WeakReference<>(transitionManager);
}
@Override
public void onTaskLaunching(int taskId, int supportedType, int color) {
- mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
+ QuickstepTransitionManager transitionManager = mTransitionManagerRef.get();
+ if (transitionManager != null) {
+ transitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
+ }
mBackgroundColor = color;
}
+ }
- public int getBackgroundColor() {
- return mBackgroundColor == Color.TRANSPARENT
- ? mLauncher.getScrimView().getBackgroundColor()
- : mBackgroundColor;
+ /**
+ * Transfer the rectangle to another coordinate if needed.
+ * @param toLauncher which one is the anchor of this transfer, if true then transfer from
+ * animation target to launcher, false transfer from launcher to animation
+ * target.
+ */
+ public void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect,
+ boolean toLauncher, RectF resultRect) {
+ mCoordinateTransfer.transferRectToTargetCoordinate(
+ target, currentRect, toLauncher, resultRect);
+ }
+
+ private static class RemoteAnimationCoordinateTransfer {
+ private final QuickstepLauncher mLauncher;
+ private final Rect mDisplayRect = new Rect();
+ private final Rect mTmpResult = new Rect();
+
+ RemoteAnimationCoordinateTransfer(QuickstepLauncher launcher) {
+ mLauncher = launcher;
+ }
+
+ void transferRectToTargetCoordinate(RemoteAnimationTarget target, RectF currentRect,
+ boolean toLauncher, RectF resultRect) {
+ final int taskRotation = target.windowConfiguration.getRotation();
+ final DeviceProfile profile = mLauncher.getDeviceProfile();
+
+ final int rotationDelta = toLauncher
+ ? android.util.RotationUtils.deltaRotation(taskRotation, profile.rotationHint)
+ : android.util.RotationUtils.deltaRotation(profile.rotationHint, taskRotation);
+ if (rotationDelta != ROTATION_0) {
+ // Get original display size when task is on top but with different rotation
+ if (rotationDelta % 2 != 0 && toLauncher && (profile.rotationHint == ROTATION_0
+ || profile.rotationHint == ROTATION_180)) {
+ mDisplayRect.set(0, 0, profile.heightPx, profile.widthPx);
+ } else {
+ mDisplayRect.set(0, 0, profile.widthPx, profile.heightPx);
+ }
+ currentRect.round(mTmpResult);
+ android.util.RotationUtils.rotateBounds(mTmpResult, mDisplayRect, rotationDelta);
+ resultRect.set(mTmpResult);
+ } else {
+ resultRect.set(currentRect);
+ }
}
}
@@ -1960,6 +2027,20 @@
mEndRadius = Math.max(1, targetRect.width()) / 2f;
mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer);
mWindowTargetBounds.set(windowTargetBounds);
+
+ // transfer the coordinate based on animation target.
+ if (mAppTargets != null) {
+ for (RemoteAnimationTarget t : mAppTargets) {
+ if (t.mode == MODE_CLOSING) {
+ final RectF targetBounds = new RectF(mWindowTargetBounds);
+ final RectF result = new RectF();
+ transferRectToTargetCoordinate(
+ t, targetBounds, false, result);
+ result.round(mWindowTargetBounds);
+ break;
+ }
+ }
+ }
}
public float getCornerRadius(float progress) {
@@ -1980,6 +2061,8 @@
}
if (target.mode == MODE_CLOSING) {
+ final RectF before = new RectF(currentRectF);
+ transferRectToTargetCoordinate(target, currentRectF, false, currentRectF);
currentRectF.round(mCurrentRect);
// Scale the target window to match the currentRectF.
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index e8374b8..037f7a8 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -35,9 +35,7 @@
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
/**
* A view which shows a horizontal divider
@@ -93,10 +91,7 @@
? R.color.all_apps_label_text_dark
: R.color.all_apps_label_text);
- OnboardingPrefs<?> onboardingPrefs = ActivityContext.lookupContext(
- getContext()).getOnboardingPrefs();
- mShowAllAppsLabel = onboardingPrefs == null || !onboardingPrefs.hasReachedMaxCount(
- ALL_APPS_VISITED_COUNT);
+ mShowAllAppsLabel = !ALL_APPS_VISITED_COUNT.hasReachedMax(context);
}
public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index f82474a..1440498 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -36,6 +36,7 @@
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.keyboard.FocusIndicatorHelper;
import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
import com.android.launcher3.model.data.ItemInfo;
@@ -126,6 +127,10 @@
int verticalPadding = getResources().getDimensionPixelSize(
R.dimen.all_apps_predicted_icon_vertical_padding);
int totalHeight = iconHeight + iconPadding + textHeight + verticalPadding * 2;
+ if (FeatureFlags.enableTwolineAllapps()) {
+ // Add extra textHeight to the existing total height.
+ totalHeight += textHeight;
+ }
return getVisibility() == GONE ? 0 : totalHeight + getPaddingTop() + getPaddingBottom();
}
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
new file mode 100644
index 0000000..10733fb
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.desktop
+
+import android.app.IApplicationThread
+import android.os.IBinder
+import android.os.RemoteException
+import android.util.Log
+import android.view.SurfaceControl
+import android.window.IRemoteTransition
+import android.window.IRemoteTransitionFinishedCallback
+import android.window.RemoteTransition
+import android.window.TransitionInfo
+import com.android.launcher3.statehandlers.DepthController
+import com.android.launcher3.statemanager.StateManager
+import com.android.launcher3.util.Executors.MAIN_EXECUTOR
+import com.android.quickstep.SystemUiProxy
+import com.android.quickstep.TaskViewUtils
+import com.android.quickstep.views.DesktopTaskView
+import java.util.function.Consumer
+
+/** Manage recents related operations with desktop tasks */
+class DesktopRecentsTransitionController(
+ private val stateManager: StateManager<*>,
+ private val systemUiProxy: SystemUiProxy,
+ private val appThread: IApplicationThread,
+ private val depthController: DepthController?
+) {
+
+ /** Launch desktop tasks from recents view */
+ fun launchDesktopFromRecents(
+ desktopTaskView: DesktopTaskView,
+ callback: Consumer<Boolean>? = null
+ ) {
+ val animRunner =
+ RemoteDesktopLaunchTransitionRunner(
+ desktopTaskView,
+ stateManager,
+ depthController,
+ callback
+ )
+ val transition = RemoteTransition(animRunner, appThread, "RecentsToDesktop")
+ systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition)
+ }
+
+ private class RemoteDesktopLaunchTransitionRunner(
+ private val desktopTaskView: DesktopTaskView,
+ private val stateManager: StateManager<*>,
+ private val depthController: DepthController?,
+ private val successCallback: Consumer<Boolean>?
+ ) : IRemoteTransition.Stub() {
+
+ override fun startAnimation(
+ token: IBinder,
+ info: TransitionInfo,
+ t: SurfaceControl.Transaction,
+ finishCallback: IRemoteTransitionFinishedCallback
+ ) {
+ val errorHandlingFinishCallback = Runnable {
+ try {
+ finishCallback.onTransitionFinished(null /* wct */, null /* sct */)
+ } catch (e: RemoteException) {
+ Log.e(TAG, "Failed to call finish callback for desktop recents animation", e)
+ }
+ }
+
+ MAIN_EXECUTOR.execute {
+ TaskViewUtils.composeRecentsDesktopLaunchAnimator(
+ desktopTaskView,
+ stateManager,
+ depthController,
+ info,
+ t
+ ) {
+ errorHandlingFinishCallback.run()
+ successCallback?.accept(true)
+ }
+ }
+ }
+
+ override fun mergeAnimation(
+ transition: IBinder,
+ info: TransitionInfo,
+ t: SurfaceControl.Transaction,
+ mergeTarget: IBinder,
+ finishCallback: IRemoteTransitionFinishedCallback
+ ) {}
+
+ override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {
+ }
+ }
+
+ companion object {
+ const val TAG = "DesktopRecentsTransitionController"
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index a63f9e8..baea418 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -23,6 +23,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -41,6 +42,7 @@
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Hotseat;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
@@ -59,7 +61,6 @@
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.views.Snackbar;
import java.io.PrintWriter;
@@ -104,12 +105,11 @@
if (mLauncher.getWorkspace().isSwitchingState()) return false;
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onWorkspaceItemLongClick");
- if (mEnableHotseatLongPressTipForTesting && !mLauncher.getOnboardingPrefs().getBoolean(
- OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN)) {
+ if (mEnableHotseatLongPressTipForTesting && !HOTSEAT_LONGPRESS_TIP_SEEN.get(mLauncher)) {
Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
R.string.hotseat_prediction_settings, null,
() -> mLauncher.startActivity(getSettingsIntent()));
- mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN);
+ LauncherPrefs.get(mLauncher).put(HOTSEAT_LONGPRESS_TIP_SEEN, true);
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
diff --git a/quickstep/src/com/android/launcher3/model/PredictionHelper.java b/quickstep/src/com/android/launcher3/model/PredictionHelper.java
index 738dd83..dbd99e1 100644
--- a/quickstep/src/com/android/launcher3/model/PredictionHelper.java
+++ b/quickstep/src/com/android/launcher3/model/PredictionHelper.java
@@ -67,6 +67,9 @@
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return new AppTarget.Builder(new AppTargetId("folder:" + info.id),
context.getPackageName(), info.user).build();
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR) {
+ return new AppTarget.Builder(new AppTargetId("app_pair:" + info.id),
+ context.getPackageName(), info.user).build();
}
return null;
}
diff --git a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
index e504141..2fcbe4e 100644
--- a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
@@ -15,8 +15,9 @@
*/
package com.android.launcher3.model;
+import static com.android.launcher3.LauncherPrefs.nonRestorableItem;
+import static com.android.launcher3.EncryptionType.ENCRYPTED;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
-import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE;
import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
import android.app.prediction.AppTarget;
@@ -29,6 +30,7 @@
import androidx.annotation.NonNull;
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -47,6 +49,9 @@
*/
public class PredictionUpdateTask extends BaseModelUpdateTask {
+ public static final ConstantItem<Boolean> LAST_PREDICTION_ENABLED =
+ nonRestorableItem("last_prediction_enabled_state", true, ENCRYPTED);
+
private final List<AppTarget> mTargets;
private final PredictorState mPredictorState;
@@ -61,8 +66,7 @@
Context context = app.getContext();
// TODO: remove this
- LauncherPrefs.getDevicePrefs(context).edit()
- .putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply();
+ LauncherPrefs.get(context).put(LAST_PREDICTION_ENABLED, !mTargets.isEmpty());
Set<UserHandle> usersForChangedShortcuts =
dataModel.extraItems.get(mPredictorState.containerId).items.stream()
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 32361a8..667f784 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -18,7 +18,8 @@
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.formatElapsedTime;
-import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
+import static com.android.launcher3.LauncherPrefs.nonRestorableItem;
+import static com.android.launcher3.EncryptionType.ENCRYPTED;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
@@ -39,7 +40,6 @@
import android.app.prediction.AppTargetEvent;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
@@ -55,8 +55,10 @@
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.InstanceId;
@@ -86,14 +88,15 @@
*/
public class QuickstepModelDelegate extends ModelDelegate {
- public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
- private static final String LAST_SNAPSHOT_TIME_MILLIS = "LAST_SNAPSHOT_TIME_MILLIS";
private static final String BUNDLE_KEY_ADDED_APP_WIDGETS = "added_app_widgets";
private static final int NUM_OF_RECOMMENDED_WIDGETS_PREDICATION = 20;
private static final boolean IS_DEBUG = false;
private static final String TAG = "QuickstepModelDelegate";
+ private static final ConstantItem<Long> LAST_SNAPSHOT_TIME_MILLIS =
+ nonRestorableItem("LAST_SNAPSHOT_TIME_MILLIS", 0L, ENCRYPTED);
+
@VisibleForTesting
final PredictorState mAllAppsState =
new PredictorState(CONTAINER_PREDICTION, "all_apps_predictions");
@@ -211,8 +214,8 @@
super.modelLoadComplete();
// Log snapshot of the model
- SharedPreferences prefs = getDevicePrefs(mApp.getContext());
- long lastSnapshotTimeMillis = prefs.getLong(LAST_SNAPSHOT_TIME_MILLIS, 0);
+ LauncherPrefs prefs = LauncherPrefs.get(mApp.getContext());
+ long lastSnapshotTimeMillis = prefs.get(LAST_SNAPSHOT_TIME_MILLIS);
// Log snapshot only if previous snapshot was older than a day
long now = System.currentTimeMillis();
if (now - lastSnapshotTimeMillis < DAY_IN_MILLIS) {
@@ -233,7 +236,7 @@
StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId);
}
additionalSnapshotEvents(instanceId);
- prefs.edit().putLong(LAST_SNAPSHOT_TIME_MILLIS, now).apply();
+ prefs.put(LAST_SNAPSHOT_TIME_MILLIS, now);
}
// Only register for launcher snapshot logging if this is the primary ModelDelegate
diff --git a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
index b982688..8b71f01 100644
--- a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
+++ b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java
@@ -22,7 +22,6 @@
import com.android.launcher3.appprediction.AppsDividerView;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.views.ActivityContext;
/**
@@ -30,22 +29,21 @@
*/
@SuppressWarnings("unused")
public final class SecondaryDisplayPredictionsImpl extends SecondaryDisplayPredictions {
+
private final ActivityContext mActivityContext;
+ private final Context mContext;
public SecondaryDisplayPredictionsImpl(Context context) {
+ mContext = context;
mActivityContext = ActivityContext.lookupContext(context);
}
@Override
void updateAppDivider() {
- OnboardingPrefs<?> onboardingPrefs = mActivityContext.getOnboardingPrefs();
- if (onboardingPrefs != null) {
- mActivityContext.getAppsView().getFloatingHeaderView()
- .findFixedRowByType(AppsDividerView.class)
- .setShowAllAppsLabel(
- !onboardingPrefs.hasReachedMaxCount(ALL_APPS_VISITED_COUNT));
- onboardingPrefs.incrementEventCount(ALL_APPS_VISITED_COUNT);
- }
+ mActivityContext.getAppsView().getFloatingHeaderView()
+ .findFixedRowByType(AppsDividerView.class)
+ .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(mContext));
+ ALL_APPS_VISITED_COUNT.increment(mContext);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index ecf483c..a7e8118 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -15,8 +15,11 @@
*/
package com.android.launcher3.statehandlers;
+import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
+import android.os.Debug;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
@@ -46,6 +49,7 @@
private boolean mFreeformTasksVisible;
private boolean mInOverviewState;
+ private boolean mBackgroundStateEnabled;
private boolean mGestureInProgress;
@Nullable
@@ -103,18 +107,14 @@
}
/**
- * Whether desktop mode is supported.
- */
- private boolean isDesktopModeSupported() {
- return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false)
- || SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
- }
-
- /**
* Whether freeform windows are visible in desktop mode.
*/
public boolean areFreeformTasksVisible() {
- return mFreeformTasksVisible;
+ if (DEBUG) {
+ Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + mFreeformTasksVisible
+ + " overview=" + mInOverviewState);
+ }
+ return mFreeformTasksVisible && !mInOverviewState;
}
/**
@@ -122,7 +122,8 @@
*/
public void setFreeformTasksVisible(boolean freeformTasksVisible) {
if (DEBUG) {
- Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible);
+ Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible
+ + " currentValue=" + mFreeformTasksVisible);
}
if (!isDesktopModeSupported()) {
return;
@@ -147,11 +148,21 @@
}
/**
- * Sets whether the overview is visible and updates launcher visibility based on that.
+ * Process launcher state change and update launcher view visibility based on desktop state
*/
- public void setOverviewStateEnabled(boolean overviewStateEnabled) {
+ public void onLauncherStateChanged(LauncherState state) {
if (DEBUG) {
- Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled);
+ Log.d(TAG, "onLauncherStateChanged: newState=" + state);
+ }
+ setBackgroundStateEnabled(state == BACKGROUND_APP);
+ // Desktop visibility tracks overview and background state separately
+ setOverviewStateEnabled(state != BACKGROUND_APP && state.overviewUi);
+ }
+
+ private void setOverviewStateEnabled(boolean overviewStateEnabled) {
+ if (DEBUG) {
+ Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled
+ + " currentValue=" + mInOverviewState);
}
if (!isDesktopModeSupported()) {
return;
@@ -161,7 +172,30 @@
if (mInOverviewState) {
setLauncherViewsVisibility(View.VISIBLE);
markLauncherResumed();
- } else if (mFreeformTasksVisible) {
+ } else if (areFreeformTasksVisible() && !mGestureInProgress) {
+ // Switching out of overview state and gesture finished.
+ // If freeform tasks are still visible, hide launcher again.
+ setLauncherViewsVisibility(View.INVISIBLE);
+ markLauncherPaused();
+ }
+ }
+ }
+
+ private void setBackgroundStateEnabled(boolean backgroundStateEnabled) {
+ if (DEBUG) {
+ Log.d(TAG, "setBackgroundStateEnabled: enabled=" + backgroundStateEnabled
+ + " currentValue=" + mBackgroundStateEnabled);
+ }
+ if (!isDesktopModeSupported()) {
+ return;
+ }
+ if (backgroundStateEnabled != mBackgroundStateEnabled) {
+ mBackgroundStateEnabled = backgroundStateEnabled;
+ if (mBackgroundStateEnabled) {
+ setLauncherViewsVisibility(View.VISIBLE);
+ markLauncherResumed();
+ } else if (areFreeformTasksVisible() && !mGestureInProgress) {
+ // Switching out of background state. If freeform tasks are visible, pause launcher.
setLauncherViewsVisibility(View.INVISIBLE);
markLauncherPaused();
}
@@ -182,6 +216,9 @@
if (!isDesktopModeSupported()) {
return;
}
+ if (DEBUG) {
+ Log.d(TAG, "setRecentsGestureStart");
+ }
setRecentsGestureInProgress(true);
}
@@ -193,6 +230,9 @@
if (!isDesktopModeSupported()) {
return;
}
+ if (DEBUG) {
+ Log.d(TAG, "setRecentsGestureEnd: endTarget=" + endTarget);
+ }
setRecentsGestureInProgress(false);
if (endTarget == null) {
@@ -202,9 +242,6 @@
}
private void setRecentsGestureInProgress(boolean gestureInProgress) {
- if (DEBUG) {
- Log.d(TAG, "setGestureInProgress: inProgress=" + gestureInProgress);
- }
if (gestureInProgress != mGestureInProgress) {
mGestureInProgress = gestureInProgress;
}
@@ -221,7 +258,8 @@
private void setLauncherViewsVisibility(int visibility) {
if (DEBUG) {
- Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility);
+ Log.d(TAG, "setLauncherViewsVisibility: visibility=" + visibility + " "
+ + Debug.getCaller());
}
View workspaceView = mLauncher.getWorkspace();
if (workspaceView != null) {
@@ -235,7 +273,7 @@
private void markLauncherPaused() {
if (DEBUG) {
- Log.d(TAG, "markLauncherPaused");
+ Log.d(TAG, "markLauncherPaused " + Debug.getCaller());
}
StatefulActivity<LauncherState> activity =
QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
@@ -246,7 +284,7 @@
private void markLauncherResumed() {
if (DEBUG) {
- Log.d(TAG, "markLauncherResumed");
+ Log.d(TAG, "markLauncherResumed " + Debug.getCaller());
}
StatefulActivity<LauncherState> activity =
QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
index 331184a..c201236 100644
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
@@ -20,8 +20,6 @@
import android.view.LayoutInflater;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -34,12 +32,10 @@
protected final LayoutInflater mLayoutInflater;
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
- private final OnboardingPrefs<BaseTaskbarContext> mOnboardingPrefs;
public BaseTaskbarContext(Context windowContext) {
super(windowContext, Themes.getActivityThemeRes(windowContext));
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
- mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
}
@Override
@@ -52,11 +48,6 @@
return mDPChangeListeners;
}
- @Override
- public OnboardingPrefs<BaseTaskbarContext> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
/** Callback invoked when a drag is initiated within this context. */
public abstract void onDragStart();
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
index 885afff..29c5204 100644
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_NOTIFICATIONS;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_QUICK_SETTINGS;
+import android.content.pm.ActivityInfo.Config;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -56,6 +57,11 @@
@Override
public void init(TaskbarControllers controllers) {
mControllers = controllers;
+ super.init(controllers);
+ }
+
+ @Override
+ protected void setupController() {
mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarHeight;
// Quick settings and notifications buttons
@@ -72,4 +78,7 @@
/** Cleans up on destroy */
@Override
public void onDestroy() { }
+
+ @Override
+ public void onConfigurationChanged(@Config int configChanges) { }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index 072fc30..f58fd45 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
+
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
@@ -28,7 +30,6 @@
import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -109,7 +110,7 @@
DesktopVisibilityController desktopController =
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
final boolean onDesktop =
- DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED
+ isDesktopModeSupported()
&& desktopController != null
&& desktopController.areFreeformTasksVisible();
@@ -136,7 +137,7 @@
// Hide all desktop tasks and show them on the hidden tile
int hiddenDesktopTasks = 0;
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
DesktopTask desktopTask = findDesktopTask(tasks);
if (desktopTask != null) {
hiddenDesktopTasks = desktopTask.tasks.size();
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 3e1a6ae..a9d50b9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -40,6 +40,8 @@
import java.util.function.Consumer;
+import kotlin.Unit;
+
/**
* A view that displays a recent task during a keyboard quick switch.
*/
@@ -96,17 +98,18 @@
Resources resources = mContext.getResources();
Preconditions.assertNotNull(mContent);
- mBorderAnimator = new BorderAnimator(
+ mBorderAnimator = BorderAnimator.createScalingBorderAnimator(
/* borderRadiusPx= */ resources.getDimensionPixelSize(
R.dimen.keyboard_quick_switch_task_view_radius),
- /* borderColor= */ mBorderColor,
- /* borderAnimationParams= */ new BorderAnimator.ScalingParams(
- /* borderWidthPx= */ resources.getDimensionPixelSize(
+ /* borderWidthPx= */ resources.getDimensionPixelSize(
R.dimen.keyboard_quick_switch_border_width),
- /* boundsBuilder= */ bounds -> bounds.set(
- 0, 0, getWidth(), getHeight()),
- /* targetView= */ this,
- /* contentView= */ mContent));
+ /* boundsBuilder= */ bounds -> {
+ bounds.set(0, 0, getWidth(), getHeight());
+ return Unit.INSTANCE;
+ },
+ /* targetView= */ this,
+ /* contentView= */ mContent,
+ /* borderColor= */ mBorderColor);
}
@Nullable
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index 4e9e301..42c423c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -46,6 +46,8 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
+import com.android.launcher3.testing.TestLogging;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.quickstep.util.GroupTask;
import java.util.HashMap;
@@ -360,11 +362,8 @@
OPEN_OUTLINE_INTERPOLATOR));
}
});
- if (currentFocusIndexOverride == -1) {
- initializeScroll(/* index= */ 0, /* shouldTruncateTarget= */ false);
- } else {
- animateFocusMove(-1, currentFocusIndexOverride);
- }
+ animateFocusMove(-1, currentFocusIndexOverride == -1
+ ? Math.min(mContent.getChildCount(), 1) : currentFocusIndexOverride);
displayedContent.setVisibility(VISIBLE);
setVisibility(VISIBLE);
requestFocus();
@@ -413,7 +412,8 @@
// there are more tasks
initializeScroll(
firstVisibleTaskIndex,
- /* shouldTruncateTarget= */ firstVisibleTaskIndex != toIndex);
+ /* shouldTruncateTarget= */ firstVisibleTaskIndex != 0
+ && firstVisibleTaskIndex != toIndex);
} else if (toIndex > fromIndex || toIndex == 0) {
// Scrolling to next task view
if (mIsRtl) {
@@ -439,6 +439,13 @@
}
@Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ TestLogging.recordKeyEvent(
+ TestProtocol.SEQUENCE_MAIN, "KeyboardQuickSwitchView key event", event);
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return (mViewCallbacks != null
&& mViewCallbacks.onKeyUp(keyCode, event, mIsRtl, mDisplayingRecentTasks))
@@ -454,56 +461,80 @@
return;
}
if (mIsRtl) {
- scrollRightTo(
- task, shouldTruncateTarget, /* smoothScroll= */ false);
- } else {
scrollLeftTo(
- task, shouldTruncateTarget, /* smoothScroll= */ false);
+ task,
+ shouldTruncateTarget,
+ /* smoothScroll= */ false,
+ /* waitForLayout= */ true);
+ } else {
+ scrollRightTo(
+ task,
+ shouldTruncateTarget,
+ /* smoothScroll= */ false,
+ /* waitForLayout= */ true);
}
}
private void scrollRightTo(@NonNull View targetTask) {
- scrollRightTo(targetTask, /* shouldTruncateTarget= */ false, /* smoothScroll= */ true);
+ scrollRightTo(
+ targetTask,
+ /* shouldTruncateTarget= */ false,
+ /* smoothScroll= */ true,
+ /* waitForLayout= */ false);
}
private void scrollRightTo(
- @NonNull View targetTask, boolean shouldTruncateTarget, boolean smoothScroll) {
+ @NonNull View targetTask,
+ boolean shouldTruncateTarget,
+ boolean smoothScroll,
+ boolean waitForLayout) {
if (!mDisplayingRecentTasks) {
return;
}
if (smoothScroll && !shouldScroll(targetTask, shouldTruncateTarget)) {
return;
}
- int scrollTo = targetTask.getLeft() - mSpacing
- + (shouldTruncateTarget ? targetTask.getWidth() / 2 : 0);
- // Scroll so that the focused task is to the left of the list
- if (smoothScroll) {
- mScrollView.smoothScrollTo(scrollTo, 0);
- } else {
- mScrollView.scrollTo(scrollTo, 0);
- }
+ runScrollCommand(waitForLayout, () -> {
+ int scrollTo = targetTask.getLeft() - mSpacing
+ + (shouldTruncateTarget ? targetTask.getWidth() / 2 : 0);
+ // Scroll so that the focused task is to the left of the list
+ if (smoothScroll) {
+ mScrollView.smoothScrollTo(scrollTo, 0);
+ } else {
+ mScrollView.scrollTo(scrollTo, 0);
+ }
+ });
}
private void scrollLeftTo(@NonNull View targetTask) {
- scrollLeftTo(targetTask, /* shouldTruncateTarget= */ false, /* smoothScroll= */ true);
+ scrollLeftTo(
+ targetTask,
+ /* shouldTruncateTarget= */ false,
+ /* smoothScroll= */ true,
+ /* waitForLayout= */ false);
}
private void scrollLeftTo(
- @NonNull View targetTask, boolean shouldTruncateTarget, boolean smoothScroll) {
+ @NonNull View targetTask,
+ boolean shouldTruncateTarget,
+ boolean smoothScroll,
+ boolean waitForLayout) {
if (!mDisplayingRecentTasks) {
return;
}
if (smoothScroll && !shouldScroll(targetTask, shouldTruncateTarget)) {
return;
}
- int scrollTo = targetTask.getRight() + mSpacing - mScrollView.getWidth()
- - (shouldTruncateTarget ? targetTask.getWidth() / 2 : 0);
- // Scroll so that the focused task is to the right of the list
- if (smoothScroll) {
- mScrollView.smoothScrollTo(scrollTo, 0);
- } else {
- mScrollView.scrollTo(scrollTo, 0);
- }
+ runScrollCommand(waitForLayout, () -> {
+ int scrollTo = targetTask.getRight() + mSpacing - mScrollView.getWidth()
+ - (shouldTruncateTarget ? targetTask.getWidth() / 2 : 0);
+ // Scroll so that the focused task is to the right of the list
+ if (smoothScroll) {
+ mScrollView.smoothScrollTo(scrollTo, 0);
+ } else {
+ mScrollView.scrollTo(scrollTo, 0);
+ }
+ });
}
private boolean shouldScroll(@NonNull View targetTask, boolean shouldTruncateTarget) {
@@ -514,6 +545,21 @@
return isTargetTruncated && !shouldTruncateTarget;
}
+ private void runScrollCommand(boolean waitForLayout, @NonNull Runnable scrollCommand) {
+ if (!waitForLayout) {
+ scrollCommand.run();
+ return;
+ }
+ mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ scrollCommand.run();
+ mScrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ }
+ });
+ }
+
@Nullable
protected KeyboardQuickSwitchTaskView getTaskAt(int index) {
return !mDisplayingRecentTasks || index < 0 || index >= mContent.getChildCount()
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index a293f74..cbb991d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -24,7 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer;
import com.android.quickstep.SystemUiProxy;
@@ -92,27 +92,19 @@
protected void closeQuickSwitchView(boolean animate) {
if (mCloseAnimation != null) {
- if (animate) {
- // Let currently-running animation finish.
- return;
- } else {
- mCloseAnimation.cancel();
+ // Let currently-running animation finish.
+ if (!animate) {
+ mCloseAnimation.end();
}
+ return;
}
if (!animate) {
- mCloseAnimation = null;
onCloseComplete();
return;
}
mCloseAnimation = mKeyboardQuickSwitchView.getCloseAnimation();
- mCloseAnimation.addListener(new AnimationSuccessListener() {
- @Override
- public void onAnimationSuccess(Animator animator) {
- mCloseAnimation = null;
- onCloseComplete();
- }
- });
+ mCloseAnimation.addListener(AnimatorListeners.forEndCallback(this::onCloseComplete));
mCloseAnimation.start();
}
@@ -160,6 +152,7 @@
}
private void onCloseComplete() {
+ mCloseAnimation = null;
mOverlayContext.getDragLayer().removeView(mKeyboardQuickSwitchView);
mControllerCallbacks.onCloseComplete();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 4e834ec..09376d7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -18,7 +18,7 @@
import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION;
import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE;
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
-import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED;
+import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import android.animation.Animator;
@@ -38,9 +38,11 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.taskbar.bubbles.BubbleBarController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory;
@@ -99,7 +101,9 @@
mLauncher.setTaskbarUIController(this);
- onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */);
+ if (!FeatureFlags.enableHomeTransitionListener()) {
+ onLauncherVisibilityChanged(mLauncher.hasBeenResumed(), true /* fromInit */);
+ }
onStashedInAppChanged(mLauncher.getDeviceProfile());
mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
@@ -118,7 +122,7 @@
@Override
protected void onDestroy() {
super.onDestroy();
- onLauncherResumedOrPaused(false);
+ onLauncherVisibilityChanged(false);
mTaskbarLauncherStateController.onDestroy();
mLauncher.setTaskbarUIController(null);
@@ -159,8 +163,9 @@
* sub-animations are properly coordinated. This duration should not
* actually be used since this animation tracks a swipe progress.
*/
- protected void addLauncherResumeAnimation(AnimatorSet animation, int placeholderDuration) {
- animation.play(onLauncherResumedOrPaused(
+ protected void addLauncherVisibilityChangedAnimation(AnimatorSet animation,
+ int placeholderDuration) {
+ animation.play(onLauncherVisibilityChanged(
/* isResumed= */ true,
/* fromInit= */ false,
/* startAnimation= */ false,
@@ -170,40 +175,48 @@
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
- public void onLauncherResumedOrPaused(boolean isResumed) {
- onLauncherResumedOrPaused(isResumed, false /* fromInit */);
+ public void onLauncherVisibilityChanged(boolean isVisible) {
+ onLauncherVisibilityChanged(isVisible, false /* fromInit */);
}
- private void onLauncherResumedOrPaused(boolean isResumed, boolean fromInit) {
- onLauncherResumedOrPaused(
- isResumed,
+ private void onLauncherVisibilityChanged(boolean isVisible, boolean fromInit) {
+ onLauncherVisibilityChanged(
+ isVisible,
fromInit,
/* startAnimation= */ true,
DisplayController.isTransientTaskbar(mLauncher)
? TRANSIENT_TASKBAR_TRANSITION_DURATION
- : (!isResumed
+ : (!isVisible
? QuickstepTransitionManager.TASKBAR_TO_APP_DURATION
: QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION));
}
@Nullable
- private Animator onLauncherResumedOrPaused(
- boolean isResumed, boolean fromInit, boolean startAnimation, int duration) {
+ private Animator onLauncherVisibilityChanged(
+ boolean isVisible, boolean fromInit, boolean startAnimation, int duration) {
// Launcher is resumed during the swipe-to-overview gesture under shell-transitions, so
// avoid updating taskbar state in that situation (when it's non-interactive -- or
// "background") to avoid premature animations.
- if (ENABLE_SHELL_TRANSITIONS && isResumed
+ if (ENABLE_SHELL_TRANSITIONS && isVisible
&& mLauncher.getStateManager().getState().hasFlag(FLAG_NON_INTERACTIVE)
&& !mLauncher.getStateManager().getState().isTaskbarAlignedWithHotseat(mLauncher)) {
return null;
}
- mTaskbarLauncherStateController.updateStateForFlag(FLAG_RESUMED, isResumed);
+ mTaskbarLauncherStateController.updateStateForFlag(FLAG_VISIBLE, isVisible);
return mTaskbarLauncherStateController.applyState(fromInit ? 0 : duration, startAnimation);
}
+ @Override
public void refreshResumedState() {
- onLauncherResumedOrPaused(mLauncher.hasBeenResumed());
+ onLauncherVisibilityChanged(mLauncher.hasBeenResumed());
+ }
+
+ @Override
+ public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {
+ if (mLauncher.getHotseat() != null) {
+ mLauncher.getHotseat().adjustForBubbleBar(isBubbleBarVisible);
+ }
}
/**
@@ -279,8 +292,7 @@
// Persistent features EDU tooltip.
if (!DisplayController.isTransientTaskbar(mLauncher)) {
- return !mLauncher.getOnboardingPrefs().hasReachedMaxCount(
- OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP);
+ return !OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP.hasReachedMax(mLauncher);
}
// Transient swipe EDU tooltip.
@@ -327,10 +339,25 @@
return mTaskbarInAppDisplayProgress.value > 0;
}
+ public boolean isBubbleBarEnabled() {
+ return BubbleBarController.isBubbleBarEnabled();
+ }
+
+ /** Whether the bubble bar has any bubbles. */
+ public boolean hasBubbles() {
+ if (mControllers == null) {
+ return false;
+ }
+ if (mControllers.bubbleControllers.isEmpty()) {
+ return false;
+ }
+ return mControllers.bubbleControllers.get().bubbleBarViewController.hasBubbles();
+ }
+
@Override
public void onExpandPip() {
super.onExpandPip();
- mTaskbarLauncherStateController.updateStateForFlag(FLAG_RESUMED, false);
+ mTaskbarLauncherStateController.updateStateForFlag(FLAG_VISIBLE, false);
mTaskbarLauncherStateController.applyState();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index fcd8c80..be4426d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -88,10 +88,10 @@
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory;
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter;
import com.android.launcher3.util.DimensionUtils;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.TouchController;
+import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.views.BaseDragLayer;
import com.android.systemui.shared.rotation.FloatingRotationButton;
import com.android.systemui.shared.rotation.RotationButton;
@@ -144,6 +144,7 @@
private int mState;
private final TaskbarActivityContext mContext;
+ private final WindowManagerProxy mWindowManagerProxy;
private final FrameLayout mNavButtonsView;
private final LinearLayout mNavButtonContainer;
// Used for IME+A11Y buttons
@@ -190,6 +191,7 @@
private MultiValueAlpha mBackButtonAlpha;
private MultiValueAlpha mHomeButtonAlpha;
private FloatingRotationButton mFloatingRotationButton;
+ private ImageView mImeSwitcherButton;
// Variables for moving nav buttons to a separate window above IME
private boolean mAreNavButtonsInSeparateWindow = false;
@@ -198,10 +200,10 @@
this::onComputeInsetsForSeparateWindow;
private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender();
private ImageView mRecentsButton;
- private DisplayController mDisplayController;
public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
mContext = context;
+ mWindowManagerProxy = WindowManagerProxy.INSTANCE.get(mContext);
mNavButtonsView = navButtonsView;
mNavButtonContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
mEndContextualContainer = mNavButtonsView.findViewById(R.id.end_contextual_buttons);
@@ -219,25 +221,27 @@
*/
public void init(TaskbarControllers controllers) {
mControllers = controllers;
+ setupController();
+ }
+
+ protected void setupController() {
boolean isThreeButtonNav = mContext.isThreeButtonNav();
DeviceProfile deviceProfile = mContext.getDeviceProfile();
Resources resources = mContext.getResources();
Point p = !mContext.isUserSetupComplete()
- ? new Point(0, controllers.taskbarActivityContext.getSetupWindowHeight())
+ ? new Point(0, mControllers.taskbarActivityContext.getSetupWindowHeight())
: DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources,
TaskbarManager.isPhoneMode(deviceProfile));
mNavButtonsView.getLayoutParams().height = p.y;
- mDisplayController = DisplayController.INSTANCE.get(mContext);
-
mIsImeRenderingNavButtons =
InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar();
if (!mIsImeRenderingNavButtons) {
// IME switcher
- View imeSwitcherButton = addButton(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH,
+ mImeSwitcherButton = addButton(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH,
isThreeButtonNav ? mStartContextualContainer : mEndContextualContainer,
mControllers.navButtonController, R.id.ime_switcher);
- mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
+ mPropertyHolders.add(new StatePropertyHolder(mImeSwitcherButton,
flags -> ((flags & FLAG_SWITCHER_SHOWING) != 0)
&& ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)));
}
@@ -467,7 +471,7 @@
/**
* @return {@code true} if A11y is showing in 3 button nav taskbar
*/
- private boolean isContextualButtonShowing() {
+ private boolean isA11yButtonPersistent() {
return mContext.isThreeButtonNav() && (mState & FLAG_A11Y_VISIBLE) != 0;
}
@@ -733,9 +737,12 @@
if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) {
NavButtonLayoutter navButtonLayoutter =
NavButtonLayoutFactory.Companion.getUiLayoutter(
- dp, mNavButtonsView, res, isInKidsMode, isInSetup, isThreeButtonNav,
- TaskbarManager.isPhoneMode(dp), mDisplayController.getInfo().rotation);
- navButtonLayoutter.layoutButtons(dp, isContextualButtonShowing());
+ dp, mNavButtonsView, mImeSwitcherButton,
+ mControllers.rotationButtonController.getRotationButton(),
+ mA11yButton, res, isInKidsMode, isInSetup, isThreeButtonNav,
+ TaskbarManager.isPhoneMode(dp),
+ mWindowManagerProxy.getRotation(mContext));
+ navButtonLayoutter.layoutButtons(dp, isA11yButtonPersistent());
updateNavButtonColor();
return;
}
@@ -831,7 +838,7 @@
int contextualWidth = mEndContextualContainer.getWidth();
// If contextual buttons are showing, we check if the end margin is enough for the
// contextual button to be showing - if not, move the nav buttons over a smidge
- if (isContextualButtonShowing() && navMarginEnd < contextualWidth) {
+ if (isA11yButtonPersistent() && navMarginEnd < contextualWidth) {
// Additional spacing, eat up half of space between last icon and nav button
navMarginEnd += res.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index b15dda2..6ee151b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -20,18 +20,24 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
+import static com.android.launcher3.Utilities.calculateTextHeight;
import static com.android.launcher3.Utilities.isRunningInTestHarness;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_PINNING;
+import static com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN;
import static com.android.launcher3.taskbar.TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW;
import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName;
+import static com.android.launcher3.util.VibratorWrapper.EFFECT_CLICK;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
@@ -109,6 +115,7 @@
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.views.RecentsView;
@@ -122,6 +129,7 @@
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Optional;
+import java.util.function.Consumer;
/**
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
@@ -167,13 +175,16 @@
private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;
+ private DeviceProfile mTransientTaskbarDeviceProfile;
+
+ private DeviceProfile mPersistentTaskbarDeviceProfile;
+
public TaskbarActivityContext(Context windowContext, DeviceProfile launcherDp,
TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
unfoldTransitionProgressProvider) {
super(windowContext);
applyDeviceProfile(launcherDp);
-
final Resources resources = getResources();
mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
@@ -215,7 +226,8 @@
// If Bubble bar is present, TaskbarControllers depends on it so build it first.
Optional<BubbleControllers> bubbleControllersOptional = Optional.empty();
- if (BubbleBarController.BUBBLE_BAR_ENABLED && bubbleBarView != null) {
+ BubbleBarController.onTaskbarRecreated();
+ if (BubbleBarController.isBubbleBarEnabled() && bubbleBarView != null) {
bubbleControllersOptional = Optional.of(new BubbleControllers(
new BubbleBarController(this, bubbleBarView),
new BubbleBarViewController(this, bubbleBarView),
@@ -247,9 +259,9 @@
new TaskbarViewController(this, taskbarView),
new TaskbarScrimViewController(this, taskbarScrimView),
new TaskbarUnfoldAnimationController(this, unfoldTransitionProgressProvider,
- mWindowManager,
- new RotationChangeProvider(c.getSystemService(DisplayManager.class), this,
- getMainThreadHandler())),
+ mWindowManager,
+ new RotationChangeProvider(c.getSystemService(DisplayManager.class), this,
+ getMainThreadHandler())),
new TaskbarKeyguardController(this),
new StashedHandleViewController(this, stashedHandleView),
new TaskbarStashController(this),
@@ -267,7 +279,7 @@
: TaskbarRecentAppsController.DEFAULT,
new TaskbarEduTooltipController(this),
new KeyboardQuickSwitchController(),
- new TaskbarDividerPopupController(this),
+ new TaskbarPinningController(this),
bubbleControllersOptional);
}
@@ -288,20 +300,42 @@
* the icon size
*/
private void applyDeviceProfile(DeviceProfile originDeviceProfile) {
- mDeviceProfile = originDeviceProfile.toBuilder(this)
- .withDimensionsOverride(deviceProfile -> {
- // Taskbar should match the number of icons of hotseat
- deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
- // Same QSB width to have a smooth animation
- deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;
+ Consumer<DeviceProfile> overrideProvider = deviceProfile -> {
+ // Taskbar should match the number of icons of hotseat
+ deviceProfile.numShownHotseatIcons = originDeviceProfile.numShownHotseatIcons;
+ // Same QSB width to have a smooth animation
+ deviceProfile.hotseatQsbWidth = originDeviceProfile.hotseatQsbWidth;
- // Update icon size
- deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
- deviceProfile.updateIconSize(1f, getResources());
- }).build();
+ // Update icon size
+ deviceProfile.iconSizePx = deviceProfile.taskbarIconSize;
+ deviceProfile.updateIconSize(1f, getResources());
+ };
+ mDeviceProfile = originDeviceProfile.toBuilder(this)
+ .withDimensionsOverride(overrideProvider).build();
+
+ if (DisplayController.isTransientTaskbar(this)) {
+ mTransientTaskbarDeviceProfile = mDeviceProfile;
+ mPersistentTaskbarDeviceProfile = mDeviceProfile
+ .toBuilder(this)
+ .withDimensionsOverride(overrideProvider)
+ .setIsTransientTaskbar(false)
+ .build();
+ } else {
+ mPersistentTaskbarDeviceProfile = mDeviceProfile;
+ mTransientTaskbarDeviceProfile = mDeviceProfile
+ .toBuilder(this)
+ .withDimensionsOverride(overrideProvider)
+ .setIsTransientTaskbar(true)
+ .build();
+ }
mNavMode = DisplayController.getNavigationMode(this);
}
+ /** Called when the visibility of the bubble bar changed. */
+ public void bubbleBarVisibilityChanged(boolean isVisible) {
+ mControllers.uiController.adjustHotseatForBubbleBar(isVisible);
+ mControllers.taskbarViewController.resetIconAlignmentController();
+ }
public void init(@NonNull TaskbarSharedState sharedState) {
mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, getResources(), false);
@@ -327,11 +361,11 @@
mIsDestroyed = false;
}
- if (!mAddedWindow) {
+ if (!enableTaskbarNoRecreate() && !mAddedWindow) {
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
mAddedWindow = true;
} else {
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
}
@@ -347,6 +381,11 @@
mControllers.taskbarAllAppsController.toggle();
}
+ /** Toggles Taskbar All Apps overlay with keyboard ready for search. */
+ public void toggleAllAppsSearch() {
+ mControllers.taskbarAllAppsController.toggleSearch();
+ }
+
@Override
public DeviceProfile getDeviceProfile() {
return mDeviceProfile;
@@ -374,7 +413,8 @@
/**
* Creates LayoutParams for adding a view directly to WindowManager as a new window.
- * @param type The window type to pass to the created WindowManager.LayoutParams.
+ *
+ * @param type The window type to pass to the created WindowManager.LayoutParams.
* @param title The window title to pass to the created WindowManager.LayoutParams.
*/
public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type, String title) {
@@ -413,9 +453,10 @@
* for taskbar showing as navigation bar
*/
private WindowManager.LayoutParams createAllWindowParams() {
+ final int windowType =
+ FLAG_HIDE_NAVBAR_WINDOW ? TYPE_NAVIGATION_BAR : TYPE_NAVIGATION_BAR_PANEL;
WindowManager.LayoutParams windowLayoutParams =
- createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL,
- TaskbarActivityContext.WINDOW_TITLE);
+ createDefaultWindowLayoutParams(windowType, TaskbarActivityContext.WINDOW_TITLE);
boolean isPhoneNavMode = TaskbarManager.isPhoneButtonNavMode(this);
if (!isPhoneNavMode) {
return windowLayoutParams;
@@ -428,7 +469,7 @@
windowLayoutParams.paramsForRotation = new WindowManager.LayoutParams[4];
for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
WindowManager.LayoutParams lp =
- createDefaultWindowLayoutParams(TYPE_NAVIGATION_BAR_PANEL,
+ createDefaultWindowLayoutParams(windowType,
TaskbarActivityContext.WINDOW_TITLE);
switch (rot) {
case Surface.ROTATION_0, Surface.ROTATION_180 -> {
@@ -678,7 +719,7 @@
mIsDestroyed = true;
setUIController(TaskbarUIController.DEFAULT);
mControllers.onDestroy();
- if (!FLAG_HIDE_NAVBAR_WINDOW) {
+ if (!enableTaskbarNoRecreate() && !FLAG_HIDE_NAVBAR_WINDOW) {
mWindowManager.removeViewImmediate(mDragLayer);
mAddedWindow = false;
}
@@ -777,7 +818,7 @@
// Overlay AFVs are in a separate window and do not require Taskbar to be fullscreen.
if (!isDragInProgress
&& !AbstractFloatingView.hasOpenView(
- this, TYPE_ALL & ~TYPE_TASKBAR_OVERLAY_PROXY)) {
+ this, TYPE_ALL & ~TYPE_TASKBAR_OVERLAY_PROXY)) {
// Reverts Taskbar window to its original size
setTaskbarWindowFullscreen(false);
}
@@ -810,7 +851,7 @@
}
mWindowLayoutParams.height = height;
mControllers.taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
/**
@@ -829,20 +870,46 @@
return getSetupWindowHeight();
}
- if (DisplayController.isTransientTaskbar(this)) {
- return mDeviceProfile.taskbarHeight
- + (2 * mDeviceProfile.taskbarBottomMargin)
- + resources.getDimensionPixelSize(R.dimen.transient_taskbar_shadow_blur);
+ boolean shouldTreatAsTransient = DisplayController.isTransientTaskbar(this)
+ || (ENABLE_TASKBAR_PINNING.get() && !isThreeButtonNav());
+
+ int extraHeightForTaskbarTooltips = enableCursorHoverStates()
+ ? resources.getDimensionPixelSize(R.dimen.arrow_toast_arrow_height)
+ + (resources.getDimensionPixelSize(R.dimen.taskbar_tooltip_vertical_padding) * 2)
+ + calculateTextHeight(
+ resources.getDimensionPixelSize(R.dimen.arrow_toast_text_size))
+ : 0;
+
+ // Return transient taskbar window height when pinning feature is enabled, so taskbar view
+ // does not get cut off during pinning animation.
+ if (shouldTreatAsTransient) {
+ DeviceProfile transientTaskbarDp = mDeviceProfile.toBuilder(this)
+ .setIsTransientTaskbar(true).build();
+
+ return transientTaskbarDp.taskbarHeight
+ + (2 * transientTaskbarDp.taskbarBottomMargin)
+ + Math.max(extraHeightForTaskbarTooltips, resources.getDimensionPixelSize(
+ R.dimen.transient_taskbar_shadow_blur));
}
+
return mDeviceProfile.taskbarHeight
- + Math.max(getLeftCornerRadius(), getRightCornerRadius());
+ + Math.max(getLeftCornerRadius(), getRightCornerRadius())
+ + extraHeightForTaskbarTooltips;
}
public int getSetupWindowHeight() {
return getResources().getDimensionPixelSize(R.dimen.taskbar_suw_frame);
}
+ public DeviceProfile getTransientTaskbarDeviceProfile() {
+ return mTransientTaskbarDeviceProfile;
+ }
+
+ public DeviceProfile getPersistentTaskbarDeviceProfile() {
+ return mPersistentTaskbarDeviceProfile;
+ }
+
/**
* Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar
* window.
@@ -853,7 +920,7 @@
} else {
mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE;
}
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
/**
@@ -1083,6 +1150,7 @@
* Called when we want to unstash taskbar when user performs swipes up gesture.
*/
public void onSwipeToUnstashTaskbar() {
+ VibratorWrapper.INSTANCE.get(this).vibrate(EFFECT_CLICK);
mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(/* stash= */ false);
mControllers.taskbarEduTooltipController.hide();
}
@@ -1212,7 +1280,7 @@
TaskbarUIController uiController = mControllers.uiController;
if (uiController instanceof LauncherTaskbarUIController) {
- ((LauncherTaskbarUIController) uiController).addLauncherResumeAnimation(
+ ((LauncherTaskbarUIController) uiController).addLauncherVisibilityChangedAnimation(
fullAnimation, duration);
}
mControllers.taskbarStashController.addUnstashToHotseatAnimation(fullAnimation, duration);
@@ -1249,12 +1317,16 @@
mWindowLayoutParams.privateFlags &=
~WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
}
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ notifyUpdateLayoutParams();
}
void notifyUpdateLayoutParams() {
if (mDragLayer.isAttachedToWindow()) {
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ if (enableTaskbarNoRecreate()) {
+ mWindowManager.updateViewLayout(mDragLayer.getRootView(), mWindowLayoutParams);
+ } else {
+ mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
index d237c1f..d6016f1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
@@ -29,26 +29,39 @@
import com.android.launcher3.Utilities.mapRange
import com.android.launcher3.Utilities.mapToRange
import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound
+import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_PERSISTENT
+import com.android.launcher3.taskbar.TaskbarPinningController.Companion.PINNING_TRANSIENT
import com.android.launcher3.util.DisplayController
+import kotlin.math.min
/** Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners. */
-class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
+class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
private val isInSetup: Boolean = !context.isUserSetupComplete
private val DARK_THEME_SHADOW_ALPHA = 51f
private val LIGHT_THEME_SHADOW_ALPHA = 25f
+ private val maxTransientTaskbarHeight =
+ context.transientTaskbarDeviceProfile.taskbarHeight.toFloat()
+ private val maxPersistentTaskbarHeight =
+ context.persistentTaskbarDeviceProfile.taskbarHeight.toFloat()
+ var backgroundProgress =
+ if (DisplayController.isTransientTaskbar(context)) {
+ PINNING_TRANSIENT
+ } else {
+ PINNING_PERSISTENT
+ }
+
+ var isAnimatingPinning = false
+
val paint = Paint()
val lastDrawnTransientRect = RectF()
var backgroundHeight = context.deviceProfile.taskbarHeight.toFloat()
var translationYForSwipe = 0f
var translationYForStash = 0f
- private var maxBackgroundHeight = context.deviceProfile.taskbarHeight.toFloat()
private val transientBackgroundBounds = context.transientTaskbarBounds
- private val isTransientTaskbar = DisplayController.isTransientTaskbar(context)
-
private val shadowAlpha: Float
private var shadowBlur = 0f
private var keyShadowDistance = 0f
@@ -75,13 +88,6 @@
paint.flags = Paint.ANTI_ALIAS_FLAG
paint.style = Paint.Style.FILL
- if (isTransientTaskbar) {
- val res = context.resources
- bottomMargin = res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
- shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
- keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
- }
-
shadowAlpha =
if (Utilities.isDarkTheme(context)) DARK_THEME_SHADOW_ALPHA
else LIGHT_THEME_SHADOW_ALPHA
@@ -90,10 +96,11 @@
}
fun updateStashedHandleWidth(dp: DeviceProfile, res: Resources) {
- stashedHandleWidth = res.getDimensionPixelSize(
+ stashedHandleWidth =
+ res.getDimensionPixelSize(
if (TaskbarManager.isPhoneMode(dp)) R.dimen.taskbar_stashed_small_screen
else R.dimen.taskbar_stashed_handle_width
- )
+ )
}
/**
@@ -102,7 +109,7 @@
* @param cornerRoundness 0 has no round corner, 1 has complete round corner.
*/
fun setCornerRoundness(cornerRoundness: Float) {
- if (isTransientTaskbar && !transientBackgroundBounds.isEmpty) {
+ if (DisplayController.isTransientTaskbar(context) && !transientBackgroundBounds.isEmpty) {
return
}
@@ -126,63 +133,123 @@
/** Draws the background with the given paint and height, on the provided canvas. */
fun draw(canvas: Canvas) {
+ if (isInSetup) return
+ val isTransientTaskbar = backgroundProgress == 0f
canvas.save()
- if (!isTransientTaskbar || transientBackgroundBounds.isEmpty) {
- canvas.translate(0f, canvas.height - backgroundHeight - bottomMargin)
- // Draw the background behind taskbar content.
- canvas.drawRect(0f, 0f, canvas.width.toFloat(), backgroundHeight, paint)
-
- // Draw the inverted rounded corners above the taskbar.
- canvas.translate(0f, -leftCornerRadius)
- canvas.drawPath(invertedLeftCornerPath, paint)
- canvas.translate(0f, leftCornerRadius)
- canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
- canvas.drawPath(invertedRightCornerPath, paint)
- } else if (!isInSetup) {
- // backgroundHeight is a value from [0...maxBackgroundHeight], so we can use it as a
- // proxy to figure out the animation progress of the stash/unstash animation.
- val progress = backgroundHeight / maxBackgroundHeight
-
- // At progress 0, we draw the background as the stashed handle.
- // At progress 1, we draw the background as the full taskbar.
- val newBackgroundHeight =
- mapRange(progress, stashedHandleHeight.toFloat(), maxBackgroundHeight)
- val fullWidth = transientBackgroundBounds.width()
- val newWidth = mapRange(progress, stashedHandleWidth.toFloat(), fullWidth.toFloat())
- val halfWidthDelta = (fullWidth - newWidth) / 2f
- val radius = newBackgroundHeight / 2f
- val bottomMarginProgress = bottomMargin * ((1f - progress) / 2f)
-
- // Aligns the bottom with the bottom of the stashed handle.
- val bottom =
- canvas.height - bottomMargin +
- bottomMarginProgress +
- translationYForSwipe +
- translationYForStash +
- -mapRange(1f - progress, 0f, stashedHandleHeight / 2f)
-
- // Draw shadow.
- val newShadowAlpha =
- mapToRange(paint.alpha.toFloat(), 0f, 255f, 0f, shadowAlpha, Interpolators.LINEAR)
- paint.setShadowLayer(
- shadowBlur,
- 0f,
- keyShadowDistance,
- setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
- )
-
- lastDrawnTransientRect.set(
- transientBackgroundBounds.left + halfWidthDelta,
- bottom - newBackgroundHeight,
- transientBackgroundBounds.right - halfWidthDelta,
- bottom
- )
- val horizontalInset = fullWidth * widthInsetPercentage
- lastDrawnTransientRect.inset(horizontalInset, 0f)
-
- canvas.drawRoundRect(lastDrawnTransientRect, radius, radius, paint)
+ if (!isTransientTaskbar || transientBackgroundBounds.isEmpty || isAnimatingPinning) {
+ drawPersistentBackground(canvas)
}
canvas.restore()
+ canvas.save()
+ if (isAnimatingPinning || isTransientTaskbar) {
+ drawTransientBackground(canvas)
+ }
+ canvas.restore()
+ }
+
+ private fun drawPersistentBackground(canvas: Canvas) {
+ if (isAnimatingPinning) {
+ val persistentTaskbarHeight = maxPersistentTaskbarHeight * backgroundProgress
+ canvas.translate(0f, canvas.height - persistentTaskbarHeight)
+ // Draw the background behind taskbar content.
+ canvas.drawRect(0f, 0f, canvas.width.toFloat(), persistentTaskbarHeight, paint)
+ } else {
+ val persistentTaskbarHeight = min(maxPersistentTaskbarHeight, backgroundHeight)
+ canvas.translate(0f, canvas.height - persistentTaskbarHeight)
+ // Draw the background behind taskbar content.
+ canvas.drawRect(0f, 0f, canvas.width.toFloat(), persistentTaskbarHeight, paint)
+ }
+
+ // Draw the inverted rounded corners above the taskbar.
+ canvas.translate(0f, -leftCornerRadius)
+ canvas.drawPath(invertedLeftCornerPath, paint)
+ canvas.translate(0f, leftCornerRadius)
+ canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
+ canvas.drawPath(invertedRightCornerPath, paint)
+ }
+
+ private fun drawTransientBackground(canvas: Canvas) {
+ val res = context.resources
+ val transientTaskbarHeight = maxTransientTaskbarHeight * (1f - backgroundProgress)
+ val heightProgressWhileAnimating =
+ if (isAnimatingPinning) transientTaskbarHeight else backgroundHeight
+
+ var progress = heightProgressWhileAnimating / maxTransientTaskbarHeight
+ progress = Math.round(progress * 100f) / 100f
+ if (isAnimatingPinning) {
+ var scale = transientTaskbarHeight / maxTransientTaskbarHeight
+ scale = Math.round(scale * 100f) / 100f
+ bottomMargin =
+ mapRange(
+ scale,
+ 0f,
+ res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin).toFloat()
+ )
+ .toInt()
+ shadowBlur =
+ mapRange(scale, 0f, res.getDimension(R.dimen.transient_taskbar_shadow_blur))
+ keyShadowDistance =
+ mapRange(scale, 0f, res.getDimension(R.dimen.transient_taskbar_key_shadow_distance))
+ } else {
+ bottomMargin = res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
+ shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
+ keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
+ }
+
+ // At progress 0, we draw the background as the stashed handle.
+ // At progress 1, we draw the background as the full taskbar.
+ // Min height capped to max persistent taskbar height for animation
+ val backgroundHeightWhileAnimating =
+ if (isAnimatingPinning) maxPersistentTaskbarHeight else stashedHandleHeight.toFloat()
+ val newBackgroundHeight =
+ mapRange(progress, backgroundHeightWhileAnimating, maxTransientTaskbarHeight)
+ val fullWidth = transientBackgroundBounds.width()
+
+ // .9f is here to restrict min width of the background while animating, so transient
+ // background keeps it pill shape until animation end.
+ val animationWidth =
+ if (DisplayController.isTransientTaskbar(context)) fullWidth.toFloat() * .9f
+ else fullWidth.toFloat()
+ val backgroundWidthWhileAnimating =
+ if (isAnimatingPinning) animationWidth else stashedHandleWidth.toFloat()
+
+ val newWidth = mapRange(progress, backgroundWidthWhileAnimating, fullWidth.toFloat())
+ val halfWidthDelta = (fullWidth - newWidth) / 2f
+ val radius = newBackgroundHeight / 2f
+ val bottomMarginProgress = bottomMargin * ((1f - progress) / 2f)
+
+ // Aligns the bottom with the bottom of the stashed handle.
+ val bottom =
+ canvas.height - bottomMargin +
+ bottomMarginProgress +
+ translationYForSwipe +
+ translationYForStash +
+ -mapRange(
+ 1f - progress,
+ 0f,
+ if (isAnimatingPinning) 0f else stashedHandleHeight / 2f
+ )
+
+ // Draw shadow.
+ val newShadowAlpha =
+ mapToRange(paint.alpha.toFloat(), 0f, 255f, 0f, shadowAlpha, Interpolators.LINEAR)
+ paint.setShadowLayer(
+ shadowBlur,
+ 0f,
+ keyShadowDistance,
+ setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
+ )
+
+ lastDrawnTransientRect.set(
+ transientBackgroundBounds.left + halfWidthDelta,
+ bottom - newBackgroundHeight,
+ transientBackgroundBounds.right - halfWidthDelta,
+ bottom
+ )
+ val horizontalInset = fullWidth * widthInsetPercentage
+ lastDrawnTransientRect.inset(horizontalInset, 0f)
+
+ canvas.drawRoundRect(lastDrawnTransientRect, radius, radius, paint)
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index d82f501..f9ddc3d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -62,7 +62,7 @@
public final TaskbarOverlayController taskbarOverlayController;
public final TaskbarEduTooltipController taskbarEduTooltipController;
public final KeyboardQuickSwitchController keyboardQuickSwitchController;
- public final TaskbarDividerPopupController taskbarPinningController;
+ public final TaskbarPinningController taskbarPinningController;
public final Optional<BubbleControllers> bubbleControllers;
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
@@ -110,7 +110,7 @@
TaskbarRecentAppsController taskbarRecentAppsController,
TaskbarEduTooltipController taskbarEduTooltipController,
KeyboardQuickSwitchController keyboardQuickSwitchController,
- TaskbarDividerPopupController taskbarPinningController,
+ TaskbarPinningController taskbarPinningController,
Optional<BubbleControllers> bubbleControllers) {
this.taskbarActivityContext = taskbarActivityContext;
this.taskbarDragController = taskbarDragController;
@@ -171,7 +171,7 @@
taskbarTranslationController.init(this);
taskbarEduTooltipController.init(this);
keyboardQuickSwitchController.init(this);
- taskbarPinningController.init(this);
+ taskbarPinningController.init(this, mSharedState);
bubbleControllers.ifPresent(controllers -> controllers.init(this));
mControllersToLog = new LoggableTaskbarController[] {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
deleted file mode 100644
index 83a3343..0000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar
-
-import android.view.View
-import com.android.launcher3.LauncherPrefs
-import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
-import com.android.launcher3.taskbar.TaskbarDividerPopupView.Companion.createAndPopulate
-import java.io.PrintWriter
-
-/** Controls taskbar pinning through a popup view. */
-class TaskbarDividerPopupController(private val context: TaskbarActivityContext) :
- TaskbarControllers.LoggableTaskbarController {
-
- private lateinit var controllers: TaskbarControllers
- private val launcherPrefs = LauncherPrefs.get(context)
-
- fun init(taskbarControllers: TaskbarControllers) {
- controllers = taskbarControllers
- }
-
- fun showPinningView(view: View) {
- context.isTaskbarWindowFullscreen = true
-
- view.post {
- val popupView = createAndPopulate(view, context)
- popupView.requestFocus()
-
- popupView.onCloseCallback =
- callback@{ didPreferenceChange ->
- context.dragLayer.post { context.onPopupVisibilityChanged(false) }
-
- if (!didPreferenceChange) {
- return@callback
- }
-
- if (launcherPrefs.get(TASKBAR_PINNING)) {
- animateTransientToPersistentTaskbar()
- } else {
- animatePersistentToTransientTaskbar()
- }
- }
- popupView.changePreference = {
- launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
- }
- context.onPopupVisibilityChanged(true)
- popupView.show()
- }
- }
-
- // TODO(b/265436799): provide animation/transition from transient taskbar to persistent one
- private fun animateTransientToPersistentTaskbar() {}
-
- // TODO(b/265436799): provide animation/transition from persistent taskbar to transient one
- private fun animatePersistentToTransientTaskbar() {}
-
- override fun dumpLogs(prefix: String, pw: PrintWriter) {
- pw.println(prefix + "TaskbarPinningController:")
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index e215bc9..3f9b66a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -15,22 +15,29 @@
*/
package com.android.launcher3.taskbar
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Rect
import android.graphics.drawable.GradientDrawable
import android.util.AttributeSet
+import android.util.Property
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout
import android.widget.Switch
import androidx.core.view.postDelayed
+import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.Themes
+import com.android.launcher3.views.ActivityContext
/** Popup view with arrow for taskbar pinning */
class TaskbarDividerPopupView<T : TaskbarActivityContext>
@@ -42,7 +49,8 @@
) : ArrowPopup<T>(context, attrs, defStyleAttr) {
companion object {
private const val TAG = "TaskbarDividerPopupView"
- private const val DIVIDER_POPUP_CLOSING_DELAY = 500L
+ private const val DIVIDER_POPUP_CLOSING_DELAY = 333L
+ private const val DIVIDER_POPUP_CLOSING_ANIMATION_DURATION = 83L
@JvmStatic
fun createAndPopulate(
@@ -59,10 +67,11 @@
return taskMenuViewWithArrow.populateForView(view)
}
}
+
private lateinit var dividerView: View
private val menuWidth =
- context.resources.getDimensionPixelSize(R.dimen.taskbar_pinning_popup_menu_width)
+ resources.getDimensionPixelSize(R.dimen.taskbar_pinning_popup_menu_width)
private val popupCornerRadius = Themes.getDialogCornerRadius(context)
private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height)
@@ -70,16 +79,12 @@
private var alwaysShowTaskbarOn = !DisplayController.isTransientTaskbar(context)
private var didPreferenceChange = false
+ private var verticalOffsetForPopupView =
+ resources.getDimensionPixelSize(R.dimen.taskbar_pinning_popup_menu_vertical_margin)
/** Callback invoked when the pinning popup view is closing. */
var onCloseCallback: (preferenceChanged: Boolean) -> Unit = {}
- /**
- * Callback invoked when the user preference changes in popup view. Preference change will be
- * based upon current value stored in [LauncherPrefs] for `TASKBAR_PINNING`
- */
- var changePreference: () -> Unit = {}
-
init {
// This synchronizes the arrow and menu to open at the same time
mOpenChildFadeStartDelay = mOpenFadeStartDelay
@@ -99,11 +104,22 @@
super.onFinishInflate()
val taskbarSwitchOption = requireViewById<LinearLayout>(R.id.taskbar_switch_option)
val alwaysShowTaskbarSwitch = requireViewById<Switch>(R.id.taskbar_pinning_switch)
+ val taskbarVisibilityIcon = requireViewById<View>(R.id.taskbar_pinning_visibility_icon)
alwaysShowTaskbarSwitch.isChecked = alwaysShowTaskbarOn
- taskbarSwitchOption.setOnClickListener {
- alwaysShowTaskbarSwitch.isClickable = true
- alwaysShowTaskbarSwitch.isChecked = !alwaysShowTaskbarOn
- onClickAlwaysShowTaskbarSwitchOption()
+ if (ActivityContext.lookupContext<TaskbarActivityContext>(context).isGestureNav) {
+ taskbarSwitchOption.setOnClickListener {
+ alwaysShowTaskbarSwitch.isClickable = true
+ alwaysShowTaskbarSwitch.isChecked = !alwaysShowTaskbarOn
+ onClickAlwaysShowTaskbarSwitchOption()
+ }
+ } else {
+ alwaysShowTaskbarSwitch.isEnabled = false
+ }
+
+ if (!alwaysShowTaskbarSwitch.isEnabled) {
+ taskbarVisibilityIcon.background.setTint(
+ resources.getColor(android.R.color.system_neutral2_500, context.theme)
+ )
}
}
@@ -176,15 +192,80 @@
}
}
- override fun closeComplete() {
+ override fun getExtraVerticalOffset(): Int {
+ return (mActivityContext.deviceProfile.taskbarHeight -
+ mActivityContext.deviceProfile.taskbarIconSize) / 2 + verticalOffsetForPopupView
+ }
+
+ override fun animateClose() {
+ if (!mIsOpen) {
+ return
+ }
+ if (mOpenCloseAnimator != null) {
+ mOpenCloseAnimator.cancel()
+ }
+ mIsOpen = false
+
+ mOpenCloseAnimator = getCloseAnimator()
+
+ mOpenCloseAnimator.addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ mOpenCloseAnimator = null
+ if (mDeferContainerRemoval) {
+ setVisibility(INVISIBLE)
+ } else {
+ closeComplete()
+ }
+ }
+ }
+ )
onCloseCallback(didPreferenceChange)
- super.closeComplete()
+ onCloseCallback = {}
+ mOpenCloseAnimator.start()
+ }
+
+ private fun getCloseAnimator(): AnimatorSet {
+ val alphaValues = floatArrayOf(1f, 0f)
+ val translateYValue =
+ if (!alwaysShowTaskbarOn) verticalOffsetForPopupView else -verticalOffsetForPopupView
+ val alpha = getAnimatorOfFloat(this, ALPHA, *alphaValues)
+ val arrowAlpha = getAnimatorOfFloat(mArrow, ALPHA, *alphaValues)
+ val translateY =
+ ObjectAnimator.ofFloat(
+ this,
+ TRANSLATION_Y,
+ *floatArrayOf(this.translationY, this.translationY + translateYValue)
+ )
+ val arrowTranslateY =
+ ObjectAnimator.ofFloat(
+ mArrow,
+ TRANSLATION_Y,
+ *floatArrayOf(mArrow.translationY, mArrow.translationY + translateYValue)
+ )
+ val animatorSet = AnimatorSet()
+ animatorSet.playTogether(alpha, arrowAlpha, translateY, arrowTranslateY)
+ return animatorSet
+ }
+
+ private fun getAnimatorOfFloat(
+ view: View,
+ property: Property<View, Float>,
+ vararg values: Float
+ ): Animator {
+ val animator: Animator = ObjectAnimator.ofFloat(view, property, *values)
+ animator.setDuration(DIVIDER_POPUP_CLOSING_ANIMATION_DURATION)
+ animator.interpolator = EMPHASIZED_ACCELERATE
+ return animator
}
private fun onClickAlwaysShowTaskbarSwitchOption() {
didPreferenceChange = true
- changePreference()
// Allow switch animation to finish and then close the popup.
- postDelayed(DIVIDER_POPUP_CLOSING_DELAY) { close(true) }
+ postDelayed(DIVIDER_POPUP_CLOSING_DELAY) {
+ if (isOpen) {
+ close(true)
+ }
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 3c7196a..6ddf9e9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -21,6 +21,8 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION;
+import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.EXTENDED_CONTAINERS;
+import static com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers.ContainerCase.DEVICE_SEARCH_RESULT_CONTAINER;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -64,6 +66,7 @@
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -259,6 +262,8 @@
DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
ItemInfo dragInfo, Rect dragRegion, float initialDragViewScale,
float dragViewScaleOnDrop, DragOptions options) {
+ mActivity.hideKeyboard();
+
mOptions = options;
mRegistrationX = mMotionDown.x - dragLayerX;
@@ -624,7 +629,9 @@
if (tag instanceof ItemInfo) {
ItemInfo item = (ItemInfo) tag;
- if (item.container == CONTAINER_ALL_APPS || item.container == CONTAINER_PREDICTION) {
+ if (item.container == CONTAINER_ALL_APPS
+ || item.container == CONTAINER_PREDICTION
+ || isInSearchResultContainer(item)) {
if (mDisallowGlobalDrag) {
// We're dragging in taskbarAllApps, we don't have folders or shortcuts
return iconView;
@@ -646,6 +653,13 @@
return iconView;
}
+ private static boolean isInSearchResultContainer(ItemInfo item) {
+ ContainerInfo containerInfo = item.getContainerInfo();
+ return containerInfo.getContainerCase() == EXTENDED_CONTAINERS
+ && containerInfo.getExtendedContainers().getContainerCase()
+ == DEVICE_SEARCH_RESULT_CONTAINER;
+ }
+
private void setupReturnDragAnimator(float fromX, float fromY, View originalView,
TaskbarReturnPropertiesListener animListener) {
// Finish any pending return animation before starting a new return
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index e521154..1eb8d53 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -73,6 +73,8 @@
private SafeCloseable mViewCaptureCloseable;
private float mTaskbarBackgroundOffset;
+ private float mTaskbarBackgroundProgress;
+ private boolean mIsAnimatingTaskbarPinning = false;
private final MultiPropertyFactory<TaskbarDragLayer> mTaskbarBackgroundAlpha;
@@ -162,10 +164,19 @@
float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
* (1f - mTaskbarBackgroundOffset);
mBackgroundRenderer.setBackgroundHeight(backgroundHeight);
+ mBackgroundRenderer.setBackgroundProgress(mTaskbarBackgroundProgress);
mBackgroundRenderer.draw(canvas);
super.dispatchDraw(canvas);
}
+ /**
+ * Sets animation boolean when taskbar pinning animation starts or stops.
+ */
+ public void setAnimatingTaskbarPinning(boolean animatingTaskbarPinning) {
+ mIsAnimatingTaskbarPinning = animatingTaskbarPinning;
+ mBackgroundRenderer.setAnimatingPinning(mIsAnimatingTaskbarPinning);
+ }
+
protected MultiProperty getBackgroundRendererAlpha() {
return mTaskbarBackgroundAlpha.get(INDEX_ALL_OTHER_STATES);
}
@@ -175,6 +186,15 @@
}
/**
+ * Sets the value for taskbar background switching between persistent and transient backgrounds.
+ * @param progress 0 is transient background, 1 is persistent background.
+ */
+ protected void setTaskbarBackgroundProgress(float progress) {
+ mTaskbarBackgroundProgress = progress;
+ invalidate();
+ }
+
+ /**
* Sets the translation of the background color behind all the Taskbar contents.
* @param offset 0 is fully onscreen, 1 is fully offscreen.
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 867b062..73e32ab 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT;
+import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;
+
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
@@ -24,6 +27,7 @@
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.util.DimensionUtils;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.TouchController;
@@ -58,6 +62,9 @@
// changes the inset visibility.
private final AnimatedFloat mTaskbarAlpha = new AnimatedFloat(this::updateTaskbarAlpha);
+ private final AnimatedFloat mTaskbarBackgroundProgress = new AnimatedFloat(
+ this::updateTaskbarBackgroundProgress);
+
// Initialized in init.
private TaskbarControllers mControllers;
private TaskbarStashViaTouchController mTaskbarStashViaTouchController;
@@ -83,6 +90,10 @@
mOnBackgroundNavButtonColorIntensity = mControllers.navbarButtonsViewController
.getOnTaskbarBackgroundNavButtonColorOverride();
+ mTaskbarBackgroundProgress.updateValue(DisplayController.isTransientTaskbar(mActivity)
+ ? PINNING_TRANSIENT
+ : PINNING_PERSISTENT);
+
mBgTaskbar.value = 1;
mKeyguardBgTaskbar.value = 1;
mNotificationShadeBgTaskbar.value = 1;
@@ -138,6 +149,11 @@
return mBgOffset;
}
+ // AnimatedFloat is for animating between pinned and transient taskbar
+ public AnimatedFloat getTaskbarBackgroundProgress() {
+ return mTaskbarBackgroundProgress;
+ }
+
public AnimatedFloat getTaskbarAlpha() {
return mTaskbarAlpha;
}
@@ -180,10 +196,13 @@
private void updateBackgroundOffset() {
mTaskbarDragLayer.setTaskbarBackgroundOffset(mBgOffset.value);
-
updateOnBackgroundNavButtonColorIntensity();
}
+ private void updateTaskbarBackgroundProgress() {
+ mTaskbarDragLayer.setTaskbarBackgroundProgress(mTaskbarBackgroundProgress.value);
+ }
+
private void updateTaskbarAlpha() {
mTaskbarDragLayer.setAlpha(mTaskbarAlpha.value);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
index de4175d..d29f8ea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
@@ -31,6 +31,7 @@
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
+import com.android.launcher3.taskbar.TaskbarManager.isPhoneMode
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
import com.android.quickstep.util.LottieAnimationColorUtils
@@ -57,7 +58,7 @@
LoggableTaskbarController {
private val isTooltipEnabled: Boolean
- get() = !Utilities.isRunningInTestHarness()
+ get() = !Utilities.isRunningInTestHarness() && !isPhoneMode(activityContext.deviceProfile)
private val isOpen: Boolean
get() = tooltip?.isOpen ?: false
val isBeforeTooltipFeaturesStep: Boolean
@@ -67,11 +68,10 @@
@TaskbarEduTooltipStep
var tooltipStep: Int
get() {
- return activityContext.onboardingPrefs?.getCount(TASKBAR_EDU_TOOLTIP_STEP)
- ?: TOOLTIP_STEP_NONE
+ return TASKBAR_EDU_TOOLTIP_STEP.get(activityContext)
}
private set(step) {
- activityContext.onboardingPrefs?.setEventCount(step, TASKBAR_EDU_TOOLTIP_STEP)
+ TASKBAR_EDU_TOOLTIP_STEP.set(step, activityContext)
}
private var tooltip: TaskbarEduTooltip? = null
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
index c3ec1e5..0443197 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHoverToolTipController.java
@@ -35,8 +35,6 @@
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.VisibleForTesting;
-
import com.android.app.animation.Interpolators;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
@@ -51,8 +49,7 @@
*/
public class TaskbarHoverToolTipController implements View.OnHoverListener {
- @VisibleForTesting protected static final int HOVER_TOOL_TIP_REVEAL_START_DELAY = 400;
- private static final int HOVER_TOOL_TIP_REVEAL_DURATION = 300;
+ private static final int HOVER_TOOL_TIP_REVEAL_DURATION = 250;
private static final int HOVER_TOOL_TIP_EXIT_DURATION = 150;
private final Handler mHoverToolTipHandler = new Handler(Looper.getMainLooper());
@@ -84,6 +81,12 @@
R.style.ArrowTipTaskbarStyle);
mHoverToolTipView = new ArrowTipView(arrowContextWrapper, /* isPointingUp = */ false,
R.layout.arrow_toast);
+ int verticalPadding = arrowContextWrapper.getResources().getDimensionPixelSize(
+ R.dimen.taskbar_tooltip_vertical_padding);
+ int horizontalPadding = arrowContextWrapper.getResources().getDimensionPixelSize(
+ R.dimen.taskbar_tooltip_horizontal_padding);
+ mHoverToolTipView.findViewById(R.id.text).setPadding(horizontalPadding, verticalPadding,
+ horizontalPadding, verticalPadding);
AnimatorSet hoverCloseAnimator = new AnimatorSet();
ObjectAnimator textCloseAnimator = ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 0);
@@ -101,17 +104,18 @@
mHoverToolTipView.setCustomCloseAnimation(hoverCloseAnimator);
AnimatorSet hoverOpenAnimator = new AnimatorSet();
- ObjectAnimator textOpenAnimator = ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 255);
- textOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.33f, 1f));
- ObjectAnimator scaleOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, SCALE_Y, 1f);
+ ObjectAnimator textOpenAnimator =
+ ObjectAnimator.ofInt(mHoverToolTipView, TEXT_ALPHA, 0, 255);
+ textOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.15f, 0.75f));
+ ObjectAnimator scaleOpenAnimator =
+ ObjectAnimator.ofFloat(mHoverToolTipView, SCALE_Y, 0f, 1f);
scaleOpenAnimator.setInterpolator(Interpolators.EMPHASIZED);
- ObjectAnimator alphaOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, ALPHA, 1f);
- alphaOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0.1f, 0.33f));
+ ObjectAnimator alphaOpenAnimator = ObjectAnimator.ofFloat(mHoverToolTipView, ALPHA, 0f, 1f);
+ alphaOpenAnimator.setInterpolator(Interpolators.clampToProgress(LINEAR, 0f, 0.33f));
hoverOpenAnimator.playTogether(
scaleOpenAnimator,
textOpenAnimator,
alphaOpenAnimator);
- hoverOpenAnimator.setStartDelay(HOVER_TOOL_TIP_REVEAL_START_DELAY);
hoverOpenAnimator.setDuration(HOVER_TOOL_TIP_REVEAL_DURATION);
mHoverToolTipView.setCustomOpenAnimation(hoverOpenAnimator);
@@ -120,8 +124,6 @@
mHoverToolTipView.setPivotY(bottom);
mHoverToolTipView.setY(mTaskbarView.getTop() - (bottom - top));
});
- mHoverToolTipView.setScaleY(0f);
- mHoverToolTipView.setAlpha(0f);
}
@Override
@@ -147,8 +149,7 @@
}
private void startRevealHoverToolTip() {
- mHoverToolTipHandler.postDelayed(mRevealHoverToolTipRunnable,
- HOVER_TOOL_TIP_REVEAL_START_DELAY);
+ mHoverToolTipHandler.post(mRevealHoverToolTipRunnable);
}
private void revealHoverToolTip() {
@@ -158,14 +159,12 @@
if (mHoverView instanceof FolderIcon && !((FolderIcon) mHoverView).getIconVisible()) {
return;
}
- mActivity.setTaskbarWindowFullscreen(true);
Rect iconViewBounds = Utilities.getViewBounds(mHoverView);
mHoverToolTipView.showAtLocation(mToolTipText, iconViewBounds.centerX(),
mTaskbarView.getTop(), /* shouldAutoClose= */ false);
}
private void startHideHoverToolTip() {
- mHoverToolTipHandler.removeCallbacks(mRevealHoverToolTipRunnable);
int accessibilityHideTimeout = AccessibilityManagerCompat.getRecommendedTimeoutMillis(
mActivity, /* originalTimeout= */ 0, FLAG_CONTENT_TEXT);
mHoverToolTipHandler.postDelayed(mHideHoverToolTipRunnable, accessibilityHideTimeout);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 5a4534e..0b52195 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -15,9 +15,9 @@
*/
package com.android.launcher3.taskbar
-import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR
import android.graphics.Insets
import android.graphics.Region
+import android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR
import android.os.Binder
import android.os.IBinder
import android.view.Gravity
@@ -41,6 +41,7 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.anim.AlphaUpdateListener
+import com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
import com.android.launcher3.util.DisplayController
import java.io.PrintWriter
@@ -97,7 +98,14 @@
0
}
- windowLayoutParams.providedInsets = getProvidedInsets(insetsRoundedCornerFlag)
+ windowLayoutParams.providedInsets =
+ if (enableTaskbarNoRecreate()) {
+ getProvidedInsets(controllers.sharedState!!.insetsFrameProviders!!,
+ insetsRoundedCornerFlag)
+ } else {
+ getProvidedInsets(insetsRoundedCornerFlag)
+ }
+
if (!context.isGestureNav) {
if (windowLayoutParams.paramsForRotation != null) {
for (layoutParams in windowLayoutParams.paramsForRotation) {
@@ -154,6 +162,26 @@
}
/**
+ * This is for when ENABLE_TASKBAR_NO_RECREATION is enabled. We generate one instance of
+ * providedInsets and use it across the entire lifecycle of TaskbarManager. The only thing
+ * we need to reset is nav bar flags based on insetsRoundedCornerFlag.
+ */
+ private fun getProvidedInsets(providedInsets: Array<InsetsFrameProvider>,
+ insetsRoundedCornerFlag: Int): Array<InsetsFrameProvider> {
+ val navBarsFlag =
+ (if (context.isGestureNav) FLAG_SUPPRESS_SCRIM else 0) or insetsRoundedCornerFlag
+ for (provider in providedInsets) {
+ if (provider.type == navigationBars()) {
+ provider.setFlags(
+ navBarsFlag,
+ FLAG_SUPPRESS_SCRIM or FLAG_INSETS_ROUNDED_CORNER
+ )
+ }
+ }
+ return providedInsets
+ }
+
+ /**
* The inset types and number of insets provided have to match for both gesture nav and button
* nav. The values and the order of the elements in array are allowed to differ.
* Reason being WM does not allow types and number of insets changing for a given window once it
@@ -197,7 +225,6 @@
provider.insetsSize = Insets.of(0, 0, rightIndexInset, 0)
}
-
// When in gesture nav, report the stashed height to the IME, to allow hiding the
// IME navigation bar.
val imeInsetsSize = if (ENABLE_HIDE_IME_CAPTION_BAR && context.isGestureNav) {
@@ -208,6 +235,12 @@
val imeInsetsSizeOverride =
arrayOf(
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize),
+ InsetsFrameProvider.InsetsSizeOverride(TYPE_VOICE_INTERACTION,
+ // No-op override to keep the size and types in sync with the
+ // override below (insetsSizeOverrides must have the same length and
+ // types after the window is added according to
+ // WindowManagerService#relayoutWindow)
+ provider.insetsSize)
)
// Use 0 tappableElement insets for the VoiceInteractionWindow when gesture nav is enabled.
val visInsetsSizeForTappableElement =
@@ -216,8 +249,7 @@
val insetsSizeOverrideForTappableElement =
arrayOf(
InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, imeInsetsSize),
- InsetsFrameProvider.InsetsSizeOverride(
- TYPE_VOICE_INTERACTION,
+ InsetsFrameProvider.InsetsSizeOverride(TYPE_VOICE_INTERACTION,
visInsetsSizeForTappableElement
),
)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 90f7bea..267b15c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -18,6 +18,7 @@
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.launcher3.taskbar.TaskbarKeyguardController.MASK_ANY_SYSUI_LOCKED;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_OVERVIEW;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
@@ -44,6 +45,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
@@ -66,13 +68,13 @@
private static final String TAG = TaskbarLauncherStateController.class.getSimpleName();
private static final boolean DEBUG = false;
- /** Launcher activity is resumed and focused. */
- public static final int FLAG_RESUMED = 1 << 0;
+ /** Launcher activity is visible and focused. */
+ public static final int FLAG_VISIBLE = 1 << 0;
/**
- * A external transition / animation is running that will result in FLAG_RESUMED being set.
+ * A external transition / animation is running that will result in FLAG_VISIBLE being set.
**/
- public static final int FLAG_TRANSITION_TO_RESUMED = 1 << 1;
+ public static final int FLAG_TRANSITION_TO_VISIBLE = 1 << 1;
/**
* Set while the launcher state machine is performing a state transition, see {@link
@@ -116,7 +118,7 @@
*/
private static final int FLAG_TASKBAR_HIDDEN = 1 << 6;
- private static final int FLAGS_LAUNCHER_ACTIVE = FLAG_RESUMED | FLAG_TRANSITION_TO_RESUMED;
+ private static final int FLAGS_LAUNCHER_ACTIVE = FLAG_VISIBLE | FLAG_TRANSITION_TO_VISIBLE;
/** Equivalent to an int with all 1s for binary operation purposes */
private static final int FLAGS_ALL = ~0;
@@ -204,11 +206,16 @@
updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, false);
// TODO(b/279514548) Cleans up bad state that can occur when user interacts with
// taskbar on top of transparent activity.
- if (finalState == LauncherState.NORMAL && mLauncher.hasBeenResumed()) {
- updateStateForFlag(FLAG_RESUMED, true);
+ if (!FeatureFlags.enableHomeTransitionListener()
+ && finalState == LauncherState.NORMAL
+ && mLauncher.hasBeenResumed()) {
+ updateStateForFlag(FLAG_VISIBLE, true);
}
applyState();
- boolean disallowLongClick = finalState == LauncherState.OVERVIEW_SPLIT_SELECT;
+ boolean disallowLongClick =
+ FeatureFlags.enableSplitContextually()
+ ? mLauncher.isSplitSelectionEnabled()
+ : finalState == LauncherState.OVERVIEW_SPLIT_SELECT;
com.android.launcher3.taskbar.Utilities.setOverviewDragState(
mControllers, finalState.disallowTaskbarGlobalDrag(),
disallowLongClick, finalState.allowTaskbarInitialSplitSelection());
@@ -277,7 +284,7 @@
}
stashController.updateStateForFlag(FLAG_IN_APP, false);
- updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, true);
+ updateStateForFlag(FLAG_TRANSITION_TO_VISIBLE, true);
animatorSet.play(stashController.createApplyStateAnimator(duration));
animatorSet.play(applyState(duration, false));
@@ -416,6 +423,9 @@
controllers.bubbleStashController.setBubblesShowingOnOverview(onOverview);
});
+ mControllers.taskbarStashController.updateStateForFlag(FLAG_IN_OVERVIEW,
+ mLauncherState == LauncherState.OVERVIEW);
+
AnimatorSet animatorSet = new AnimatorSet();
if (hasAnyFlag(changedFlags, FLAG_LAUNCHER_IN_STATE_TRANSITION)) {
@@ -425,7 +435,7 @@
if (launcherTransitionCompleted
&& mLauncherState == LauncherState.QUICK_SWITCH_FROM_HOME) {
// We're about to be paused, set immediately to ensure seamless handoff.
- updateStateForFlag(FLAG_RESUMED, false);
+ updateStateForFlag(FLAG_VISIBLE, false);
applyState(0 /* duration */);
}
if (mLauncherState == LauncherState.NORMAL) {
@@ -751,10 +761,10 @@
mTaskBarRecentsAnimationListener = null;
((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(null);
- // Update the resumed state immediately to ensure a seamless handoff
- boolean launcherResumed = !finishedToApp;
- updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, false);
- updateStateForFlag(FLAG_RESUMED, launcherResumed);
+ // Update the visible state immediately to ensure a seamless handoff
+ boolean launcherVisible = !finishedToApp;
+ updateStateForFlag(FLAG_TRANSITION_TO_VISIBLE, false);
+ updateStateForFlag(FLAG_VISIBLE, launcherVisible);
applyState();
TaskbarStashController controller = mControllers.taskbarStashController;
@@ -768,8 +778,8 @@
private static String getStateString(int flags) {
StringJoiner result = new StringJoiner("|");
- appendFlag(result, flags, FLAG_RESUMED, "resumed");
- appendFlag(result, flags, FLAG_TRANSITION_TO_RESUMED, "transition_to_resumed");
+ appendFlag(result, flags, FLAG_VISIBLE, "flag_visible");
+ appendFlag(result, flags, FLAG_TRANSITION_TO_VISIBLE, "transition_to_visible");
appendFlag(result, flags, FLAG_LAUNCHER_IN_STATE_TRANSITION,
"launcher_in_state_transition");
appendFlag(result, flags, FLAG_AWAKE, "awake");
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index b115ca8..9bb7e67 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -18,23 +18,24 @@
import static android.content.Context.RECEIVER_NOT_EXPORTED;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING;
-import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY;
+import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate;
import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
+import static com.android.quickstep.util.SystemActionConstants.ACTION_SHOW_TASKBAR;
+import static com.android.quickstep.util.SystemActionConstants.SYSTEM_ACTION_ID_TASKBAR;
import android.annotation.SuppressLint;
-import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
@@ -45,6 +46,9 @@
import android.provider.Settings;
import android.util.Log;
import android.view.Display;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -53,12 +57,11 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.quickstep.RecentsActivity;
@@ -105,6 +108,9 @@
Settings.Secure.NAV_BAR_KIDS_MODE);
private final Context mContext;
+ private WindowManager mWindowManager;
+ private FrameLayout mTaskbarRootLayout;
+ private boolean mAddedWindow;
private final TaskbarNavButtonController mNavButtonController;
private final ComponentCallbacks mComponentCallbacks;
@@ -135,44 +141,28 @@
private boolean mUserUnlocked = false;
- public static final int SYSTEM_ACTION_ID_TASKBAR = 499;
-
- /**
- * For Taskbar broadcast intent filter.
- */
- public static final String ACTION_SHOW_TASKBAR = "ACTION_SHOW_TASKBAR";
-
private final SimpleBroadcastReceiver mTaskbarBroadcastReceiver =
new SimpleBroadcastReceiver(this::showTaskbarFromBroadcast);
- private final SharedPreferences.OnSharedPreferenceChangeListener
- mTaskbarPinningPreferenceChangeListener = (sharedPreferences, key) -> {
- if (TASKBAR_PINNING_KEY.equals(key)) {
- recreateTaskbar();
- }
- };
-
- private final ActivityLifecycleCallbacksAdapter mLifecycleCallbacks =
- new ActivityLifecycleCallbacksAdapter() {
- @Override
- public void onActivityDestroyed(Activity activity) {
- if (mActivity != activity) return;
- if (mActivity != null) {
- mActivity.removeOnDeviceProfileChangeListener(
- mDebugActivityDeviceProfileChanged);
- Log.d(TASKBAR_NOT_DESTROYED_TAG,
- "unregistering activity lifecycle callbacks from "
- + "onActivityDestroyed.");
- mActivity.unregisterActivityLifecycleCallbacks(this);
- }
- mActivity = null;
- debugWhyTaskbarNotDestroyed("clearActivity");
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.setUIController(TaskbarUIController.DEFAULT);
- }
- mUnfoldProgressProvider.setSourceProvider(null);
- }
- };
+ private final Runnable mActivityOnDestroyCallback = new Runnable() {
+ @Override
+ public void run() {
+ if (mActivity != null) {
+ mActivity.removeOnDeviceProfileChangeListener(
+ mDebugActivityDeviceProfileChanged);
+ Log.d(TASKBAR_NOT_DESTROYED_TAG,
+ "unregistering activity lifecycle callbacks from "
+ + "onActivityDestroyed.");
+ mActivity.removeEventCallback(EVENT_DESTROYED, this);
+ }
+ mActivity = null;
+ debugWhyTaskbarNotDestroyed("clearActivity");
+ if (mTaskbarActivityContext != null) {
+ mTaskbarActivityContext.setUIController(TaskbarUIController.DEFAULT);
+ }
+ mUnfoldProgressProvider.setSourceProvider(null);
+ }
+ };
UnfoldTransitionProgressProvider.TransitionProgressListener mUnfoldTransitionProgressListener =
new UnfoldTransitionProgressProvider.TransitionProgressListener() {
@@ -207,7 +197,23 @@
public TaskbarManager(TouchInteractionService service) {
Display display =
service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
- mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
+ mContext = service.createWindowContext(display,
+ FLAG_HIDE_NAVBAR_WINDOW ? TYPE_NAVIGATION_BAR : TYPE_NAVIGATION_BAR_PANEL, null);
+ if (enableTaskbarNoRecreate()) {
+ mWindowManager = mContext.getSystemService(WindowManager.class);
+ mTaskbarRootLayout = new FrameLayout(mContext) {
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ // The motion events can be outside the view bounds of task bar, and hence
+ // manually dispatching them to the drag layer here.
+ if (mTaskbarActivityContext != null
+ && mTaskbarActivityContext.getDragLayer().isAttachedToWindow()) {
+ return mTaskbarActivityContext.getDragLayer().dispatchTouchEvent(ev);
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+ };
+ }
mNavButtonController = new TaskbarNavButtonController(service,
SystemUiProxy.INSTANCE.get(mContext), new Handler(),
AssistUtils.newInstance(mContext));
@@ -288,13 +294,16 @@
private void destroyExistingTaskbar() {
debugWhyTaskbarNotDestroyed("destroyExistingTaskbar: " + mTaskbarActivityContext);
if (mTaskbarActivityContext != null) {
- LauncherPrefs.get(mContext).removeListener(mTaskbarPinningPreferenceChangeListener,
- TASKBAR_PINNING);
mTaskbarActivityContext.onDestroy();
- if (!FLAG_HIDE_NAVBAR_WINDOW) {
+ if (!FLAG_HIDE_NAVBAR_WINDOW || enableTaskbarNoRecreate()) {
mTaskbarActivityContext = null;
}
}
+ DeviceProfile dp = mUserUnlocked ?
+ LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
+ if (dp == null || !isTaskbarPresent(dp)) {
+ removeTaskbarRootViewFromWindow();
+ }
}
/**
@@ -322,7 +331,7 @@
return;
}
- mTaskbarActivityContext.toggleAllApps();
+ mTaskbarActivityContext.toggleAllAppsSearch();
}
/**
@@ -343,6 +352,7 @@
mUserUnlocked = true;
LauncherAppState.getIDP(mContext).addOnChangeListener(mIdpChangeListener);
recreateTaskbar();
+ addTaskbarRootViewToWindow();
}
/**
@@ -358,7 +368,7 @@
mActivity.addOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
Log.d(TASKBAR_NOT_DESTROYED_TAG,
"registering activity lifecycle callbacks from setActivity().");
- mActivity.registerActivityLifecycleCallbacks(mLifecycleCallbacks);
+ mActivity.addEventCallback(EVENT_DESTROYED, mActivityOnDestroyCallback);
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
getUnfoldTransitionProgressProviderForActivity(activity);
if (unfoldTransitionProgressProvider != null) {
@@ -425,13 +435,14 @@
return;
}
- if (mTaskbarActivityContext == null) {
+ if (enableTaskbarNoRecreate() || mTaskbarActivityContext == null) {
mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp,
- mNavButtonController,
- mUnfoldProgressProvider);
+ mNavButtonController, mUnfoldProgressProvider);
} else {
mTaskbarActivityContext.updateDeviceProfile(dp);
}
+ mSharedState.startTaskbarVariantIsTransient =
+ DisplayController.isTransientTaskbar(mTaskbarActivityContext);
mTaskbarActivityContext.init(mSharedState);
if (mActivity != null) {
@@ -439,9 +450,12 @@
createTaskbarUIControllerForActivity(mActivity));
}
- // We to wait until user unlocks the device to attach listener.
- LauncherPrefs.get(mContext).addListener(mTaskbarPinningPreferenceChangeListener,
- TASKBAR_PINNING);
+ if (enableTaskbarNoRecreate()) {
+ addTaskbarRootViewToWindow();
+ mTaskbarRootLayout.removeAllViews();
+ mTaskbarRootLayout.addView(mTaskbarActivityContext.getDragLayer());
+ mTaskbarActivityContext.notifyUpdateLayoutParams();
+ }
} finally {
Trace.endSection();
}
@@ -530,7 +544,7 @@
Log.d(TASKBAR_NOT_DESTROYED_TAG,
"unregistering activity lifecycle callbacks from "
+ "removeActivityCallbackAndListeners().");
- mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
+ mActivity.removeEventCallback(EVENT_DESTROYED, mActivityOnDestroyCallback);
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
getUnfoldTransitionProgressProviderForActivity(mActivity);
if (unfoldTransitionProgressProvider != null) {
@@ -573,6 +587,21 @@
}
}
+ private void addTaskbarRootViewToWindow() {
+ if (enableTaskbarNoRecreate() && !mAddedWindow && mTaskbarActivityContext != null) {
+ mWindowManager.addView(mTaskbarRootLayout,
+ mTaskbarActivityContext.getWindowLayoutParams());
+ mAddedWindow = true;
+ }
+ }
+
+ private void removeTaskbarRootViewFromWindow() {
+ if (enableTaskbarNoRecreate() && mAddedWindow) {
+ mWindowManager.removeViewImmediate(mTaskbarRootLayout);
+ mAddedWindow = false;
+ }
+ }
+
/** Temp logs for b/254119092. */
public void debugWhyTaskbarNotDestroyed(String debugReason) {
StringJoiner log = new StringJoiner("\n");
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 03df036..3f72e5d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -27,6 +27,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_IME_SWITCHER_BUTTON_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
@@ -52,7 +53,6 @@
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.AssistUtils;
-import com.android.quickstep.views.DesktopTaskView;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -274,7 +274,7 @@
private void navigateHome() {
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
DesktopVisibilityController desktopVisibilityController =
LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
if (desktopVisibilityController != null) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
new file mode 100644
index 0000000..cbfa024
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.taskbar
+
+import android.animation.AnimatorSet
+import android.view.View
+import androidx.core.animation.doOnEnd
+import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN
+import com.android.launcher3.taskbar.TaskbarDividerPopupView.Companion.createAndPopulate
+import java.io.PrintWriter
+
+/** Controls taskbar pinning through a popup view. */
+class TaskbarPinningController(private val context: TaskbarActivityContext) :
+ TaskbarControllers.LoggableTaskbarController {
+
+ private lateinit var controllers: TaskbarControllers
+ private lateinit var taskbarSharedState: TaskbarSharedState
+ private val launcherPrefs = LauncherPrefs.get(context)
+ private val statsLogManager = context.statsLogManager
+ private var isAnimatingTaskbarPinning = false
+
+ fun init(taskbarControllers: TaskbarControllers, sharedState: TaskbarSharedState) {
+ controllers = taskbarControllers
+ taskbarSharedState = sharedState
+ }
+
+ fun showPinningView(view: View) {
+ context.isTaskbarWindowFullscreen = true
+
+ view.post {
+ val popupView = createAndPopulate(view, context)
+ popupView.requestFocus()
+
+ popupView.onCloseCallback =
+ callback@{ didPreferenceChange ->
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE)
+ context.dragLayer.post { context.onPopupVisibilityChanged(false) }
+
+ if (!didPreferenceChange) {
+ return@callback
+ }
+ val animateToValue =
+ if (!launcherPrefs.get(TASKBAR_PINNING)) {
+ PINNING_PERSISTENT
+ } else {
+ PINNING_TRANSIENT
+ }
+ taskbarSharedState.taskbarWasPinned = animateToValue == PINNING_TRANSIENT
+ animateTaskbarPinning(animateToValue)
+ }
+ context.onPopupVisibilityChanged(true)
+ popupView.show()
+ statsLogManager.logger().log(LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN)
+ }
+ }
+
+ private fun animateTaskbarPinning(animateToValue: Float) {
+ val animatorSet = AnimatorSet()
+ val taskbarViewController = controllers.taskbarViewController
+ val dragLayerController = controllers.taskbarDragLayerController
+
+ animatorSet.playTogether(
+ dragLayerController.taskbarBackgroundProgress.animateToValue(animateToValue),
+ taskbarViewController.taskbarIconTranslationYForPinning.animateToValue(animateToValue),
+ taskbarViewController.taskbarIconScaleForPinning.animateToValue(animateToValue),
+ taskbarViewController.taskbarIconTranslationXForPinning.animateToValue(animateToValue)
+ )
+
+ controllers.taskbarOverlayController.hideWindow()
+
+ animatorSet.doOnEnd { recreateTaskbarAndUpdatePinningValue() }
+ animatorSet.duration = PINNING_ANIMATION_DURATION
+ updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(true)
+ taskbarViewController.animateAwayNotificationDotsDuringTaskbarPinningAnimation()
+ animatorSet.start()
+ }
+
+ private fun updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(isAnimating: Boolean) {
+ isAnimatingTaskbarPinning = isAnimating
+ context.dragLayer.setAnimatingTaskbarPinning(isAnimating)
+ }
+
+ private fun recreateTaskbarAndUpdatePinningValue() {
+ updateIsAnimatingTaskbarPinningAndNotifyTaskbarDragLayer(false)
+ launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
+ }
+
+ override fun dumpLogs(prefix: String, pw: PrintWriter) {
+ pw.println(prefix + "TaskbarPinningController:")
+ pw.println("$prefix\tisAnimatingTaskbarPinning=$isAnimatingTaskbarPinning")
+ pw.println("$prefix\tTASKBAR_PINNING shared pref =" + launcherPrefs.get(TASKBAR_PINNING))
+ }
+
+ companion object {
+ const val PINNING_PERSISTENT = 1f
+ const val PINNING_TRANSIENT = 0f
+ const val PINNING_ANIMATION_DURATION = 500L
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 512b77a..a667dca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
import android.content.Intent;
@@ -163,19 +162,9 @@
.filter(Objects::nonNull)
.collect(Collectors.toList());
- if (ENABLE_MATERIAL_U_POPUP.get()) {
- container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
- R.layout.popup_container_material_u, context.getDragLayer(), false);
- container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
- } else {
- container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
+ container = (PopupContainerWithArrow) context.getLayoutInflater().inflate(
R.layout.popup_container, context.getDragLayer(), false);
- container.populateAndShow(
- icon,
- deepShortcutCount,
- mPopupDataProvider.getNotificationKeysForItem(item),
- systemShortcuts);
- }
+ container.populateAndShowRows(icon, deepShortcutCount, systemShortcuts);
container.addOnAttachStateChangeListener(
new PopupLiveUpdateHandler<BaseTaskbarContext>(context, container) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
index cdc6d59..e40757a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
@@ -70,6 +70,10 @@
invalidate();
}
+ protected float getScrimAlpha() {
+ return mRenderer.getPaint().getAlpha() / 255f;
+ }
+
/**
* Sets the roundness of the round corner above Taskbar.
* @param cornerRoundness 0 has no round corner, 1 has complete round corner.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
index 1c250bf..712374d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -15,9 +15,13 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.taskbar.bubbles.BubbleBarController.BUBBLE_BAR_ENABLED;
+import static android.view.View.VISIBLE;
+
+import static com.android.launcher3.taskbar.bubbles.BubbleBarController.isBubbleBarEnabled;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
+import static com.android.wm.shell.common.bubbles.BubbleConstants.BUBBLE_EXPANDED_SCRIM_ALPHA;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
import android.animation.ObjectAnimator;
import android.view.animation.Interpolator;
@@ -35,13 +39,13 @@
public class TaskbarScrimViewController implements TaskbarControllers.LoggableTaskbarController,
TaskbarControllers.BackgroundRendererController {
- private static final float SCRIM_ALPHA = 0.6f;
-
private static final Interpolator SCRIM_ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
private static final Interpolator SCRIM_ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
private final TaskbarActivityContext mActivity;
private final TaskbarScrimView mScrimView;
+ private boolean mTaskbarVisible;
+ private int mSysUiStateFlags;
// Alpha property for the scrim.
private final AnimatedFloat mScrimAlpha = new AnimatedFloat(this::updateScrimAlpha);
@@ -62,35 +66,60 @@
}
/**
+ * Called when the taskbar visibility changes.
+ *
+ * @param visibility the current visibility of {@link TaskbarView}.
+ */
+ public void onTaskbarVisibilityChanged(int visibility) {
+ mTaskbarVisible = visibility == VISIBLE;
+ if (shouldShowScrim()) {
+ showScrim(true, getScrimAlpha(), false /* skipAnim */);
+ } else if (mScrimView.getScrimAlpha() > 0f) {
+ showScrim(false, 0, false /* skipAnim */);
+ }
+ }
+
+ /**
* Updates the scrim state based on the flags.
*/
public void updateStateForSysuiFlags(int stateFlags, boolean skipAnim) {
- if (BUBBLE_BAR_ENABLED && DisplayController.isTransientTaskbar(mActivity)) {
+ if (isBubbleBarEnabled() && DisplayController.isTransientTaskbar(mActivity)) {
// These scrims aren't used if bubble bar & transient taskbar are active.
return;
}
- final boolean bubblesExpanded = (stateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
+ mSysUiStateFlags = stateFlags;
+ showScrim(shouldShowScrim(), getScrimAlpha(), skipAnim);
+ }
+
+ private boolean shouldShowScrim() {
+ final boolean bubblesExpanded = (mSysUiStateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
+ boolean isShadeVisible = (mSysUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE) != 0;
+ return bubblesExpanded && !mControllers.navbarButtonsViewController.isImeVisible()
+ && !isShadeVisible
+ && !mControllers.taskbarStashController.isStashed()
+ && mTaskbarVisible;
+ }
+
+ private float getScrimAlpha() {
final boolean manageMenuExpanded =
- (stateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
- final boolean showScrim = !mControllers.navbarButtonsViewController.isImeVisible()
- && bubblesExpanded
- && mControllers.taskbarStashController.isTaskbarVisibleAndNotStashing();
- final float scrimAlpha = manageMenuExpanded
+ (mSysUiStateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
+ return manageMenuExpanded
// When manage menu shows there's the first scrim and second scrim so figure out
// what the total transparency would be.
- ? (SCRIM_ALPHA + (SCRIM_ALPHA * (1 - SCRIM_ALPHA)))
- : showScrim ? SCRIM_ALPHA : 0;
- showScrim(showScrim, scrimAlpha, skipAnim);
+ ? (BUBBLE_EXPANDED_SCRIM_ALPHA + (BUBBLE_EXPANDED_SCRIM_ALPHA
+ * (1 - BUBBLE_EXPANDED_SCRIM_ALPHA)))
+ : shouldShowScrim() ? BUBBLE_EXPANDED_SCRIM_ALPHA : 0;
}
private void showScrim(boolean showScrim, float alpha, boolean skipAnim) {
mScrimView.setOnClickListener(showScrim ? (view) -> onClick() : null);
mScrimView.setClickable(showScrim);
- ObjectAnimator anim = mScrimAlpha.animateToValue(showScrim ? alpha : 0);
- anim.setInterpolator(showScrim ? SCRIM_ALPHA_IN : SCRIM_ALPHA_OUT);
- anim.start();
if (skipAnim) {
- anim.end();
+ mScrimView.setScrimAlpha(alpha);
+ } else {
+ ObjectAnimator anim = mScrimAlpha.animateToValue(showScrim ? alpha : 0);
+ anim.setInterpolator(showScrim ? SCRIM_ALPHA_IN : SCRIM_ALPHA_OUT);
+ anim.start();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index 66ca7d9..176a8c5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -15,15 +15,28 @@
*/
package com.android.launcher3.taskbar;
+import static android.view.InsetsFrameProvider.SOURCE_DISPLAY;
+import static android.view.WindowInsets.Type.mandatorySystemGestures;
+import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowInsets.Type.systemGestures;
+import static android.view.WindowInsets.Type.tappableElement;
+
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.DISPLAY_PROGRESS_COUNT;
import android.app.PendingIntent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.InsetsFrameProvider;
/**
* State shared across different taskbar instance
*/
public class TaskbarSharedState {
+ private final IBinder mInsetsOwner = new Binder();
+ private static int INDEX_LEFT = 0;
+ private static int INDEX_RIGHT = 1;
+
// TaskbarManager#onSystemUiFlagsChanged
public int sysuiStateFlags;
@@ -48,4 +61,21 @@
// Taskbar System Action
public PendingIntent taskbarSystemActionPendingIntent;
+
+ public final InsetsFrameProvider[] insetsFrameProviders = new InsetsFrameProvider[] {
+ new InsetsFrameProvider(mInsetsOwner, 0, navigationBars()),
+ new InsetsFrameProvider(mInsetsOwner, 0, tappableElement()),
+ new InsetsFrameProvider(mInsetsOwner, 0, mandatorySystemGestures()),
+ new InsetsFrameProvider(mInsetsOwner, INDEX_LEFT, systemGestures())
+ .setSource(SOURCE_DISPLAY),
+ new InsetsFrameProvider(mInsetsOwner, INDEX_RIGHT, systemGestures())
+ .setSource(SOURCE_DISPLAY)
+ };
+
+ // Allows us to shift translation logic when doing taskbar pinning animation.
+ public Boolean startTaskbarVariantIsTransient = true;
+
+ // To track if taskbar was pinned using taskbar pinning feature at the time of recreate,
+ // so we can unstash transient taskbar when we un-pinning taskbar.
+ public Boolean taskbarWasPinned = false;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index a920dfa..5be74be 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -22,17 +22,18 @@
import static com.android.app.animation.Interpolators.FINAL_FRAME;
import static com.android.app.animation.Interpolators.INSTANT;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY;
+import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_PINNING;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_SHOW;
import static com.android.launcher3.taskbar.TaskbarKeyguardController.MASK_ANY_SYSUI_LOCKED;
-import static com.android.launcher3.taskbar.TaskbarManager.SYSTEM_ACTION_ID_TASKBAR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
+import static com.android.quickstep.util.SystemActionConstants.SYSTEM_ACTION_ID_TASKBAR;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE;
@@ -96,6 +97,7 @@
public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 9; // Autohide (transient taskbar).
public static final int FLAG_STASHED_SYSUI = 1 << 10; // app pinning,...
public static final int FLAG_STASHED_DEVICE_LOCKED = 1 << 11; // device is locked: keyguard, ...
+ public static final int FLAG_IN_OVERVIEW = 1 << 12; // launcher is in overview
// If any of these flags are enabled, isInApp should return true.
private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
@@ -276,8 +278,14 @@
mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
mAccessibilityManager = mActivity.getSystemService(AccessibilityManager.class);
- mUnstashedHeight = mActivity.getDeviceProfile().taskbarHeight;
- mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarHeight;
+ if (isPhoneMode()) {
+ mUnstashedHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_size);
+ mStashedHeight = mActivity.getResources().getDimensionPixelSize(
+ R.dimen.taskbar_stashed_size);
+ } else {
+ mUnstashedHeight = mActivity.getDeviceProfile().taskbarHeight;
+ mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarHeight;
+ }
}
/**
@@ -329,7 +337,8 @@
&& mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF);
boolean isInSetup = !mActivity.isUserSetupComplete() || setupUIVisible;
updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
- updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, isTransientTaskbar);
+ updateStateForFlag(FLAG_STASHED_IN_APP_AUTO,
+ isTransientTaskbar && !mTaskbarSharedState.taskbarWasPinned);
updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup);
updateStateForFlag(FLAG_IN_SETUP, isInSetup);
updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, isPhoneMode()
@@ -338,6 +347,9 @@
// us that we're paused until a bit later. This avoids flickering upon recreating taskbar.
updateStateForFlag(FLAG_IN_APP, true);
applyState(/* duration = */ 0);
+ if (mTaskbarSharedState.taskbarWasPinned) {
+ tryStartTaskbarTimeout();
+ }
notifyStashChange(/* visible */ false, /* stashed */ isStashedInApp());
}
@@ -353,7 +365,7 @@
* Returns whether the user can manually stash the taskbar based on the current device state.
*/
protected boolean supportsManualStashing() {
- if (ENABLE_TASKBAR_PINNING.get() && mPrefs.getBoolean(TASKBAR_PINNING_KEY, false)) {
+ if (ENABLE_TASKBAR_PINNING.get() && LauncherPrefs.get(mActivity).get(TASKBAR_PINNING)) {
return false;
}
return supportsVisualStashing()
@@ -1015,9 +1027,12 @@
updateStateForFlag(FLAG_STASHED_IN_APP_SYSUI, hasAnyFlag(systemUiStateFlags,
SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE));
- updateStateForFlag(FLAG_STASHED_SYSUI,
- hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));
+ boolean stashForBubbles = hasAnyFlag(FLAG_IN_OVERVIEW)
+ && hasAnyFlag(systemUiStateFlags, SYSUI_STATE_BUBBLES_EXPANDED)
+ && DisplayController.isTransientTaskbar(mActivity);
+ updateStateForFlag(FLAG_STASHED_SYSUI,
+ hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING) || stashForBubbles);
boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED)
&& !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY);
updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 6fad655..445b312 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -43,7 +43,6 @@
import com.android.systemui.shared.recents.model.Task;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;
@@ -156,7 +155,7 @@
mControllers.taskbarActivityContext.startTranslationSpring();
}
- /*
+ /**
* @param ev MotionEvent in screen coordinates.
* @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
*/
@@ -165,6 +164,14 @@
|| mControllers.navbarButtonsViewController.isEventOverAnyItem(ev);
}
+ /** Checks if the given {@link MotionEvent} is over the bubble bar stash handle. */
+ public boolean isEventOverBubbleBarStashHandle(MotionEvent ev) {
+ return mControllers.bubbleControllers.map(
+ bubbleControllers ->
+ bubbleControllers.bubbleStashController.isEventOverStashHandle(ev))
+ .orElse(false);
+ }
+
/**
* Returns true if icons should be aligned to hotseat in the current transition.
*/
@@ -336,4 +343,7 @@
.stream()
.map(mControllers.taskbarPopupController::createSplitShortcutFactory);
}
+
+ /** Adjusts the hotseat for the bubble bar. */
+ public void adjustHotseatForBubbleBar(boolean isBubbleBarVisible) {}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index fa5a1ae..a7461b7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -18,7 +18,8 @@
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import android.content.Context;
@@ -33,6 +34,8 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
+import androidx.annotation.DimenRes;
+import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -90,11 +93,9 @@
// Only non-null when device supports having an All Apps button.
private @Nullable IconButtonView mTaskbarDivider;
- private View mQsb;
+ private final View mQsb;
- private float mTransientTaskbarMinWidth;
-
- private float mTransientTaskbarAllAppsButtonTranslationXOffset;
+ private final float mTransientTaskbarMinWidth;
private boolean mShouldTryStartAlign;
@@ -120,17 +121,17 @@
boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext)
&& !TaskbarManager.isPhoneMode(mActivityContext.getDeviceProfile());
mIsRtl = Utilities.isRtl(resources);
- mTransientTaskbarMinWidth = mContext.getResources().getDimension(
- R.dimen.transient_taskbar_min_width);
- mTransientTaskbarAllAppsButtonTranslationXOffset =
- resources.getDimension(isTransientTaskbar
- ? R.dimen.transient_taskbar_all_apps_button_translation_x_offset
- : R.dimen.taskbar_all_apps_button_translation_x_offset);
+ mTransientTaskbarMinWidth = resources.getDimension(R.dimen.transient_taskbar_min_width);
+
onDeviceProfileChanged(mActivityContext.getDeviceProfile());
int actualMargin = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
int actualIconSize = mActivityContext.getDeviceProfile().taskbarIconSize;
+ if (FeatureFlags.ENABLE_TASKBAR_PINNING.get()) {
+ DeviceProfile deviceProfile = mActivityContext.getTransientTaskbarDeviceProfile();
+ actualIconSize = deviceProfile.taskbarIconSize;
+ }
int visualIconSize = (int) (actualIconSize * ICON_VISIBLE_AREA_FACTOR);
mIconTouchSize = Math.max(actualIconSize,
@@ -138,8 +139,11 @@
// We layout the icons to be of mIconTouchSize in width and height
mItemMarginLeftRight = actualMargin - (mIconTouchSize - visualIconSize) / 2;
- mItemPadding = (mIconTouchSize - actualIconSize) / 2;
+ // We always layout taskbar as a transient taskbar when we have taskbar pinning feature on,
+ // then we scale and translate the icons to match persistent taskbar designs, so we use
+ // taskbar icon size from current device profile to calculate correct item padding.
+ mItemPadding = (mIconTouchSize - mActivityContext.getDeviceProfile().taskbarIconSize) / 2;
mFolderLeaveBehindColor = Themes.getAttrColor(mActivityContext,
android.R.attr.textColorTertiary);
@@ -149,9 +153,8 @@
if (!mActivityContext.getPackageManager().hasSystemFeature(FEATURE_PC)) {
mAllAppsButton = (IconButtonView) LayoutInflater.from(context)
.inflate(R.layout.taskbar_all_apps_button, this, false);
- mAllAppsButton.setIconDrawable(resources.getDrawable(isTransientTaskbar
- ? R.drawable.ic_transient_taskbar_all_apps_button
- : R.drawable.ic_taskbar_all_apps_button));
+ mAllAppsButton.setIconDrawable(resources.getDrawable(
+ getAllAppsButton(isTransientTaskbar)));
mAllAppsButton.setScaleX(mIsRtl ? -1 : 1);
mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
mAllAppsButton.setForegroundTint(
@@ -171,6 +174,42 @@
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
}
+ @DrawableRes
+ private int getAllAppsButton(boolean isTransientTaskbar) {
+ boolean shouldSelectTransientIcon =
+ (isTransientTaskbar || FeatureFlags.ENABLE_TASKBAR_PINNING.get())
+ && !mActivityContext.isThreeButtonNav();
+ if (ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
+ return shouldSelectTransientIcon
+ ? R.drawable.ic_transient_taskbar_all_apps_search_button
+ : R.drawable.ic_taskbar_all_apps_search_button;
+ } else {
+ return shouldSelectTransientIcon
+ ? R.drawable.ic_transient_taskbar_all_apps_button
+ : R.drawable.ic_taskbar_all_apps_button;
+ }
+ }
+
+ @DimenRes
+ public int getAllAppsButtonTranslationXOffset(boolean isTransientTaskbar) {
+ if (isTransientTaskbar) {
+ return R.dimen.transient_taskbar_all_apps_button_translation_x_offset;
+ } else {
+ return ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()
+ ? R.dimen.taskbar_all_apps_search_button_translation_x_offset
+ : R.dimen.taskbar_all_apps_button_translation_x_offset;
+ }
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ boolean changed = getVisibility() != visibility;
+ super.setVisibility(visibility);
+ if (changed && mControllerCallbacks != null) {
+ mControllerCallbacks.notifyVisibilityChanged();
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -324,7 +363,7 @@
}
}
setClickAndLongClickListenersForIcon(hotseatView);
- if (ENABLE_CURSOR_HOVER_STATES.get()) {
+ if (enableCursorHoverStates()) {
setHoverListenerForIcon(hotseatView);
}
nextViewIndex++;
@@ -335,8 +374,6 @@
}
if (mAllAppsButton != null) {
- mAllAppsButton.setTranslationXForTaskbarAllAppsIcon(getChildCount() > 0
- ? mTransientTaskbarAllAppsButtonTranslationXOffset : 0f);
addView(mAllAppsButton, mIsRtl ? getChildCount() : 0);
// if only all apps button present, don't include divider view.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 4614e8d..78d5bd3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -21,14 +21,19 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.Utilities.mapRange;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.anim.AnimatedFloat.VALUE;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_PINNING;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
+import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT;
+import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;
import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode;
import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM;
+import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_PINNING_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_REVEAL_ANIM;
import android.animation.Animator;
@@ -47,6 +52,7 @@
import androidx.core.view.OneShotPreDrawListener;
import com.android.app.animation.Interpolators;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
@@ -61,11 +67,13 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.views.IconButtonView;
import java.io.PrintWriter;
import java.util.function.Predicate;
@@ -98,12 +106,27 @@
this::updateTranslationY);
private final AnimatedFloat mTaskbarIconTranslationYForStash = new AnimatedFloat(
this::updateTranslationY);
+
+ private final AnimatedFloat mTaskbarIconScaleForPinning = new AnimatedFloat(
+ this::updateTaskbarIconsScale);
+
+ private final AnimatedFloat mTaskbarIconTranslationXForPinning = new AnimatedFloat(
+ this::updateTaskbarIconTranslationXForPinning);
+
+ private final AnimatedFloat mTaskbarIconTranslationYForPinning = new AnimatedFloat(
+ this::updateTranslationY);
+
+ private final View.OnLayoutChangeListener mTaskbarViewLayoutChangeListener =
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
+ -> updateTaskbarIconTranslationXForPinning();
+
+
private AnimatedFloat mTaskbarNavButtonTranslationY;
private AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay;
private float mTaskbarIconTranslationYForSwipe;
private float mTaskbarIconTranslationYForSpringOnStash;
- private final int mTaskbarBottomMargin;
+ private int mTaskbarBottomMargin;
private final int mStashedHandleHeight;
private final int mLauncherThemedIconsBackgroundColor;
private final int mTaskbarThemedIconsBackgroundColor;
@@ -131,8 +154,18 @@
private final boolean mIsRtl;
+ private final DeviceProfile mTransientTaskbarDp;
+ private final DeviceProfile mPersistentTaskbarDp;
+
+ private final int mTransientIconSize;
+ private final int mPersistentIconSize;
+
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
mActivity = activity;
+ mTransientTaskbarDp = mActivity.getTransientTaskbarDeviceProfile();
+ mPersistentTaskbarDp = mActivity.getPersistentTaskbarDeviceProfile();
+ mTransientIconSize = mTransientTaskbarDp.taskbarIconSize;
+ mPersistentIconSize = mPersistentTaskbarDp.taskbarIconSize;
mTaskbarView = taskbarView;
mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, NUM_ALPHA_CHANNELS);
mTaskbarIconAlpha.setUpdateVisibility(true);
@@ -162,6 +195,12 @@
: mActivity.getDeviceProfile().taskbarHeight;
mTaskbarIconScaleForStash.updateValue(1f);
+ float pinningValue = DisplayController.isTransientTaskbar(mActivity)
+ ? PINNING_TRANSIENT
+ : PINNING_PERSISTENT;
+ mTaskbarIconScaleForPinning.updateValue(pinningValue);
+ mTaskbarIconTranslationYForPinning.updateValue(pinningValue);
+ mTaskbarIconTranslationXForPinning.updateValue(pinningValue);
mModelCallbacks.init(controllers);
if (mActivity.isUserSetupComplete()) {
@@ -181,6 +220,9 @@
mTaskbarIconAlpha.get(ALPHA_INDEX_SMALL_SCREEN)
.animateToValue(isPhoneButtonNavMode(mActivity) ? 0 : 1).start();
}
+ if (ENABLE_TASKBAR_PINNING.get()) {
+ mTaskbarView.addOnLayoutChangeListener(mTaskbarViewLayoutChangeListener);
+ }
}
/**
@@ -191,6 +233,9 @@
}
public void onDestroy() {
+ if (ENABLE_TASKBAR_PINNING.get()) {
+ mTaskbarView.removeOnLayoutChangeListener(mTaskbarViewLayoutChangeListener);
+ }
LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks);
mActivity.removeOnDeviceProfileChangeListener(mDeviceProfileChangeListener);
mModelCallbacks.unregisterListeners();
@@ -253,6 +298,18 @@
return mTaskbarIconTranslationYForStash;
}
+ public AnimatedFloat getTaskbarIconScaleForPinning() {
+ return mTaskbarIconScaleForPinning;
+ }
+
+ public AnimatedFloat getTaskbarIconTranslationXForPinning() {
+ return mTaskbarIconTranslationXForPinning;
+ }
+
+ public AnimatedFloat getTaskbarIconTranslationYForPinning() {
+ return mTaskbarIconTranslationYForPinning;
+ }
+
/**
* Applies scale properties for the entire TaskbarView (rather than individual icons).
*/
@@ -263,6 +320,76 @@
}
/**
+ * Applies scale properties for the taskbar icons
+ */
+ private void updateTaskbarIconsScale() {
+ float scale = mTaskbarIconScaleForPinning.value;
+ View[] iconViews = mTaskbarView.getIconViews();
+
+ float finalScale;
+ if (mControllers.getSharedState().startTaskbarVariantIsTransient) {
+ finalScale = mapRange(scale, 1f, ((float) mPersistentIconSize / mTransientIconSize));
+ } else {
+ finalScale = mapRange(scale, ((float) mTransientIconSize / mPersistentIconSize), 1f);
+ }
+
+ for (int iconIndex = 0; iconIndex < iconViews.length; iconIndex++) {
+ iconViews[iconIndex].setScaleX(finalScale);
+ iconViews[iconIndex].setScaleY(finalScale);
+ }
+ }
+
+ /**
+ * Animate away taskbar icon notification dots during the taskbar pinning animation.
+ */
+ public void animateAwayNotificationDotsDuringTaskbarPinningAnimation() {
+ for (View iconView : mTaskbarView.getIconViews()) {
+ if (iconView instanceof BubbleTextView && ((BubbleTextView) iconView).hasDot()) {
+ ((BubbleTextView) iconView).animateDotScale(0);
+ }
+ }
+ }
+
+ private void updateTaskbarIconTranslationXForPinning() {
+ View[] iconViews = mTaskbarView.getIconViews();
+ float scale = mTaskbarIconTranslationXForPinning.value;
+ float taskbarCenterX =
+ mTaskbarView.getLeft() + (mTaskbarView.getRight() - mTaskbarView.getLeft()) / 2.0f;
+
+ float finalMarginScale = mapRange(scale, 0f, mTransientIconSize - mPersistentIconSize);
+
+ float transientTaskbarAllAppsOffset = mActivity.getResources().getDimension(
+ mTaskbarView.getAllAppsButtonTranslationXOffset(true));
+ float persistentTaskbarAllAppsOffset = mActivity.getResources().getDimension(
+ mTaskbarView.getAllAppsButtonTranslationXOffset(false));
+
+ float allAppIconTranslateRange = mapRange(scale, transientTaskbarAllAppsOffset,
+ persistentTaskbarAllAppsOffset);
+
+ float halfIconCount = iconViews.length / 2.0f;
+ for (int iconIndex = 0; iconIndex < iconViews.length; iconIndex++) {
+ View iconView = iconViews[iconIndex];
+ MultiTranslateDelegate translateDelegate =
+ ((Reorderable) iconView).getTranslateDelegate();
+ float iconCenterX =
+ iconView.getLeft() + (iconView.getRight() - iconView.getLeft()) / 2.0f;
+ if (iconCenterX <= taskbarCenterX) {
+ translateDelegate.getTranslationX(INDEX_TASKBAR_PINNING_ANIM).setValue(
+ finalMarginScale * (halfIconCount - iconIndex));
+ } else {
+ translateDelegate.getTranslationX(INDEX_TASKBAR_PINNING_ANIM).setValue(
+ -finalMarginScale * (iconIndex - halfIconCount));
+ }
+
+ if (iconView.equals(mTaskbarView.getAllAppsButtonView()) && iconViews.length > 1) {
+ ((IconButtonView) iconView).setTranslationXForTaskbarAllAppsIcon(
+ allAppIconTranslateRange);
+ }
+ }
+ }
+
+
+ /**
* Sets the translation of the TaskbarView during the swipe up gesture.
*/
public void setTranslationYForSwipe(float transY) {
@@ -282,10 +409,41 @@
mTaskbarView.setTranslationY(mTaskbarIconTranslationYForHome.value
+ mTaskbarIconTranslationYForStash.value
+ mTaskbarIconTranslationYForSwipe
+ + getTaskbarIconTranslationYForPinningValue()
+ mTaskbarIconTranslationYForSpringOnStash);
}
/**
+ * Computes translation y for taskbar pinning.
+ */
+ private float getTaskbarIconTranslationYForPinningValue() {
+ if (mControllers.getSharedState() == null) return 0f;
+
+ float scale = mTaskbarIconTranslationYForPinning.value;
+ float taskbarIconTranslationYForPinningValue;
+
+ // transY is calculated here by adding/subtracting the taskbar bottom margin
+ // aligning the icon bound to be at bottom of current taskbar view and then
+ // finally placing the icon in the middle of new taskbar background height.
+ if (mControllers.getSharedState().startTaskbarVariantIsTransient) {
+ float transY =
+ mTransientTaskbarDp.taskbarBottomMargin + (mTransientTaskbarDp.taskbarHeight
+ - mTaskbarView.getIconLayoutBounds().bottom)
+ - (mPersistentTaskbarDp.taskbarHeight
+ - mTransientTaskbarDp.taskbarIconSize) / 2f;
+ taskbarIconTranslationYForPinningValue = mapRange(scale, 0f, transY);
+ } else {
+ float transY =
+ -mTransientTaskbarDp.taskbarBottomMargin + (mPersistentTaskbarDp.taskbarHeight
+ - mTaskbarView.getIconLayoutBounds().bottom)
+ - (mTransientTaskbarDp.taskbarHeight
+ - mTransientTaskbarDp.taskbarIconSize) / 2f;
+ taskbarIconTranslationYForPinningValue = mapRange(scale, transY, 0f);
+ }
+ return taskbarIconTranslationYForPinningValue;
+ }
+
+ /**
* Updates the Taskbar's themed icons background according to the progress between in-app/home.
*/
protected void updateIconsBackground() {
@@ -435,6 +593,11 @@
* 1 => fully aligned
*/
public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) {
+ if (isPhoneMode(launcherDp)) {
+ mIconAlignControllerLazy = null;
+ return;
+ }
+
boolean isHotseatIconOnTopWhenAligned =
mControllers.uiController.isHotseatIconOnTopWhenAligned();
boolean isStashed = mControllers.taskbarStashController.isStashed();
@@ -453,19 +616,21 @@
}
}
+ /** Resets the icon alignment controller so that it can be recreated again later. */
+ void resetIconAlignmentController() {
+ mIconAlignControllerLazy = null;
+ }
+
/**
* Creates an animation for aligning the Taskbar icons with the provided Launcher device profile
*/
private AnimatorPlaybackController createIconAlignmentController(DeviceProfile launcherDp) {
PendingAnimation setter = new PendingAnimation(100);
- if (TaskbarManager.isPhoneButtonNavMode(mActivity)) {
- // No animation for icons in small-screen
- return setter.createPlaybackController();
- }
-
mOnControllerPreCreateCallback.run();
DeviceProfile taskbarDp = mActivity.getDeviceProfile();
Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(mActivity);
+ boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivity);
+
float scaleUp = ((float) launcherDp.iconSizePx) / taskbarDp.taskbarIconSize;
int borderSpacing = launcherDp.hotseatBorderSpace;
int hotseatCellSize = DeviceProfile.calculateCellWidth(
@@ -492,6 +657,10 @@
setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight(
anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));
+ mTaskbarBottomMargin = isTransientTaskbar
+ ? mTransientTaskbarDp.taskbarBottomMargin
+ : mPersistentTaskbarDp.taskbarBottomMargin;
+
for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
View child = mTaskbarView.getChildAt(i);
boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonView();
@@ -502,7 +671,7 @@
// to avoid icons disappearing rather than fading out visually.
setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0.8f, 1f));
} else if ((isAllAppsButton && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get())
- || (isTaskbarDividerView && FeatureFlags.ENABLE_TASKBAR_PINNING.get())) {
+ || (isTaskbarDividerView && ENABLE_TASKBAR_PINNING.get())) {
if (!isToHome
&& mIsHotseatIconOnTopWhenAligned
&& mIsStashed) {
@@ -523,6 +692,8 @@
+ launcherDp.hotseatQsbWidth / 2f
: hotseatPadding.left - borderSpacing - launcherDp.hotseatQsbWidth / 2f;
float childCenter = (child.getLeft() + child.getRight()) / 2f;
+ childCenter += ((Reorderable) child).getTranslateDelegate().getTranslationX(
+ INDEX_TASKBAR_PINNING_ANIM).getValue();
float halfQsbIconWidthDiff =
(launcherDp.hotseatQsbWidth - taskbarDp.taskbarIconSize) / 2f;
float scale = ((float) taskbarDp.taskbarIconSize)
@@ -555,13 +726,19 @@
continue;
}
- int positionInHotseat;
+ float positionInHotseat;
if (isAllAppsButton) {
- // Note that there is no All Apps button in the hotseat, this position is only used
- // as its convenient for animation purposes.
+ // Note that there is no All Apps button in the hotseat,
+ // this position is only used as its convenient for animation purposes.
positionInHotseat = Utilities.isRtl(child.getResources())
? taskbarDp.numShownHotseatIcons
: -1;
+ } else if (isTaskbarDividerView) {
+ // Note that there is no taskbar divider view in the hotseat,
+ // this position is only used as its convenient for animation purposes.
+ positionInHotseat = Utilities.isRtl(child.getResources())
+ ? taskbarDp.numShownHotseatIcons - 0.5f
+ : -0.5f;
} else if (child.getTag() instanceof ItemInfo) {
positionInHotseat = ((ItemInfo) child.getTag()).screenId;
} else {
@@ -569,14 +746,24 @@
continue;
}
- float hotseatIconCenter = hotseatPadding.left
- + (hotseatCellSize + borderSpacing) * positionInHotseat
- + hotseatCellSize / 2f;
+ float hotseatAdjustedBorderSpace =
+ launcherDp.getHotseatAdjustedBorderSpaceForBubbleBar(child.getContext());
+ float hotseatIconCenter;
+ if (bubbleBarHasBubbles() && hotseatAdjustedBorderSpace != 0) {
+ hotseatIconCenter = hotseatPadding.left + hotseatCellSize
+ + (hotseatCellSize + hotseatAdjustedBorderSpace) * positionInHotseat
+ + hotseatCellSize / 2f;
+ } else {
+ hotseatIconCenter = hotseatPadding.left
+ + (hotseatCellSize + borderSpacing) * positionInHotseat
+ + hotseatCellSize / 2f;
+ }
float childCenter = (child.getLeft() + child.getRight()) / 2f;
+ childCenter += ((Reorderable) child).getTranslateDelegate().getTranslationX(
+ INDEX_TASKBAR_PINNING_ANIM).getValue();
float toX = hotseatIconCenter - childCenter;
if (child instanceof Reorderable) {
MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
-
setter.setFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
MULTI_PROPERTY_VALUE, toX, interpolator);
setter.setFloat(mtd.getTranslationY(INDEX_TASKBAR_ALIGNMENT_ANIM),
@@ -593,6 +780,11 @@
return controller;
}
+ private boolean bubbleBarHasBubbles() {
+ return mControllers.bubbleControllers.isPresent()
+ && mControllers.bubbleControllers.get().bubbleBarViewController.hasBubbles();
+ }
+
public void onRotationChanged(DeviceProfile deviceProfile) {
if (!mControllers.uiController.isIconAlignedWithHotseat()) {
// We only translate on rotation when icon is aligned with hotseat
@@ -742,5 +934,13 @@
public void notifyIconLayoutBoundsChanged() {
mControllers.uiController.onIconLayoutBoundsChanged();
}
+
+ /**
+ * Notifies the taskbar scrim when the visibility of taskbar changes.
+ */
+ public void notifyVisibilityChanged() {
+ mControllers.taskbarScrimViewController.onTaskbarVisibilityChanged(
+ mTaskbarView.getVisibility());
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
index d786d94..07d86e4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
@@ -89,7 +89,8 @@
mAppsModelFlags = flags;
mPackageUserKeytoUidMap = map;
if (mAppsView != null) {
- mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags, mPackageUserKeytoUidMap);
+ mAppsView.getAppsStore().setApps(
+ mApps, mAppsModelFlags, mPackageUserKeytoUidMap, false);
}
}
@@ -128,10 +129,19 @@
/** Toggles visibility of {@link TaskbarAllAppsContainerView} in the overlay window. */
public void toggle() {
+ toggle(false);
+ }
+
+ /** Toggles visibility of {@link TaskbarAllAppsContainerView} with the keyboard for search. */
+ public void toggleSearch() {
+ toggle(true);
+ }
+
+ private void toggle(boolean showKeyboard) {
if (isOpen()) {
mSlideInView.close(true);
} else {
- show(true);
+ show(true, showKeyboard);
}
}
@@ -141,13 +151,13 @@
}
private void show(boolean animate) {
+ show(animate, false);
+ }
+
+ private void show(boolean animate, boolean showKeyboard) {
if (mAppsView != null) {
return;
}
- // mControllers and getSharedState should never be null here. Do not handle null-pointer
- // to catch invalid states.
- mControllers.getSharedState().allAppsVisible = true;
-
mOverlayContext = mControllers.taskbarOverlayController.requestWindow();
// Initialize search session for All Apps.
@@ -161,16 +171,20 @@
mSlideInView = (TaskbarAllAppsSlideInView) mOverlayContext.getLayoutInflater().inflate(
R.layout.taskbar_all_apps_sheet, mOverlayContext.getDragLayer(), false);
- mSlideInView.addOnCloseListener(() -> {
- mControllers.getSharedState().allAppsVisible = false;
- cleanUpOverlay();
- });
+ // Ensures All Apps gets touch events in case it is not the top floating view. Floating
+ // views above it may not be able to intercept the touch, so All Apps should try to.
+ mOverlayContext.getDragLayer().addTouchController(mSlideInView);
+ mSlideInView.addOnCloseListener(this::cleanUpOverlay);
TaskbarAllAppsViewController viewController = new TaskbarAllAppsViewController(
- mOverlayContext, mSlideInView, mControllers, mSearchSessionController);
+ mOverlayContext,
+ mSlideInView,
+ mControllers,
+ mSearchSessionController,
+ showKeyboard);
viewController.show(animate);
mAppsView = mOverlayContext.getAppsView();
- mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags, mPackageUserKeytoUidMap);
+ mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags, mPackageUserKeytoUidMap, false);
mAppsView.getFloatingHeaderView()
.findFixedRowByType(PredictionRowView.class)
.setPredictedApps(mPredictedApps);
@@ -195,6 +209,7 @@
mSearchSessionController = null;
}
if (mOverlayContext != null) {
+ mOverlayContext.getDragLayer().removeTouchController(mSlideInView);
mOverlayContext.setSearchSessionController(null);
mOverlayContext = null;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 001c3bc..5ce2a7a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -220,7 +220,9 @@
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mNoIntercept = !mAppsView.shouldContainerScroll(ev);
+ mNoIntercept = !mAppsView.shouldContainerScroll(ev)
+ || getTopOpenViewWithType(
+ mActivityContext, TYPE_ACCESSIBLE & ~TYPE_TASKBAR_OVERLAYS) != null;
}
return super.onControllerInterceptTouchEvent(ev);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
index 85633e9..b1c5151 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
@@ -18,17 +18,22 @@
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS;
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.allapps.AllAppsTransitionListener;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.appprediction.AppsDividerView;
import com.android.launcher3.taskbar.NavbarButtonsViewController;
import com.android.launcher3.taskbar.TaskbarControllers;
+import com.android.launcher3.taskbar.TaskbarSharedState;
import com.android.launcher3.taskbar.TaskbarStashController;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayController;
import com.android.launcher3.util.DisplayController;
+import java.util.Optional;
+
/**
* Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
* taskbar stashing.
@@ -41,12 +46,15 @@
private final TaskbarStashController mTaskbarStashController;
private final NavbarButtonsViewController mNavbarButtonsViewController;
private final TaskbarOverlayController mOverlayController;
+ private final @Nullable TaskbarSharedState mTaskbarSharedState;
+ private final boolean mShowKeyboard;
TaskbarAllAppsViewController(
TaskbarOverlayContext context,
TaskbarAllAppsSlideInView slideInView,
TaskbarControllers taskbarControllers,
- TaskbarSearchSessionController searchSessionController) {
+ TaskbarSearchSessionController searchSessionController,
+ boolean showKeyboard) {
mContext = context;
mSlideInView = slideInView;
@@ -54,6 +62,8 @@
mTaskbarStashController = taskbarControllers.taskbarStashController;
mNavbarButtonsViewController = taskbarControllers.navbarButtonsViewController;
mOverlayController = taskbarControllers.taskbarOverlayController;
+ mTaskbarSharedState = taskbarControllers.getSharedState();
+ mShowKeyboard = showKeyboard;
mSlideInView.init(new TaskbarAllAppsCallbacks(searchSessionController));
setUpAppDivider();
@@ -73,26 +83,27 @@
private void setUpAppDivider() {
mAppsView.getFloatingHeaderView()
.findFixedRowByType(AppsDividerView.class)
- .setShowAllAppsLabel(!mContext.getOnboardingPrefs().hasReachedMaxCount(
- ALL_APPS_VISITED_COUNT));
- mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
+ .setShowAllAppsLabel(!ALL_APPS_VISITED_COUNT.hasReachedMax(mContext));
+ ALL_APPS_VISITED_COUNT.increment(mContext);
}
private void setUpTaskbarStashing() {
if (DisplayController.isTransientTaskbar(mContext)) {
mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true);
- mTaskbarStashController.applyState(mOverlayController.getOpenDuration());
+ mTaskbarStashController.applyState();
}
+ Optional.ofNullable(mTaskbarSharedState).ifPresent(s -> s.allAppsVisible = true);
mNavbarButtonsViewController.setSlideInViewVisible(true);
mSlideInView.setOnCloseBeginListener(() -> {
+ Optional.ofNullable(mTaskbarSharedState).ifPresent(s -> s.allAppsVisible = false);
mNavbarButtonsViewController.setSlideInViewVisible(false);
AbstractFloatingView.closeOpenContainer(
mContext, AbstractFloatingView.TYPE_ACTION_POPUP);
if (DisplayController.isTransientTaskbar(mContext)) {
mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
- mTaskbarStashController.applyState(mOverlayController.getCloseDuration());
+ mTaskbarStashController.applyState();
}
});
}
@@ -120,6 +131,11 @@
@Override
public void onAllAppsTransitionEnd(boolean toAllApps) {
mSearchSessionController.onAllAppsTransitionEnd(toAllApps);
+ if (toAllApps
+ && mShowKeyboard
+ && mAppsView.getSearchUiManager().getEditText() != null) {
+ mAppsView.getSearchUiManager().getEditText().requestFocus();
+ }
}
/** Invoked on back press, returning {@code true} if the search session handled it. */
@@ -128,7 +144,7 @@
}
void onAllAppsAnimationPending(PendingAnimation animation, boolean toAllApps) {
- mSearchSessionController.onAllAppsAnimationPending(animation, toAllApps);
+ mSearchSessionController.onAllAppsAnimationPending(animation, toAllApps, mShowKeyboard);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
index 8a2041f..3d15fbd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarSearchSessionController.kt
@@ -51,7 +51,11 @@
open fun handleBackInvoked(): Boolean = false
- open fun onAllAppsAnimationPending(animation: PendingAnimation, toAllApps: Boolean) = Unit
+ open fun onAllAppsAnimationPending(
+ animation: PendingAnimation,
+ toAllApps: Boolean,
+ showKeyboard: Boolean,
+ ) = Unit
companion object {
@JvmStatic
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 24db380..3fb7247 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -85,17 +85,31 @@
* information to render each of the bubbles & dispatches changes to
* {@link BubbleBarViewController} which will then update {@link BubbleBarView} as needed.
*
- * For details around the behavior of the bubble bar, see {@link BubbleBarView}.
+ * <p>For details around the behavior of the bubble bar, see {@link BubbleBarView}.
*/
public class BubbleBarController extends IBubblesListener.Stub {
private static final String TAG = BubbleBarController.class.getSimpleName();
private static final boolean DEBUG = false;
- // Whether bubbles are showing in the bubble bar from launcher
- public static final boolean BUBBLE_BAR_ENABLED =
+ /**
+ * Determines whether bubbles can be shown in the bubble bar. This value updates when the
+ * taskbar is recreated.
+ *
+ * @see #onTaskbarRecreated()
+ */
+ private static boolean sBubbleBarEnabled =
SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
+ /** Whether showing bubbles in the launcher bubble bar is enabled. */
+ public static boolean isBubbleBarEnabled() {
+ return sBubbleBarEnabled;
+ }
+
+ /** Re-reads the value of the flag from SystemProperties when taskbar is recreated. */
+ public static void onTaskbarRecreated() {
+ sBubbleBarEnabled = SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
+ }
private static final int MASK_HIDE_BUBBLE_BAR = SYSUI_STATE_BOUNCER_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
@@ -137,6 +151,7 @@
private static class BubbleBarViewUpdate {
boolean expandedChanged;
boolean expanded;
+ boolean shouldShowEducation;
String selectedBubbleKey;
String suppressedBubbleKey;
String unsuppressedBubbleKey;
@@ -151,6 +166,7 @@
BubbleBarViewUpdate(BubbleBarUpdate update) {
expandedChanged = update.expandedChanged;
expanded = update.expanded;
+ shouldShowEducation = update.shouldShowEducation;
selectedBubbleKey = update.selectedBubbleKey;
suppressedBubbleKey = update.suppressedBubbleKey;
unsuppressedBubbleKey = update.unsupressedBubbleKey;
@@ -165,7 +181,7 @@
mSystemUiProxy = SystemUiProxy.INSTANCE.get(context);
- if (BUBBLE_BAR_ENABLED) {
+ if (sBubbleBarEnabled) {
mSystemUiProxy.setBubblesListener(this);
}
mMainExecutor = MAIN_EXECUTOR;
@@ -188,8 +204,10 @@
mBubbleStashedHandleViewController = bubbleControllers.bubbleStashedHandleViewController;
bubbleControllers.runAfterInit(() -> {
- mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
- mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
+ mBubbleBarViewController.setHiddenForBubbles(
+ !sBubbleBarEnabled || mBubbles.isEmpty());
+ mBubbleStashedHandleViewController.setHiddenForBubbles(
+ !sBubbleBarEnabled || mBubbles.isEmpty());
mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse(
key -> setSelectedBubble(mBubbles.get(key)));
});
@@ -366,7 +384,9 @@
mBubbleStashController.animateToInitialState(update.expanded);
}
}
-
+ if (update.shouldShowEducation) {
+ mBubbleBarViewController.prepareToShowEducation();
+ }
if (update.expandedChanged) {
if (update.expanded != mBubbleBarViewController.isExpanded()) {
mBubbleBarViewController.setExpandedFromSysui(update.expanded);
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 20b8e3b..065dd58 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -18,6 +18,7 @@
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
@@ -74,7 +75,8 @@
// Whether the bar is hidden for a sysui state.
private boolean mHiddenForSysui;
// Whether the bar is hidden because there are no bubbles.
- private boolean mHiddenForNoBubbles;
+ private boolean mHiddenForNoBubbles = true;
+ private boolean mShouldShowEducation;
public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) {
mActivity = activity;
@@ -98,7 +100,7 @@
mBarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarHeight;
mBubbleBarScale.updateValue(1f);
mBubbleClickListener = v -> onBubbleClicked(v);
- mBubbleBarClickListener = v -> setExpanded(true);
+ mBubbleBarClickListener = v -> onBubbleBarClicked();
mBubbleDragController.setupBubbleBarView(mBarView);
mBarView.setOnClickListener(mBubbleBarClickListener);
mBarView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) ->
@@ -121,6 +123,21 @@
}
}
+ private void onBubbleBarClicked() {
+ if (mShouldShowEducation) {
+ mShouldShowEducation = false;
+ // Get the bubble bar bounds on screen
+ Rect bounds = new Rect();
+ mBarView.getBoundsOnScreen(bounds);
+ // Calculate user education reference position in Screen coordinates
+ Point position = new Point(bounds.centerX(), bounds.top);
+ // Show user education relative to the reference point
+ mSystemUiProxy.showUserEducation(position);
+ } else {
+ setExpanded(true);
+ }
+ }
+
//
// The below animators are exposed to BubbleStashController so it can manage the stashing
// animation.
@@ -195,6 +212,7 @@
if (mHiddenForNoBubbles != hidden) {
mHiddenForNoBubbles = hidden;
updateVisibilityForStateChange();
+ mActivity.bubbleBarVisibilityChanged(!hidden);
}
}
@@ -326,6 +344,12 @@
}
}
+ /** Marks as should show education and shows the bubble bar in a collapsed state */
+ public void prepareToShowEducation() {
+ mShouldShowEducation = true;
+ mBubbleStashController.showBubbleBar(false /* expand the bubbles */);
+ }
+
/**
* Updates the dragged bubble view in the bubble bar view, and notifies SystemUI
* that a bubble is being dragged to dismiss.
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
index 4b235a9..6c3f0d8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
@@ -30,6 +30,7 @@
fun DismissView.setup() {
setup(
DismissView.Config(
+ dismissViewResId = R.id.dismiss_view,
targetSizeResId = R.dimen.bubblebar_dismiss_target_size,
iconSizeResId = R.dimen.bubblebar_dismiss_target_icon_size,
bottomMarginResId = R.dimen.bubblebar_dismiss_target_bottom_margin,
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
index a5ea5a9..09021ed 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
@@ -22,6 +22,7 @@
import android.animation.AnimatorSet;
import android.annotation.Nullable;
import android.view.InsetsController;
+import android.view.MotionEvent;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.taskbar.StashedHandleViewController;
@@ -350,4 +351,9 @@
return mBubblesShowingOnHome ? getBubbleBarTranslationYForHotseat()
: getBubbleBarTranslationYForTaskbar();
}
+
+ /** Checks whether the motion event is over the stash handle. */
+ public boolean isEventOverStashHandle(MotionEvent ev) {
+ return mHandleViewController.isEventOverHandle(ev);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index fbab595..c998d97 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -24,6 +24,7 @@
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -268,4 +269,22 @@
});
return revealAnim;
}
+
+ /** Checks that the stash handle is visible and that the motion event is within bounds. */
+ public boolean isEventOverHandle(MotionEvent ev) {
+ if (mStashedHandleView.getVisibility() != VISIBLE) {
+ return false;
+ }
+
+ // the bounds of the handle only include the visible part, so we check that the Y coordinate
+ // is anywhere within the stashed taskbar height.
+ int top = mActivity.getDeviceProfile().heightPx - mStashedTaskbarHeight;
+
+ return (int) ev.getRawY() >= top && containsX((int) ev.getRawX());
+ }
+
+ /** Checks if the given x coordinate is within the stashed handle bounds. */
+ public boolean containsX(int x) {
+ return x >= mStashedHandleBounds.left && x <= mStashedHandleBounds.right;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
index b682081..b516d6f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
@@ -18,12 +18,15 @@
import android.content.res.Resources
import android.graphics.drawable.RotateDrawable
+import android.view.Gravity
import android.view.ViewGroup
+import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter
+import com.android.systemui.shared.rotation.RotationButton
/**
* Meant to be a simple container for data subclasses will need
@@ -37,10 +40,13 @@
* @property startContextualContainer ViewGroup that holds the start contextual button (ex, A11y).
*/
abstract class AbstractNavButtonLayoutter(
- val resources: Resources,
- val navButtonContainer: LinearLayout,
- protected val endContextualContainer: ViewGroup,
- protected val startContextualContainer: ViewGroup
+ val resources: Resources,
+ val navButtonContainer: LinearLayout,
+ protected val endContextualContainer: ViewGroup,
+ protected val startContextualContainer: ViewGroup,
+ protected val imeSwitcher: ImageView?,
+ protected val rotationButton: RotationButton?,
+ protected val a11yButton: ImageView?
) : NavButtonLayoutter {
protected val homeButton: ImageView? = navButtonContainer.findViewById(R.id.home)
protected val recentsButton: ImageView? = navButtonContainer.findViewById(R.id.recent_apps)
@@ -56,4 +62,25 @@
backButton.setImageDrawable(rotateDrawable)
}
}
+
+ fun getParamsToCenterView(): FrameLayout.LayoutParams {
+ val params = FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ params.gravity = Gravity.CENTER
+ return params;
+ }
+
+ open fun repositionContextualContainer(contextualContainer: ViewGroup, barAxisMargin: Int,
+ gravity: Int) {
+ val contextualContainerParams = FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ contextualContainerParams.apply {
+ marginStart = barAxisMargin
+ marginEnd = barAxisMargin
+ topMargin = 0
+ bottomMargin = 0
+ }
+ contextualContainerParams.gravity = gravity or Gravity.CENTER_VERTICAL
+ contextualContainer.layoutParams = contextualContainerParams
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
index 4a53c0c..3f51958 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt
@@ -25,22 +25,30 @@
import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.R
import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.*
+import com.android.systemui.shared.rotation.RotationButton
class KidsNavLayoutter(
- resources: Resources,
- navBarContainer: LinearLayout,
- endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ resources: Resources,
+ navBarContainer: LinearLayout,
+ endContextualContainer: ViewGroup,
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?
) :
AbstractNavButtonLayoutter(
- resources,
- navBarContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navBarContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
val iconSize: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_ICON_SIZE_KIDS)
val buttonWidth: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS)
val buttonHeight: Int =
@@ -89,5 +97,25 @@
navButtonContainer.requestLayout()
homeButton.onLongClickListener = null
+
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
+
+ if (imeSwitcher != null) {
+ startContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ endContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ endContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
index 931f692..6b05e9a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
@@ -21,11 +21,13 @@
import android.view.Surface.Rotation
import android.view.ViewGroup
import android.widget.FrameLayout
+import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.*
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.Companion
import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter
+import com.android.systemui.shared.rotation.RotationButton
/**
* Select the correct layout for nav buttons
@@ -52,14 +54,17 @@
* @param isThreeButtonNav are no-ops when taskbar is present/showing
*/
fun getUiLayoutter(
- deviceProfile: DeviceProfile,
- navButtonsView: FrameLayout,
- resources: Resources,
- isKidsMode: Boolean,
- isInSetup: Boolean,
- isThreeButtonNav: Boolean,
- phoneMode: Boolean,
- @Rotation surfaceRotation: Int
+ deviceProfile: DeviceProfile,
+ navButtonsView: FrameLayout,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?,
+ resources: Resources,
+ isKidsMode: Boolean,
+ isInSetup: Boolean,
+ isThreeButtonNav: Boolean,
+ phoneMode: Boolean,
+ @Rotation surfaceRotation: Int
): NavButtonLayoutter {
val navButtonContainer =
navButtonsView.requireViewById<LinearLayout>(ID_END_NAV_BUTTONS)
@@ -73,24 +78,33 @@
isPhoneNavMode -> {
if (!deviceProfile.isLandscape) {
PhonePortraitNavLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
} else if (surfaceRotation == ROTATION_90) {
PhoneLandscapeNavLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
} else {
PhoneSeascapeNavLayoutter(
resources,
navButtonContainer,
endContextualContainer,
- startContextualContainer
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
}
}
@@ -99,33 +113,45 @@
resources,
navButtonContainer,
endContextualContainer,
- startContextualContainer
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
}
deviceProfile.isTaskbarPresent -> {
return when {
isInSetup -> {
SetupNavLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
}
isKidsMode -> {
KidsNavLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
}
else ->
TaskbarNavLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
)
}
}
@@ -136,6 +162,6 @@
/** Lays out and provides access to the home, recents, and back buttons for various mischief */
interface NavButtonLayoutter {
- fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean)
+ fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
index 8525c6c..5a7bc49 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt
@@ -18,24 +18,33 @@
import android.content.res.Resources
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.systemui.shared.rotation.RotationButton
/** Layoutter for showing gesture navigation on phone screen. No buttons here, no-op container */
class PhoneGestureLayoutter(
resources: Resources,
navBarContainer: LinearLayout,
endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?
) :
AbstractNavButtonLayoutter(
resources,
navBarContainer,
endContextualContainer,
- startContextualContainer
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
- // no-op
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
index 2acd5d4..382e298 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
@@ -20,27 +20,35 @@
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
+import android.widget.ImageView
import android.widget.LinearLayout
import androidx.core.view.children
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.util.DimensionUtils
+import com.android.systemui.shared.rotation.RotationButton
open class PhoneLandscapeNavLayoutter(
- resources: Resources,
- navBarContainer: LinearLayout,
- endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ resources: Resources,
+ navBarContainer: LinearLayout,
+ endContextualContainer: ViewGroup,
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?,
) :
AbstractNavButtonLayoutter(
- resources,
- navBarContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navBarContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// TODO(b/230395757): Polish pending, this is just to make it usable
val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
@@ -57,14 +65,11 @@
marginStart = 0
}
- // Swap recents and back button
- navButtonContainer.addView(recentsButton)
- navButtonContainer.addView(homeButton)
- navButtonContainer.addView(backButton)
-
navButtonContainer.layoutParams = navContainerParams
navButtonContainer.gravity = Gravity.CENTER
+ addThreeButtons()
+
// Add the spaces in between the nav buttons
val spaceInBetween: Int =
resources.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone)
@@ -84,5 +89,49 @@
}
}
}
+
+ repositionContextualButtons()
+ }
+
+ open fun addThreeButtons() {
+ // Swap recents and back button
+ navButtonContainer.addView(recentsButton)
+ navButtonContainer.addView(homeButton)
+ navButtonContainer.addView(backButton)
+ }
+
+ open fun repositionContextualButtons() {
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.TOP)
+
+ if (imeSwitcher != null) {
+ startContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ startContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ startContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
+ }
+
+ override fun repositionContextualContainer(contextualContainer: ViewGroup, barAxisMargin: Int,
+ gravity: Int) {
+ val contextualContainerParams = FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ contextualContainerParams.apply {
+ marginStart = 0
+ marginEnd = 0
+ topMargin = barAxisMargin
+ bottomMargin = barAxisMargin
+ }
+ contextualContainerParams.gravity = gravity or Gravity.CENTER_HORIZONTAL
+ contextualContainer.layoutParams = contextualContainerParams
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
index c763115..e1ffa4d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
@@ -20,26 +20,34 @@
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
+import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.util.DimensionUtils
+import com.android.systemui.shared.rotation.RotationButton
class PhonePortraitNavLayoutter(
- resources: Resources,
- navBarContainer: LinearLayout,
- endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ resources: Resources,
+ navBarContainer: LinearLayout,
+ endContextualContainer: ViewGroup,
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?,
) :
AbstractNavButtonLayoutter(
- resources,
- navBarContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navBarContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// TODO(b/230395757): Polish pending, this is just to make it usable
val taskbarDimensions =
DimensionUtils.getTaskbarPhoneDimensions(dp, resources,
@@ -90,5 +98,24 @@
}
}
}
+
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, contextualMargin, Gravity.END)
+
+ if (imeSwitcher != null) {
+ endContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ endContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ endContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
index f0fe581..0368b1d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
@@ -17,30 +17,57 @@
package com.android.launcher3.taskbar.navbutton
import android.content.res.Resources
+import android.view.Gravity
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.LinearLayout
-import com.android.launcher3.DeviceProfile
+import com.android.launcher3.R
+import com.android.systemui.shared.rotation.RotationButton
class PhoneSeascapeNavLayoutter(
resources: Resources,
navBarContainer: LinearLayout,
endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?
) :
PhoneLandscapeNavLayoutter(
resources,
navBarContainer,
endContextualContainer,
- startContextualContainer
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
- // TODO(b/230395757): Polish pending, this is just to make it usable
- super.layoutButtons(dp, isContextualButtonShowing)
- navButtonContainer.removeAllViews()
+ override fun addThreeButtons() {
// Flip ordering of back and recents buttons
navButtonContainer.addView(backButton)
navButtonContainer.addView(homeButton)
navButtonContainer.addView(recentsButton)
}
+
+ override fun repositionContextualButtons() {
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, contextualMargin, Gravity.BOTTOM)
+
+ if (imeSwitcher != null) {
+ endContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ endContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ endContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
index a24002c..abdd32c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
@@ -20,23 +20,32 @@
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
+import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.R
+import com.android.systemui.shared.rotation.RotationButton
class SetupNavLayoutter(
- resources: Resources,
- navButtonContainer: LinearLayout,
- endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ resources: Resources,
+ navButtonContainer: LinearLayout,
+ endContextualContainer: ViewGroup,
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?
) :
AbstractNavButtonLayoutter(
- resources,
- navButtonContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navButtonContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// Since setup wizard only has back button enabled, it looks strange to be
// end-aligned, so start-align instead.
val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams
@@ -46,5 +55,25 @@
gravity = Gravity.START
}
navButtonContainer.requestLayout()
+
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
+
+ if (imeSwitcher != null) {
+ startContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ endContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ endContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
index 8332b7d..f5a4c64 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
@@ -20,31 +20,41 @@
import android.view.Gravity
import android.view.ViewGroup
import android.widget.FrameLayout
+import android.widget.ImageView
import android.widget.LinearLayout
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
+import com.android.systemui.shared.rotation.RotationButton
-/** Layoutter for showing 3 button navigation on large screen */
+/**
+ * Layoutter for rendering task bar in large screen, both in 3-button and gesture nav mode.
+ */
class TaskbarNavLayoutter(
- resources: Resources,
- navBarContainer: LinearLayout,
- endContextualContainer: ViewGroup,
- startContextualContainer: ViewGroup
+ resources: Resources,
+ navBarContainer: LinearLayout,
+ endContextualContainer: ViewGroup,
+ startContextualContainer: ViewGroup,
+ imeSwitcher: ImageView?,
+ rotationButton: RotationButton?,
+ a11yButton: ImageView?
) :
AbstractNavButtonLayoutter(
- resources,
- navBarContainer,
- endContextualContainer,
- startContextualContainer
+ resources,
+ navBarContainer,
+ endContextualContainer,
+ startContextualContainer,
+ imeSwitcher,
+ rotationButton,
+ a11yButton
) {
- override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) {
+ override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) {
// Add spacing after the end of the last nav button
var navMarginEnd = resources.getDimension(dp.inv.inlineNavButtonsEndSpacing).toInt()
val contextualWidth = endContextualContainer.width
// If contextual buttons are showing, we check if the end margin is enough for the
// contextual button to be showing - if not, move the nav buttons over a smidge
- if (isContextualButtonShowing && navMarginEnd < contextualWidth) {
+ if (isA11yButtonPersistent && navMarginEnd < contextualWidth) {
// Additional spacing, eat up half of space between last icon and nav button
navMarginEnd += resources.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2
}
@@ -77,5 +87,27 @@
}
}
}
+
+ endContextualContainer.removeAllViews()
+ startContextualContainer.removeAllViews()
+
+ if (!dp.isGestureMode) {
+ val contextualMargin = resources.getDimensionPixelSize(
+ R.dimen.taskbar_contextual_button_padding)
+ repositionContextualContainer(endContextualContainer, 0, Gravity.END)
+ repositionContextualContainer(startContextualContainer, contextualMargin, Gravity.START)
+
+ if (imeSwitcher != null) {
+ startContextualContainer.addView(imeSwitcher)
+ imeSwitcher.layoutParams = getParamsToCenterView()
+ }
+ if (a11yButton != null) {
+ endContextualContainer.addView(a11yButton)
+ }
+ if (rotationButton != null) {
+ endContextualContainer.addView(rotationButton.currentView)
+ rotationButton.currentView.layoutParams = getParamsToCenterView()
+ }
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index d4e2be9..c4eeea7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import android.annotation.SuppressLint;
-import android.content.ComponentName;
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
@@ -60,14 +59,26 @@
private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
@Override
- public void onTaskCreated(int taskId, ComponentName componentName) {
- // Created task will be below existing overlay, so move out of the way.
- hideWindow();
+ public void onTaskMovedToFront(int taskId) {
+ // New front task will be below existing overlay, so move out of the way.
+ hideWindowOnTaskStackChange();
}
@Override
- public void onTaskMovedToFront(int taskId) {
- // New front task will be below existing overlay, so move out of the way.
+ public void onTaskStackChanged() {
+ // The other callbacks are insufficient for All Apps, because there are many cases where
+ // it can relaunch the same task already behind it. However, this callback needs to be a
+ // no-op when only EDU is shown, because going between the EDU steps invokes this
+ // callback.
+ if (mControllers.getSharedState() != null
+ && mControllers.getSharedState().allAppsVisible) {
+ hideWindowOnTaskStackChange();
+ }
+ }
+
+ private void hideWindowOnTaskStackChange() {
+ // A task was launched while overlay window was open, so stash Taskbar.
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
hideWindow();
}
};
@@ -199,8 +210,10 @@
@Override
protected void handleClose(boolean animate) {
- mTaskbarContext.getDragLayer().removeView(this);
- Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate));
+ if (mIsOpen) {
+ mTaskbarContext.getDragLayer().removeView(this);
+ Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate));
+ }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index ff00560..e742a3d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -38,6 +38,7 @@
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -69,6 +70,7 @@
return true;
}
};
+ private final List<TouchController> mTouchControllers = new ArrayList<>();
TaskbarOverlayDragLayer(Context context) {
super(context, null, 1);
@@ -93,10 +95,13 @@
@Override
public void recreateControllers() {
- mControllers = mOnClickListeners.isEmpty()
- ? new TouchController[]{mActivity.getDragController()}
- : new TouchController[] {
- mActivity.getDragController(), mClickListenerTouchController};
+ List<TouchController> controllers = new ArrayList<>();
+ controllers.add(mActivity.getDragController());
+ controllers.addAll(mTouchControllers);
+ if (!mOnClickListeners.isEmpty()) {
+ controllers.add(mClickListenerTouchController);
+ }
+ mControllers = controllers.toArray(new TouchController[0]);
}
@Override
@@ -183,6 +188,18 @@
});
}
+ /** Adds a {@link TouchController} to this drag layer. */
+ public void addTouchController(@NonNull TouchController touchController) {
+ mTouchControllers.add(touchController);
+ recreateControllers();
+ }
+
+ /** Removes a {@link TouchController} from this drag layer. */
+ public void removeTouchController(@NonNull TouchController touchController) {
+ mTouchControllers.remove(touchController);
+ recreateControllers();
+ }
+
/**
* Taskbar automatically stashes when opening all apps, but we don't report the insets as
* changing to avoid moving the underlying app. But internally, the apps view should still
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index 475f465..4a26559 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -21,12 +21,20 @@
import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
+import android.content.pm.LauncherUserInfo;
import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.ColorDrawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArrayMap;
import android.window.RemoteTransition;
+import com.android.launcher3.Flags;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.UserIconInfo;
import com.android.quickstep.util.FadeOutRemoteTransition;
+import java.util.List;
import java.util.Map;
/**
@@ -53,4 +61,56 @@
options.setRemoteTransition(new RemoteTransition(new FadeOutRemoteTransition()));
return options;
}
+
+ /**
+ * Returns a map of all users on the device to their corresponding UI properties
+ */
+ public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
+ UserManager um = context.getSystemService(UserManager.class);
+ Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
+ List<UserHandle> usersActual = um.getUserProfiles();
+ if (usersActual != null) {
+ for (UserHandle user : usersActual) {
+ if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
+ LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
+ LauncherUserInfo launcherUserInfo = launcherApps.getLauncherUserInfo(user);
+ // UserTypes not supported in Launcher are deemed to be the current
+ // Foreground User.
+ int userType = switch (launcherUserInfo.getUserType()) {
+ case UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK;
+ case UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED;
+ case UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE;
+ default -> UserIconInfo.TYPE_MAIN;
+ };
+ long serial = launcherUserInfo.getUserSerialNumber();
+ users.put(user, new UserIconInfo(user, userType, serial));
+ } else {
+ long serial = um.getSerialNumberForUser(user);
+
+ // Simple check to check if the provided user is work profile
+ // TODO: Migrate to a better platform API
+ NoopDrawable d = new NoopDrawable();
+ boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
+ UserIconInfo info = new UserIconInfo(
+ user,
+ isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
+ serial);
+ users.put(user, info);
+ }
+ }
+ }
+ return users;
+ }
+
+ private static class NoopDrawable extends ColorDrawable {
+ @Override
+ public int getIntrinsicHeight() {
+ return 1;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 1;
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index d78ca88..e2f4f32 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -107,8 +107,7 @@
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
- boolean exitingOverview = !FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()
- && !toState.overviewUi;
+ boolean exitingOverview = !FeatureFlags.enableSplitContextually() && !toState.overviewUi;
if (mRecentsView.isSplitSelectionActive() && exitingOverview) {
setter.add(mRecentsView.getSplitSelectController().getSplitAnimationController()
.createPlaceholderDismissAnim(mLauncher));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 5a46b8d..22ab79d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -19,7 +19,6 @@
import static android.os.Trace.TRACE_TAG_APP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
-
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON;
import static com.android.launcher3.LauncherSettings.Animation.VIEW_BACKGROUND;
@@ -33,6 +32,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_HOME_TRANSITION_LISTENER;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
@@ -50,9 +50,10 @@
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -61,7 +62,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
@@ -93,6 +93,7 @@
import com.android.app.viewcapture.SettingsAwareViewCapture;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.HomeTransitionController;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherState;
@@ -106,6 +107,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
@@ -163,7 +165,6 @@
import com.android.quickstep.util.SplitToWorkspaceController;
import com.android.quickstep.util.SplitWithKeyboardShortcutController;
import com.android.quickstep.util.TISBindHelper;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
@@ -185,6 +186,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -217,29 +219,40 @@
private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController;
private SplitToWorkspaceController mSplitToWorkspaceController;
- private AsyncClockEventDelegate mAsyncClockEventDelegate;
-
/**
* If Launcher restarted while in the middle of an Overview split select, it needs this data to
* recover. In all other cases this will remain null.
*/
private PendingSplitSelectInfo mPendingSplitSelectInfo = null;
+ @Nullable
+ private DesktopRecentsTransitionController mDesktopRecentsTransitionController;
+
private SafeCloseable mViewCapture;
private boolean mEnableWidgetDepth;
+ private HomeTransitionController mHomeTransitionController;
+
@Override
protected void setupViews() {
super.setupViews();
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = getOverviewPanel();
+ SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
mSplitSelectStateController =
new SplitSelectStateController(this, mHandler, getStateManager(),
getDepthController(), getStatsLogManager(),
- SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this));
- overviewPanel.init(mActionsView, mSplitSelectStateController);
+ systemUiProxy, RecentsModel.INSTANCE.get(this),
+ () -> onStateBack());
+ if (isDesktopModeSupported()) {
+ mDesktopRecentsTransitionController = new DesktopRecentsTransitionController(
+ getStateManager(), systemUiProxy, getIApplicationThread(),
+ getDepthController());
+ }
+ overviewPanel.init(mActionsView, mSplitSelectStateController,
+ mDesktopRecentsTransitionController);
mSplitWithKeyboardShortcutController = new SplitWithKeyboardShortcutController(this,
mSplitSelectStateController);
mSplitToWorkspaceController = new SplitToWorkspaceController(this,
@@ -251,10 +264,15 @@
mAppTransitionManager.registerRemoteAnimations();
mAppTransitionManager.registerRemoteTransitions();
+ if (FeatureFlags.enableHomeTransitionListener()) {
+ mHomeTransitionController = new HomeTransitionController(this);
+ mHomeTransitionController.registerHomeTransitionListener();
+ }
+
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
mDepthController = new DepthController(this);
mDesktopVisibilityController = new DesktopVisibilityController(this);
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
mDesktopVisibilityController.registerSystemUiListener();
mSplitSelectStateController.initSplitFromDesktopController(this);
}
@@ -263,6 +281,7 @@
mEnableWidgetDepth = SystemProperties.getBoolean("ro.launcher.depth.widget", true);
getWorkspace().addOverlayCallback(progress ->
onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX));
+ addBackAnimationCallback(mSplitSelectStateController.getSplitBackHandler());
}
@Override
@@ -332,11 +351,6 @@
}
@Override
- protected QuickstepOnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
- return new QuickstepOnboardingPrefs(this, sharedPrefs);
- }
-
- @Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onStateOrResumeChanging(false /* inTransition */);
@@ -362,8 +376,8 @@
}
if ((changeBits & ACTIVITY_STATE_RESUMED) != 0) {
- if (mTaskbarUIController != null) {
- mTaskbarUIController.onLauncherResumedOrPaused(hasBeenResumed());
+ if (!FeatureFlags.enableHomeTransitionListener() && mTaskbarUIController != null) {
+ mTaskbarUIController.onLauncherVisibilityChanged(hasBeenResumed());
}
}
@@ -476,6 +490,10 @@
mLauncherUnfoldAnimationController.onDestroy();
}
+ if (mHomeTransitionController != null) {
+ mHomeTransitionController.unregisterHomeTransitionListener();
+ }
+
if (mDesktopVisibilityController != null) {
mDesktopVisibilityController.unregisterSystemUiListener();
}
@@ -484,14 +502,11 @@
mSplitSelectStateController.onDestroy();
}
- if (mAsyncClockEventDelegate != null) {
- mAsyncClockEventDelegate.onDestroy();
- }
-
super.onDestroy();
mHotseatPredictionController.destroy();
mSplitWithKeyboardShortcutController.onDestroy();
if (mViewCapture != null) mViewCapture.close();
+ removeBackAnimationCallback(mSplitSelectStateController.getSplitBackHandler());
}
@Override
@@ -610,6 +625,7 @@
mViewCapture = SettingsAwareViewCapture.getInstance(this).startCapture(getWindow());
}
getWindow().addPrivateFlags(PRIVATE_FLAG_OPTIMIZE_MEASURE);
+ QuickstepOnboardingPrefs.setup(this);
View.setTraceLayoutSteps(TRACE_LAYOUTS);
View.setTracedRequestLayoutClassClass(TRACE_RELAYOUT_CLASS);
}
@@ -627,7 +643,7 @@
splitSelectSource.alreadyRunningTaskId = taskWasFound
? foundTask.key.id
: INVALID_TASK_ID;
- if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
startSplitToHome(splitSelectSource);
} else {
recentsView.initiateSplitSelect(splitSelectSource);
@@ -661,6 +677,9 @@
floatingTaskView.setAlpha(1);
floatingTaskView.addStagingAnimation(anim, startingTaskRect, tempRect,
false /* fadeWithThumbnail */, true /* isStagedTask */);
+ floatingTaskView.setOnClickListener(view ->
+ mSplitSelectStateController.getSplitAnimationController().
+ playAnimPlaceholderToFullscreen(this, view, Optional.empty()));
mSplitSelectStateController.setFirstFloatingTaskView(floatingTaskView);
anim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -676,6 +695,10 @@
anim.buildAnim().start();
}
+ @Override
+ public boolean isSplitSelectionEnabled() {
+ return mSplitSelectStateController.isSplitSelectActive();
+ }
@Override
protected void onResume() {
@@ -693,6 +716,15 @@
}
super.onPause();
+
+ if (FeatureFlags.enableSplitContextually()) {
+ // If Launcher pauses before both split apps are selected, exit split screen.
+ if (!mSplitSelectStateController.isBothSplitAppsConfirmed() &&
+ !mSplitSelectStateController.isLaunchingFirstAppFullscreen()) {
+ mSplitSelectStateController.getSplitAnimationController()
+ .playPlaceholderDismissAnim(this);
+ }
+ }
}
@Override
@@ -739,15 +771,6 @@
}
@Override
- protected void onScreenOnChanged(boolean isOn) {
- super.onScreenOnChanged(isOn);
- if (!isOn) {
- RecentsView recentsView = getOverviewPanel();
- recentsView.finishRecentsAnimation(true /* toRecents */, null);
- }
- }
-
- @Override
public void onAllAppsTransition(float progress) {
super.onAllAppsTransition(progress);
onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
@@ -866,7 +889,7 @@
@Override
public void setResumed() {
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
DesktopVisibilityController controller = mDesktopVisibilityController;
if (controller != null && controller.areFreeformTasksVisible()
&& !controller.isRecentsGestureInProgress()) {
@@ -971,6 +994,13 @@
.playPlaceholderDismissAnim(this);
}
+ @Override
+ public void dismissSplitSelection() {
+ super.dismissSplitSelection();
+ mSplitSelectStateController.getSplitAnimationController()
+ .playPlaceholderDismissAnim(this);
+ }
+
public <T extends OverviewActionsView> T getActionsView() {
return (T) mActionsView;
}
@@ -1003,7 +1033,7 @@
@Override
public boolean supportsAdaptiveIconAnimation(View clickedView) {
- return mAppTransitionManager.hasControlRemoteAppTransitionPermission();
+ return true;
}
@Override
@@ -1038,10 +1068,7 @@
@Override
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- ActivityOptionsWrapper activityOptions =
- mAppTransitionManager.hasControlRemoteAppTransitionPermission()
- ? mAppTransitionManager.getActivityLaunchOptions(v)
- : super.getActivityLaunchOptions(v, item);
+ ActivityOptionsWrapper activityOptions = mAppTransitionManager.getActivityLaunchOptions(v);
if (mLastTouchUpTime > 0) {
activityOptions.options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_LAUNCHER,
mLastTouchUpTime);
@@ -1156,11 +1183,6 @@
}
@Override
- public void tryClearAccessibilityFocus(View view) {
- view.clearAccessibilityFocus();
- }
-
- @Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -1254,10 +1276,8 @@
/* callback= */ success -> mSplitSelectStateController.resetState(),
/* freezeTaskList= */ true,
groupTask.mSplitBounds == null
- ? DEFAULT_SPLIT_RATIO
- : groupTask.mSplitBounds.appsStackedVertically
- ? groupTask.mSplitBounds.topTaskPercent
- : groupTask.mSplitBounds.leftTaskPercent);
+ ? SNAP_TO_50_50
+ : groupTask.mSplitBounds.snapPosition);
}
/**
@@ -1272,6 +1292,16 @@
return overviewCommandHelper == null || overviewCommandHelper.canStartHomeSafely();
}
+ @Override
+ public boolean isBubbleBarEnabled() {
+ return (mTaskbarUIController != null && mTaskbarUIController.isBubbleBarEnabled());
+ }
+
+ @Override
+ public boolean hasBubbles() {
+ return (mTaskbarUIController != null && mTaskbarUIController.hasBubbles());
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {
@@ -1321,18 +1351,12 @@
switch (name) {
case "TextClock", "android.widget.TextClock" -> {
TextClock tc = new TextClock(context, attrs);
- if (mAsyncClockEventDelegate == null) {
- mAsyncClockEventDelegate = new AsyncClockEventDelegate(this);
- }
- tc.setClockEventDelegate(mAsyncClockEventDelegate);
+ tc.setClockEventDelegate(AsyncClockEventDelegate.INSTANCE.get(this));
return tc;
}
case "AnalogClock", "android.widget.AnalogClock" -> {
AnalogClock ac = new AnalogClock(context, attrs);
- if (mAsyncClockEventDelegate == null) {
- mAsyncClockEventDelegate = new AsyncClockEventDelegate(this);
- }
- ac.setClockEventDelegate(mAsyncClockEventDelegate);
+ ac.setClockEventDelegate(AsyncClockEventDelegate.INSTANCE.get(this));
return ac;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
index f7bef03..f66bc60 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@@ -37,6 +37,7 @@
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.LauncherWidgetHolder;
+import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
import java.util.Collections;
@@ -237,6 +238,14 @@
@Override
public LauncherAppWidgetHostView createView(@NonNull Context context, int appWidgetId,
@NonNull LauncherAppWidgetProviderInfo appWidget) {
+
+ if (appWidget.isCustomWidget()) {
+ LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context);
+ lahv.setAppWidget(appWidgetId, appWidget);
+ CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv);
+ return lahv;
+ }
+
LauncherAppWidgetHostView widgetView = getPendingView(appWidgetId);
if (widgetView != null) {
removePendingView(appWidgetId);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
similarity index 67%
rename from quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
rename to quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index a76eb43..36d62c6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -15,20 +15,28 @@
*/
package com.android.launcher3.uioverrides.flags;
-import static android.content.Intent.ACTION_PACKAGE_ADDED;
-import static android.content.Intent.ACTION_PACKAGE_CHANGED;
-import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
+import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
+import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_LONGPRESS_TIP_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP;
-import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -36,23 +44,17 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
import android.provider.Settings;
import android.text.Editable;
-import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.ArrayMap;
import android.util.Pair;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceDataStore;
@@ -63,17 +65,15 @@
import androidx.preference.SeekBarPreference;
import androidx.preference.SwitchPreference;
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.OnboardingPrefs;
-import com.android.launcher3.util.SimpleBroadcastReceiver;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -81,40 +81,39 @@
* Dev-build only UI allowing developers to toggle flag settings and plugins.
* See {@link FeatureFlags}.
*/
-@TargetApi(Build.VERSION_CODES.O)
-public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
+public class DeveloperOptionsUI {
- private static final String ACTION_PLUGIN_SETTINGS = "com.android.systemui.action.PLUGIN_SETTINGS";
+ private static final String ACTION_PLUGIN_SETTINGS =
+ "com.android.systemui.action.PLUGIN_SETTINGS";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
- private final SimpleBroadcastReceiver mPluginReceiver =
- new SimpleBroadcastReceiver(i -> loadPluginPrefs());
-
- private PreferenceScreen mPreferenceScreen;
+ private final PreferenceFragmentCompat mFragment;
+ private final PreferenceScreen mPreferenceScreen;
private PreferenceCategory mPluginsCategory;
- private FlagTogglerPrefUi mFlagTogglerPrefUi;
- @Override
- public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- mPluginReceiver.registerPkgActions(getContext(), null,
- ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REMOVED);
- mPluginReceiver.register(getContext(), Intent.ACTION_USER_UNLOCKED);
+ public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
+ mFragment = fragment;
+ mPreferenceScreen = fragment.getPreferenceScreen();
- mPreferenceScreen = getPreferenceManager().createPreferenceScreen(getContext());
- setPreferenceScreen(mPreferenceScreen);
+ // Add search bar
+ View listView = mFragment.getListView();
+ ViewGroup parent = (ViewGroup) listView.getParent();
+ View topBar = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.developer_options_top_bar, parent, false);
+ parent.addView(topBar, parent.indexOfChild(listView));
+ initSearch(topBar.findViewById(R.id.filter_box));
- initFlags();
+ new FlagTogglerPrefUi(mFragment.requireActivity(), topBar.findViewById(R.id.flag_apply_btn))
+ .applyTo(flags);
+
loadPluginPrefs();
maybeAddSandboxCategory();
addOnboardingPrefsCatergory();
if (FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) {
addAllAppsFromOverviewCatergory();
}
-
- if (getActivity() != null) {
- getActivity().setTitle("Developer Options");
- }
+ addCustomLpnhCategory();
}
private void filterPreferences(String query, PreferenceGroup pg) {
@@ -137,21 +136,13 @@
pg.setVisible(hidden != count);
}
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- EditText filterBox = view.findViewById(R.id.filter_box);
- filterBox.setVisibility(VISIBLE);
+ private void initSearch(EditText filterBox) {
filterBox.addTextChangedListener(new TextWatcher() {
@Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
@Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-
- }
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { }
@Override
public void afterTextChanged(Editable editable) {
@@ -160,85 +151,33 @@
}
});
- if (getArguments() != null) {
- String filter = getArguments().getString(EXTRA_FRAGMENT_ARG_KEY);
+ if (mFragment.getArguments() != null) {
+ String filter = mFragment.getArguments().getString(EXTRA_FRAGMENT_HIGHLIGHT_KEY);
// Normally EXTRA_FRAGMENT_ARG_KEY is used to highlight the preference with the given
// key. This is a slight variation where we instead filter by the human-readable titles.
if (filter != null) {
filterBox.setText(filter);
}
}
-
- View listView = getListView();
- final int bottomPadding = listView.getPaddingBottom();
- listView.setOnApplyWindowInsetsListener((v, insets) -> {
- v.setPadding(
- v.getPaddingLeft(),
- v.getPaddingTop(),
- v.getPaddingRight(),
- bottomPadding + insets.getSystemWindowInsetBottom());
- return insets.consumeSystemWindowInsets();
- });
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mPluginReceiver.unregisterReceiverSafely(getContext());
}
private PreferenceCategory newCategory(String title) {
- return newCategory(title, null);
- }
-
- private PreferenceCategory newCategory(String title, @Nullable String summary) {
PreferenceCategory category = new PreferenceCategory(getContext());
category.setOrder(Preference.DEFAULT_ORDER);
category.setTitle(title);
- if (!TextUtils.isEmpty(summary)) {
- category.setSummary(summary);
- }
mPreferenceScreen.addPreference(category);
return category;
}
- private void initFlags() {
- if (!FeatureFlags.showFlagTogglerUi(getContext())) {
- return;
- }
-
- mFlagTogglerPrefUi = new FlagTogglerPrefUi(this);
- mFlagTogglerPrefUi.applyTo(newCategory("Feature flags", "Long press to reset"));
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- if (mFlagTogglerPrefUi != null) {
- mFlagTogglerPrefUi.onCreateOptionsMenu(menu);
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (mFlagTogglerPrefUi != null) {
- mFlagTogglerPrefUi.onOptionsItemSelected(item);
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onStop() {
- if (mFlagTogglerPrefUi != null) {
- mFlagTogglerPrefUi.onStop();
- }
- super.onStop();
+ private Context getContext() {
+ return mFragment.requireContext();
}
private void loadPluginPrefs() {
if (mPluginsCategory != null) {
mPreferenceScreen.removePreference(mPluginsCategory);
}
- if (!PluginManagerWrapper.hasPlugins(getActivity())) {
+ if (!PluginManagerWrapper.hasPlugins(getContext())) {
mPluginsCategory = null;
return;
}
@@ -311,118 +250,151 @@
launchTutorialStepMenuPreference.setKey("launchTutorialStepMenu");
launchTutorialStepMenuPreference.setTitle("Launch Gesture Tutorial Steps menu");
launchTutorialStepMenuPreference.setSummary("Select a gesture tutorial step.");
- launchTutorialStepMenuPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent.putExtra("use_tutorial_menu", true));
- return true;
- });
+ launchTutorialStepMenuPreference.setIntent(
+ new Intent(launchSandboxIntent).putExtra("use_tutorial_menu", true));
+
sandboxCategory.addPreference(launchTutorialStepMenuPreference);
Preference launchOnboardingTutorialPreference = new Preference(context);
launchOnboardingTutorialPreference.setKey("launchOnboardingTutorial");
launchOnboardingTutorialPreference.setTitle("Launch Onboarding Tutorial");
launchOnboardingTutorialPreference.setSummary("Learn the basic navigation gestures.");
- launchOnboardingTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent
- .putExtra("use_tutorial_menu", false)
- .putExtra("tutorial_steps",
- new String[] {
- "HOME_NAVIGATION",
- "BACK_NAVIGATION",
- "OVERVIEW_NAVIGATION"}));
- return true;
- });
+ launchTutorialStepMenuPreference.setIntent(new Intent(launchSandboxIntent)
+ .putExtra("use_tutorial_menu", false)
+ .putExtra("tutorial_steps",
+ new String[] {
+ "HOME_NAVIGATION",
+ "BACK_NAVIGATION",
+ "OVERVIEW_NAVIGATION"}));
+
sandboxCategory.addPreference(launchOnboardingTutorialPreference);
Preference launchBackTutorialPreference = new Preference(context);
launchBackTutorialPreference.setKey("launchBackTutorial");
launchBackTutorialPreference.setTitle("Launch Back Tutorial");
launchBackTutorialPreference.setSummary("Learn how to use the Back gesture");
- launchBackTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent
+ launchBackTutorialPreference.setIntent(new Intent(launchSandboxIntent)
.putExtra("use_tutorial_menu", false)
.putExtra("tutorial_steps", new String[] {"BACK_NAVIGATION"}));
- return true;
- });
+
sandboxCategory.addPreference(launchBackTutorialPreference);
Preference launchHomeTutorialPreference = new Preference(context);
launchHomeTutorialPreference.setKey("launchHomeTutorial");
launchHomeTutorialPreference.setTitle("Launch Home Tutorial");
launchHomeTutorialPreference.setSummary("Learn how to use the Home gesture");
- launchHomeTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent
+ launchHomeTutorialPreference.setIntent(new Intent(launchSandboxIntent)
.putExtra("use_tutorial_menu", false)
.putExtra("tutorial_steps", new String[] {"HOME_NAVIGATION"}));
- return true;
- });
+
sandboxCategory.addPreference(launchHomeTutorialPreference);
Preference launchOverviewTutorialPreference = new Preference(context);
launchOverviewTutorialPreference.setKey("launchOverviewTutorial");
launchOverviewTutorialPreference.setTitle("Launch Overview Tutorial");
launchOverviewTutorialPreference.setSummary("Learn how to use the Overview gesture");
- launchOverviewTutorialPreference.setOnPreferenceClickListener(preference -> {
- startActivity(launchSandboxIntent
+ launchOverviewTutorialPreference.setIntent(new Intent(launchSandboxIntent)
.putExtra("use_tutorial_menu", false)
.putExtra("tutorial_steps", new String[] {"OVERVIEW_NAVIGATION"}));
- return true;
- });
+
sandboxCategory.addPreference(launchOverviewTutorialPreference);
Preference launchSecondaryDisplayPreference = new Preference(context);
launchSecondaryDisplayPreference.setKey("launchSecondaryDisplay");
launchSecondaryDisplayPreference.setTitle("Launch Secondary Display");
launchSecondaryDisplayPreference.setSummary("Launch secondary display activity");
- launchSecondaryDisplayPreference.setOnPreferenceClickListener(preference -> {
- startActivity(new Intent(context, SecondaryDisplayLauncher.class));
- return true;
- });
- sandboxCategory.addPreference(launchSecondaryDisplayPreference);
+ launchSecondaryDisplayPreference.setIntent(
+ new Intent(context, SecondaryDisplayLauncher.class));
+
}
private void addOnboardingPrefsCatergory() {
PreferenceCategory onboardingCategory = newCategory("Onboarding Flows");
onboardingCategory.setSummary("Reset these if you want to see the education again.");
- for (Map.Entry<String, String[]> titleAndKeys : OnboardingPrefs.ALL_PREF_KEYS.entrySet()) {
- String title = titleAndKeys.getKey();
- String[] keys = titleAndKeys.getValue();
- Preference onboardingPref = new Preference(getContext());
- onboardingPref.setTitle(title);
- onboardingPref.setSummary("Tap to reset");
- onboardingPref.setOnPreferenceClickListener(preference -> {
- SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
- .edit();
- for (String key : keys) {
- sharedPrefsEdit.remove(key);
- }
- sharedPrefsEdit.apply();
- Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
- return true;
- });
- onboardingCategory.addPreference(onboardingPref);
- }
+
+ onboardingCategory.addPreference(createOnboardPref("All Apps Bounce",
+ HOME_BOUNCE_SEEN.getSharedPrefKey(), HOME_BOUNCE_COUNT.getSharedPrefKey()));
+ onboardingCategory.addPreference(createOnboardPref("Hybrid Hotseat Education",
+ HOTSEAT_DISCOVERY_TIP_COUNT.getSharedPrefKey(),
+ HOTSEAT_LONGPRESS_TIP_SEEN.getSharedPrefKey()));
+ onboardingCategory.addPreference(createOnboardPref("Taskbar Education",
+ TASKBAR_EDU_TOOLTIP_STEP.getSharedPrefKey()));
+ onboardingCategory.addPreference(createOnboardPref("All Apps Visited Count",
+ ALL_APPS_VISITED_COUNT.getSharedPrefKey()));
+ }
+
+ private Preference createOnboardPref(String title, String... keys) {
+ Preference onboardingPref = new Preference(getContext());
+ onboardingPref.setTitle(title);
+ onboardingPref.setSummary("Tap to reset");
+ onboardingPref.setOnPreferenceClickListener(preference -> {
+ SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
+ .edit();
+ for (String key : keys) {
+ sharedPrefsEdit.remove(key);
+ }
+ sharedPrefsEdit.apply();
+ Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
+ return true;
+ });
+ return onboardingPref;
}
private void addAllAppsFromOverviewCatergory() {
PreferenceCategory category = newCategory("All Apps from Overview Config");
+ category.addPreference(createSeekBarPreference("Threshold to open All Apps from Overview",
+ 105, 500, 100, ALL_APPS_OVERVIEW_THRESHOLD));
+ }
- SeekBarPreference thresholdPref = new SeekBarPreference(getContext());
- thresholdPref.setTitle("Threshold to open All Apps from Overview");
- thresholdPref.setSingleLineTitle(false);
+ private void addCustomLpnhCategory() {
+ PreferenceCategory category = newCategory("Long Press Nav Handle Config");
+ if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
+ category.addPreference(createSeekBarPreference("Slop multiplier (applied to edge slop, "
+ + "which is generally already 50% higher than touch slop)",
+ 25, 200, 100, LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE));
+ category.addPreference(createSeekBarPreference("Trigger milliseconds",
+ 100, 500, 1, LONG_PRESS_NAV_HANDLE_TIMEOUT_MS));
+ }
+ if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
+ category.addPreference(createSeekBarPreference("Haptic hint start scale",
+ 0, 100, 100, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT));
+ category.addPreference(createSeekBarPreference("Haptic hint end scale",
+ 0, 100, 100, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT));
+ category.addPreference(createSeekBarPreference("Haptic hint scale exponent",
+ 1, 5, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT));
+ category.addPreference(createSeekBarPreference("Haptic hint iterations (12 ms each)",
+ 0, 100, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS));
+ }
+ }
- // These values are 100x swipe up shift value (100 = where overview sits).
- thresholdPref.setMax(500);
- thresholdPref.setMin(105);
- thresholdPref.setUpdatesContinuously(true);
- thresholdPref.setIconSpaceReserved(false);
+ /**
+ * Create a preference with text and a seek bar. Should be added to a PreferenceCategory.
+ *
+ * @param title text to show for this seek bar
+ * @param min min value for the seek bar
+ * @param max max value for the seek bar
+ * @param scale how much to divide the value to convert int to float
+ * @param launcherPref used to store the current value
+ */
+ private SeekBarPreference createSeekBarPreference(String title, int min, int max, int scale,
+ ConstantItem<Integer> launcherPref) {
+ SeekBarPreference seekBarPref = new SeekBarPreference(getContext());
+ seekBarPref.setTitle(title);
+ seekBarPref.setSingleLineTitle(false);
+
+ seekBarPref.setMax(max);
+ seekBarPref.setMin(min);
+ seekBarPref.setUpdatesContinuously(true);
+ seekBarPref.setIconSpaceReserved(false);
// Don't directly save to shared prefs, use LauncherPrefs instead.
- thresholdPref.setPersistent(false);
- thresholdPref.setOnPreferenceChangeListener((preference, newValue) -> {
- LauncherPrefs.get(getContext()).put(ALL_APPS_OVERVIEW_THRESHOLD, newValue);
- preference.setSummary(String.valueOf((int) newValue / 100f));
+ seekBarPref.setPersistent(false);
+ seekBarPref.setOnPreferenceChangeListener((preference, newValue) -> {
+ LauncherPrefs.get(getContext()).put(launcherPref, newValue);
+ preference.setSummary(String.valueOf(scale == 1 ? newValue
+ : (int) newValue / (float) scale));
return true;
});
- int value = LauncherPrefs.get(getContext()).get(ALL_APPS_OVERVIEW_THRESHOLD);
- thresholdPref.setValue(value);
+ int value = LauncherPrefs.get(getContext()).get(launcherPref);
+ seekBarPref.setValue(value);
// For some reason the initial value is not triggering the summary update, so call manually.
- thresholdPref.getOnPreferenceChangeListener().onPreferenceChange(thresholdPref, value);
-
- category.addPreference(thresholdPref);
+ seekBarPref.setSummary(String.valueOf(scale == 1 ? value
+ : value / (float) scale));
+ return seekBarPref;
}
private String toName(String action) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
index 87c836b..ec0566a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
@@ -19,24 +19,23 @@
import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.TEAMFOOD_FLAG;
+import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Process;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
+import android.view.View;
import android.widget.Toast;
import androidx.preference.PreferenceDataStore;
-import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
-import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import java.util.List;
import java.util.Set;
@@ -44,12 +43,13 @@
/**
* Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
*/
-public final class FlagTogglerPrefUi {
+public final class FlagTogglerPrefUi implements ActivityLifecycleCallbacksAdapter {
private static final String TAG = "FlagTogglerPrefFrag";
- private final PreferenceFragmentCompat mFragment;
+ private final View mFlagsApplyButton;
private final Context mContext;
+
private final PreferenceDataStore mDataStore = new PreferenceDataStore() {
@Override
@@ -64,9 +64,17 @@
}
};
- public FlagTogglerPrefUi(PreferenceFragmentCompat fragment) {
- mFragment = fragment;
- mContext = fragment.getActivity();
+ public FlagTogglerPrefUi(Activity activity, View flagsApplyButton) {
+ mFlagsApplyButton = flagsApplyButton;
+ mContext = mFlagsApplyButton.getContext();
+ activity.registerActivityLifecycleCallbacks(this);
+
+ mFlagsApplyButton.setOnClickListener(v -> {
+ FlagsFactory.getSharedPreferences().edit().commit();
+ Log.e(TAG,
+ "Killing launcher process " + Process.myPid() + " to apply new flag values");
+ System.exit(0);
+ });
}
public void applyTo(PreferenceGroup parent) {
@@ -137,27 +145,11 @@
}
private void updateMenu() {
- mFragment.setHasOptionsMenu(anyChanged());
- mFragment.getActivity().invalidateOptionsMenu();
+ mFlagsApplyButton.setVisibility(anyChanged() ? View.VISIBLE : View.INVISIBLE);
}
- public void onCreateOptionsMenu(Menu menu) {
- if (anyChanged()) {
- menu.add(0, R.id.menu_apply_flags, 0, "Apply")
- .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
- }
- }
-
- public void onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.menu_apply_flags) {
- FlagsFactory.getSharedPreferences().edit().commit();
- Log.e(TAG,
- "Killing launcher process " + Process.myPid() + " to apply new flag values");
- System.exit(0);
- }
- }
-
- public void onStop() {
+ @Override
+ public void onActivityStopped(Activity activity) {
if (anyChanged()) {
Toast.makeText(mContext, "Flag won't be applied until you restart launcher",
Toast.LENGTH_LONG).show();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 6279f63..28d4bf8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -57,6 +57,7 @@
public static final String NAMESPACE_LAUNCHER = "launcher";
private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
+ private static final List<IntFlag> sIntFlags = new ArrayList<>();
private static SharedPreferences sSharedPreferences;
static final BooleanFlag TEAMFOOD_FLAG = getReleaseFlag(
@@ -132,7 +133,14 @@
public static IntFlag getIntFlag(
int bugId, String key, int defaultValueInCode, String description) {
INSTANCE.mKeySet.add(key);
- return new IntFlag(DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode));
+ int defaultValue = DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode);
+ if (IS_DEBUG_DEVICE) {
+ IntDeviceFlag flag = new IntDeviceFlag(key, defaultValue, defaultValueInCode);
+ sIntFlags.add(flag);
+ return flag;
+ } else {
+ return new IntFlag(defaultValue);
+ }
}
static List<DebugFlag> getDebugFlags() {
@@ -163,13 +171,20 @@
return;
}
pw.println("DeviceFlags:");
+ pw.println(" BooleanFlags:");
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
if (flag instanceof DeviceFlag) {
- pw.println(" " + flag);
+ pw.println(" " + flag);
}
}
}
+ pw.println(" IntFlags:");
+ synchronized (sIntFlags) {
+ for (IntFlag flag : sIntFlags) {
+ pw.println(" " + flag);
+ }
+ }
pw.println("DebugFlags:");
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java
new file mode 100644
index 0000000..4f3b0ae
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides.flags;
+
+import com.android.launcher3.config.FeatureFlags.IntFlag;
+
+public class IntDeviceFlag extends IntFlag {
+ public final String key;
+ private final int mDefaultValueInCode;
+
+ public IntDeviceFlag(String key, int currentValue, int defaultValueInCode) {
+ super(currentValue);
+ this.key = key;
+ mDefaultValueInCode = defaultValueInCode;
+ }
+
+ @Override
+ public String toString() {
+ return key + ": mCurrentValue=" + get() + ", defaultValueInCode=" + mDefaultValueInCode;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index ed0a0d5..3767cce 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -121,13 +121,13 @@
@Override
public int getFloatingSearchBarRestingMarginStart(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
- return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin();
+ return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(launcher);
}
@Override
public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
- return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin();
+ return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(launcher);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index e578720..d11a08b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.content.Context;
import android.graphics.Color;
@@ -26,7 +27,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.quickstep.util.LayoutUtils;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
/**
@@ -90,7 +90,7 @@
@Override
protected float getDepthUnchecked(Context context) {
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
if (Launcher.getLauncher(context).areFreeformTasksVisible()) {
// Don't blur the background while freeform tasks are visible
return 0;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index b9221ee..1d55da3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -21,9 +21,9 @@
import android.graphics.Rect;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.Flags;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.config.FeatureFlags;
import com.android.quickstep.views.RecentsView;
/**
@@ -72,7 +72,7 @@
@Override
public boolean isTaskbarStashed(Launcher launcher) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (Flags.enableGridOnlyOverview()) {
return true;
}
return super.isTaskbarStashed(launcher);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 7392469..ba44d6a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -16,6 +16,7 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.graphics.Color;
@@ -23,7 +24,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
-import com.android.quickstep.views.DesktopTaskView;
/**
* State to indicate we are about to launch a recent task. Note that this state is only used when
@@ -46,7 +46,7 @@
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
if (launcher.areFreeformTasksVisible()) {
// No scrim while freeform tasks are visible
return Color.TRANSPARENT;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 6651c73..e7b285a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -55,14 +55,12 @@
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import android.animation.ValueAnimator;
-import android.util.Log;
import com.android.launcher3.CellLayout;
import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
@@ -96,8 +94,6 @@
@Override
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
StateAnimationConfig config) {
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "creating animation fromState: "
- + fromState + " toState: " + toState);
RecentsView overview = mActivity.getOverviewPanel();
if ((fromState == OVERVIEW || fromState == OVERVIEW_SPLIT_SELECT) && toState == NORMAL) {
overview.switchToScreenshot(() ->
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index b266bcd..f6cd30a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -195,7 +195,7 @@
() -> recentsView.finishRecentsAnimation(true /* toRecents */, null));
if (mStartState.overviewUi) {
new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(mEndState),
- FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()
+ FeatureFlags.enableSplitContextually()
? mCancelSplitRunnable
: null)
.animateWithVelocity(velocity);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 6f421eb..968faf0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -16,7 +16,6 @@
package com.android.launcher3.uioverrides.touchcontrollers;
import static android.view.MotionEvent.ACTION_DOWN;
-
import static com.android.app.animation.Interpolators.ACCELERATE_0_75;
import static com.android.app.animation.Interpolators.DECELERATE_3;
import static com.android.app.animation.Interpolators.LINEAR;
@@ -49,6 +48,7 @@
import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
@@ -83,7 +83,6 @@
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.WorkspaceRevealAnim;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.LauncherRecentsView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -177,7 +176,7 @@
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
return false;
}
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
// TODO(b/268075592): add support for quickswitch to/from desktop
return false;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 9a35bb2..ff142fe 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -30,6 +30,7 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
@@ -48,7 +49,6 @@
import com.android.launcher3.util.NavigationMode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -79,7 +79,7 @@
if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) {
return false;
}
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
// TODO(b/268075592): add support for quickswitch to/from desktop
return false;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 1ef4039..b06a978 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -20,10 +20,11 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.widget.Toast.LENGTH_SHORT;
-
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
import static com.android.app.animation.Interpolators.DECELERATE;
import static com.android.app.animation.Interpolators.OVERSHOOT_1_2;
+import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
+import static com.android.launcher3.BaseActivity.EVENT_STARTED;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
@@ -51,8 +52,10 @@
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.INVALID_VELOCITY_ON_SWIPE_UP;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.LAUNCHER_DESTROYED;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -61,7 +64,6 @@
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.app.ActivityManager;
import android.app.TaskInfo;
import android.app.WindowConfiguration;
@@ -88,6 +90,7 @@
import android.widget.Toast;
import android.window.PictureInPictureSurfaceTransaction;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -108,7 +111,6 @@
import com.android.launcher3.taskbar.TaskbarThresholdUtils;
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.TraceHelper;
@@ -131,7 +133,6 @@
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.SwipePipToHomeAnimator;
import com.android.quickstep.util.TaskViewSimulator;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
@@ -183,19 +184,13 @@
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
private boolean mRecentsViewScrollLinked = false;
- private final ActivityLifecycleCallbacksAdapter mLifecycleCallbacks =
- new ActivityLifecycleCallbacksAdapter() {
- @Override
- public void onActivityDestroyed(Activity activity) {
- if (mActivity != activity) {
- return;
- }
- ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
- mRecentsView = null;
- mActivity = null;
- mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
- }
- };
+
+ private final Runnable mLauncherOnDestroyCallback = () -> {
+ ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
+ mRecentsView = null;
+ mActivity = null;
+ mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
+ };
private static int FLAG_COUNT = 0;
private static int getNextStateFlag(String name) {
@@ -316,8 +311,9 @@
private final int mSplashMainWindowShiftLength;
private final Runnable mOnDeferredActivityLaunch = this::onDeferredActivityLaunch;
+ private final Runnable mLauncherOnStartCallback = this::onLauncherStart;
- private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
+ @Nullable private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
protected boolean mIsSwipingPipToHome;
// TODO(b/195473090) no split PIP for now, remove once we have more clarity
// can try to have RectFSpringAnim evaluate multiple rects at once
@@ -489,6 +485,7 @@
mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED);
return true;
}
+ resetLauncherListeners();
// The launcher may have been recreated as a result of device rotation.
int oldState = mStateCallback.getState() & ~LAUNCHER_UI_STATES;
@@ -512,7 +509,7 @@
if (alreadyOnHome) {
onLauncherStart();
} else {
- activity.runOnceOnStart(this::onLauncherStart);
+ activity.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
}
// Set up a entire animation lifecycle callback to notify the current recents view when
@@ -537,9 +534,8 @@
setupRecentsViewUi();
mRecentsView.runOnPageScrollsInitialized(this::linkRecentsViewScroll);
- activity.runOnBindToTouchInteractionService(this::onLauncherBindToService);
-
- mActivity.registerActivityLifecycleCallbacks(mLifecycleCallbacks);
+ mActivity.runOnBindToTouchInteractionService(this::onLauncherBindToService);
+ mActivity.addEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
return true;
}
@@ -676,6 +672,9 @@
if (Arrays.stream(runningTasks).anyMatch(Objects::isNull)) {
return;
}
+ if (mRecentsView == null) {
+ return;
+ }
mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper());
}
@@ -935,7 +934,7 @@
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
super.onRecentsAnimationStart(controller, targets);
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && targets.hasDesktopTasks()) {
+ if (isDesktopModeSupported() && targets.hasDesktopTasks()) {
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
} else {
int untrimmedAppCount = mRemoteTargetHandles.length;
@@ -1161,7 +1160,7 @@
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
// Notify the SysUI to use fade-in animation when entering PiP
SystemUiProxy.INSTANCE.get(mContext).setPipAnimationTypeToAlpha();
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
// Notify the SysUI to stash desktop apps if they are visible
DesktopVisibilityController desktopVisibilityController =
mActivityInterface.getDesktopVisibilityController();
@@ -1189,7 +1188,8 @@
break;
}
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onSettledOnEndTarget " + endTarget,
+ new ActiveGestureLog.CompoundString("onSettledOnEndTarget ")
+ .append(endTarget.name()),
/* gestureEvent= */ ON_SETTLED_ON_END_TARGET);
}
@@ -1213,6 +1213,11 @@
private GestureEndTarget calculateEndTarget(
PointF velocityPxPerMs, float endVelocityPxPerMs, boolean isFlingY, boolean isCancel) {
+
+ ActiveGestureErrorDetector.GestureEvent gestureEvent =
+ velocityPxPerMs.x == 0 && velocityPxPerMs.y == 0
+ ? INVALID_VELOCITY_ON_SWIPE_UP
+ : null;
ActiveGestureLog.INSTANCE.addLog(
new ActiveGestureLog.CompoundString("calculateEndTarget: velocities=(x=")
.append(Float.toString(dpiFromPx(velocityPxPerMs.x)))
@@ -1220,7 +1225,7 @@
.append(Float.toString(dpiFromPx(velocityPxPerMs.y)))
.append("dp/ms), angle=")
.append(Double.toString(Math.toDegrees(Math.atan2(
- -velocityPxPerMs.y, velocityPxPerMs.x)))));
+ -velocityPxPerMs.y, velocityPxPerMs.x)))), gestureEvent);
if (mGestureState.isHandlingAtomicEvent()) {
// Button mode, this is only used to go to recents.
@@ -1240,7 +1245,7 @@
return LAST_TASK;
}
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED && endTarget == NEW_TASK) {
+ if (isDesktopModeSupported() && endTarget == NEW_TASK) {
// TODO(b/268075592): add support for quickswitch to/from desktop
return LAST_TASK;
}
@@ -1257,8 +1262,8 @@
return isSwipeUp ? ALL_APPS : LAST_TASK;
}
if (!isSwipeUp) {
- final boolean isCenteredOnNewTask =
- mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
+ final boolean isCenteredOnNewTask = mRecentsView != null
+ && mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
return willGoToNewTask || isCenteredOnNewTask ? NEW_TASK : LAST_TASK;
}
@@ -1534,11 +1539,13 @@
HomeAnimationFactory homeAnimFactory =
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
- mIsSwipingPipToHome = !mIsSwipeForSplit && appCanEnterPip;
+ SwipePipToHomeAnimator swipePipToHomeAnimator = !mIsSwipeForSplit && appCanEnterPip
+ ? createWindowAnimationToPip(homeAnimFactory, runningTaskTarget, start)
+ : null;
+ mIsSwipingPipToHome = swipePipToHomeAnimator != null;
final RectFSpringAnim[] windowAnim;
if (mIsSwipingPipToHome) {
- mSwipePipToHomeAnimator = createWindowAnimationToPip(
- homeAnimFactory, runningTaskTarget, start);
+ mSwipePipToHomeAnimator = swipePipToHomeAnimator;
mSwipePipToHomeAnimators[0] = mSwipePipToHomeAnimator;
if (mSwipePipToHomeReleaseCheck != null) {
mSwipePipToHomeReleaseCheck.setCanRelease(false);
@@ -1546,6 +1553,9 @@
// grab a screenshot before the PipContentOverlay gets parented on top of the task
UI_HELPER_EXECUTOR.execute(() -> {
+ if (mRecentsAnimationController == null) {
+ return;
+ }
// Directly use top task, split to pip handled on shell side
final int taskId = mGestureState.getTopRunningTaskId();
mTaskSnapshotCache.put(taskId,
@@ -1663,6 +1673,10 @@
@Nullable
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
RemoteAnimationTarget runningTaskTarget, float startProgress) {
+ if (mRecentsView == null) {
+ // Overview was destroyed, bail early.
+ return null;
+ }
// Directly animate the app to PiP (picture-in-picture) mode
final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo;
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
@@ -1803,7 +1817,8 @@
private void continueComputingRecentsScrollIfNecessary() {
if (!mGestureState.hasState(STATE_RECENTS_SCROLLING_FINISHED)
&& !mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)
- && !mCanceled) {
+ && !mCanceled
+ && mRecentsView != null) {
computeRecentsScrollIfInvisible();
mRecentsView.postOnAnimation(this::continueComputingRecentsScrollIfNecessary);
}
@@ -1847,7 +1862,6 @@
if (mActivity != null) {
// In the off chance that the gesture ends before Launcher is started, we should clear
// the callback here so that it doesn't update with the wrong state
- mActivity.clearRunOnceOnStartCallback();
resetLauncherListeners();
}
if (mGestureState.isRecentsAnimationRunning() && mGestureState.getEndTarget() != null
@@ -1913,7 +1927,7 @@
private void reset() {
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
if (mActivity != null) {
- mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
+ mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
}
}
@@ -1984,6 +1998,9 @@
* continued quick switch gesture, which cancels the previous handler but doesn't invalidate it.
*/
private void resetLauncherListeners() {
+ mActivity.removeEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
+ mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
+
mActivity.getRootView().setOnApplyWindowInsetsListener(null);
if (mRecentsView != null) {
@@ -2077,18 +2094,9 @@
}
private void finishCurrentTransitionToRecents() {
- if (mRecentsView != null
- && mActivityInterface.getDesktopVisibilityController() != null
- && mActivityInterface.getDesktopVisibilityController().areFreeformTasksVisible()) {
- mRecentsView.switchToScreenshot(() -> {
- mRecentsView.finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
- });
- } else {
- mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
- if (mRecentsAnimationController != null) {
- mRecentsAnimationController.detachNavigationBarFromApp(true);
- }
+ mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
+ if (mRecentsAnimationController != null) {
+ mRecentsAnimationController.detachNavigationBarFromApp(true);
}
}
@@ -2114,7 +2122,7 @@
* from Launcher to WM.
*/
private void maybeAbortSwipePipToHome() {
- if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
+ if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
SystemUiProxy.INSTANCE.get(mContext).abortSwipePipToHome(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getComponentName());
@@ -2128,7 +2136,10 @@
* This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
*/
private void maybeFinishSwipePipToHome() {
- if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
+ if (mRecentsAnimationController == null) {
+ return;
+ }
+ if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
mRecentsAnimationController.setFinishTaskTransaction(
mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getFinishTransaction(),
@@ -2152,7 +2163,7 @@
protected abstract void finishRecentsControllerToHome(Runnable callback);
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
- if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
+ if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED) || mRecentsView == null) {
return;
}
endLauncherTransitionController();
@@ -2186,6 +2197,9 @@
}
protected void linkRecentsViewScroll() {
+ if (mRecentsView == null) {
+ return;
+ }
SurfaceTransactionApplier applier = new SurfaceTransactionApplier(mRecentsView);
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
.setSyncTransactionApplier(applier));
@@ -2193,9 +2207,13 @@
mRecentsAnimationTargets.addReleaseCheck(applier));
mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
- runOnRecentsAnimationAndLauncherBound(() ->
- mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
- mRecentsAnimationTargets));
+ runOnRecentsAnimationAndLauncherBound(() -> {
+ if (mRecentsView == null) {
+ return;
+ }
+ mRecentsView.setRecentsAnimationTargets(
+ mRecentsAnimationController, mRecentsAnimationTargets);
+ });
// Disable scrolling in RecentsView for trackpad 3-finger swipe up gesture.
if (!mGestureState.isThreeFingerTrackpadGesture()) {
@@ -2215,7 +2233,8 @@
TaskView nextTask = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
if (nextTask != null) {
int[] taskIds = nextTask.getTaskIds();
- StringBuilder nextTaskLog = new StringBuilder();
+ ActiveGestureLog.CompoundString nextTaskLog = new ActiveGestureLog.CompoundString(
+ "Launching task: ");
for (TaskIdAttributeContainer c : nextTask.getTaskIdAttributeContainers()) {
if (c == null) {
continue;
@@ -2234,7 +2253,7 @@
if (!hasTaskPreviouslyAppeared) {
ActiveGestureLog.INSTANCE.trackEvent(EXPECTING_TASK_APPEARED);
}
- ActiveGestureLog.INSTANCE.addLog("Launching task: " + nextTaskLog);
+ ActiveGestureLog.INSTANCE.addLog(nextTaskLog);
nextTask.launchTask(success -> {
resultCallback.accept(success);
if (success) {
@@ -2301,7 +2320,7 @@
}
@Override
- public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
+ public void onTasksAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTargets) {
if (mRecentsAnimationController != null) {
boolean hasStartedTaskBefore = Arrays.stream(appearedTaskTargets).anyMatch(
mGestureState.mLastStartedTaskIdPredicate);
@@ -2310,9 +2329,12 @@
// previous quickswitch task launch, then cancel the animation back to the app
RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
TaskInfo taskInfo = appearedTaskTarget.taskInfo;
- ActiveGestureLog.INSTANCE.addLog("Unexpected task appeared"
- + " id=" + taskInfo.taskId
- + " pkg=" + taskInfo.baseIntent.getComponent().getPackageName());
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Unexpected task appeared")
+ .append(" id=")
+ .append(taskInfo.taskId)
+ .append(" pkg=")
+ .append(taskInfo.baseIntent.getComponent().getPackageName()));
finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
} else if (handleTaskAppeared(appearedTaskTargets)) {
Optional<RemoteAnimationTarget> taskTargetOptional =
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 5a9d80d..2dd6a29 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -25,6 +25,7 @@
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -50,10 +51,10 @@
import androidx.annotation.UiThread;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.BaseState;
@@ -65,7 +66,6 @@
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -111,7 +111,7 @@
if (endTarget != null) {
// We were on our way to this state when we got canceled, end there instead.
startState = stateFromGestureEndTarget(endTarget);
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
DesktopVisibilityController controller = getDesktopVisibilityController();
if (controller != null && controller.areFreeformTasksVisible()
&& endTarget == LAST_TASK) {
@@ -191,8 +191,11 @@
public abstract boolean allowAllAppsFromOverview();
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ TaskbarUIController controller = getTaskbarController();
+ boolean isEventOverBubbleBarStashHandle =
+ controller != null && controller.isEventOverBubbleBarStashHandle(ev);
return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
- || isTrackpadMultiFingerSwipe(ev);
+ || isTrackpadMultiFingerSwipe(ev) || isEventOverBubbleBarStashHandle;
}
/**
@@ -239,7 +242,7 @@
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
if (dp.isTablet) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (Flags.enableGridOnlyOverview()) {
calculateGridTaskSize(context, dp, outRect, orientedState);
} else {
calculateFocusTaskSize(context, dp, outRect);
@@ -264,7 +267,7 @@
Resources res = context.getResources();
float maxScale = res.getFloat(R.dimen.overview_max_scale);
Rect gridRect = new Rect();
- calculateGridSize(dp, gridRect);
+ calculateGridSize(dp, context, gridRect);
calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
}
@@ -318,10 +321,16 @@
/**
* Calculates the overview grid size for the provided device configuration.
*/
- public final void calculateGridSize(DeviceProfile dp, Rect outRect) {
+ public final void calculateGridSize(DeviceProfile dp, Context context, Rect outRect) {
Rect insets = dp.getInsets();
int topMargin = dp.overviewTaskThumbnailTopMarginPx;
int bottomMargin = dp.getOverviewActionsClaimedSpace();
+ if (dp.isTaskbarPresent && Flags.enableGridOnlyOverview()) {
+ topMargin += context.getResources().getDimensionPixelSize(
+ R.dimen.overview_top_margin_grid_only);
+ bottomMargin += context.getResources().getDimensionPixelSize(
+ R.dimen.overview_bottom_margin_grid_only);
+ }
int sideMargin = dp.overviewGridSideMargin;
outRect.set(0, 0, dp.widthPx, dp.heightPx);
@@ -336,8 +345,8 @@
PagedOrientationHandler orientedState) {
Resources res = context.getResources();
Rect potentialTaskRect = new Rect();
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
- calculateGridSize(dp, potentialTaskRect);
+ if (Flags.enableGridOnlyOverview()) {
+ calculateGridSize(dp, context, potentialTaskRect);
} else {
calculateFocusTaskSize(context, dp, potentialTaskRect);
}
@@ -368,7 +377,7 @@
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
calculateTaskSize(context, dp, outRect, orientedState);
- boolean isGridOnlyOverview = dp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
+ boolean isGridOnlyOverview = dp.isTablet && Flags.enableGridOnlyOverview();
int claimedSpaceBelow = isGridOnlyOverview
? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
: (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
@@ -437,11 +446,13 @@
}
protected void runOnInitBackgroundStateUI(Runnable callback) {
- mOnInitBackgroundStateUICallback = callback;
ACTIVITY_TYPE activity = getCreatedActivity();
if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
+ callback.run();
onInitBackgroundStateUI();
+ return;
}
+ mOnInitBackgroundStateUICallback = callback;
}
private void onInitBackgroundStateUI() {
diff --git a/quickstep/src/com/android/quickstep/BootAwarePreloader.kt b/quickstep/src/com/android/quickstep/BootAwarePreloader.kt
index 35404a9..2fc4d04 100644
--- a/quickstep/src/com/android/quickstep/BootAwarePreloader.kt
+++ b/quickstep/src/com/android/quickstep/BootAwarePreloader.kt
@@ -19,7 +19,7 @@
import android.util.Log
import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherPrefs
-import com.android.launcher3.isBootAwareStartupDataEnabled
+import com.android.launcher3.moveStartupDataToDeviceProtectedStorageIsEnabled
import com.android.launcher3.util.LockedUserState
/**
@@ -33,7 +33,8 @@
fun start(context: Context) {
val lp = LauncherPrefs.get(context)
when {
- LockedUserState.get(context).isUserUnlocked || !isBootAwareStartupDataEnabled -> {
+ LockedUserState.get(context).isUserUnlocked ||
+ !moveStartupDataToDeviceProtectedStorageIsEnabled -> {
/* No-Op */
}
lp.isStartupDataMigrated -> {
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index c5a88bc..57b9a39 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -66,6 +66,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TransformParams;
@@ -151,19 +152,20 @@
return new FallbackPipToHomeAnimationFactory();
}
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
- startHomeIntent(mActiveAnimationFactory, runningTaskTarget);
+ startHomeIntent(mActiveAnimationFactory, runningTaskTarget, "FallbackSwipeHandler-home");
return mActiveAnimationFactory;
}
private void startHomeIntent(
@Nullable FallbackHomeAnimationFactory gestureContractAnimationFactory,
- @Nullable RemoteAnimationTarget runningTaskTarget) {
+ @Nullable RemoteAnimationTarget runningTaskTarget,
+ @NonNull String reason) {
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
Intent intent = new Intent(mGestureState.getHomeIntent());
if (gestureContractAnimationFactory != null && runningTaskTarget != null) {
gestureContractAnimationFactory.addGestureContract(intent, runningTaskTarget.taskInfo);
}
- startHomeIntentSafely(mContext, intent, options.toBundle());
+ startHomeIntentSafely(mContext, intent, options.toBundle(), reason);
}
@Override
@@ -185,8 +187,8 @@
// the PiP task appearing.
recentsCallback = () -> {
callback.run();
- startHomeIntent(
- null /* gestureContractAnimationFactory */, null /* runningTaskTarget */);
+ startHomeIntent(null /* gestureContractAnimationFactory */,
+ null /* runningTaskTarget */, "FallbackSwipeHandler-resumeLauncher");
};
} else {
recentsCallback = callback;
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index c2d8c62..49ec85e 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -410,7 +410,8 @@
mEndTarget = target;
mStateCallback.setState(STATE_END_TARGET_SET);
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "setEndTarget " + mEndTarget,
+ new ActiveGestureLog.CompoundString("setEndTarget ")
+ .append(mEndTarget.name()),
/* gestureEvent= */ SET_END_TARGET);
switch (mEndTarget) {
case HOME:
diff --git a/quickstep/src/com/android/quickstep/InputConsumer.java b/quickstep/src/com/android/quickstep/InputConsumer.java
index 23def14..f898e2f 100644
--- a/quickstep/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/src/com/android/quickstep/InputConsumer.java
@@ -126,4 +126,14 @@
}
return name.toString();
}
+
+ /**
+ * Returns an input consumer of the given class type, or null if none is found.
+ */
+ default <T extends InputConsumer> T getInputConsumerOfClass(Class<T> c) {
+ if (getClass().equals(c)) {
+ return c.cast(this);
+ }
+ return null;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index f1660ee..406e9f4 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -58,6 +58,8 @@
import com.android.quickstep.util.RectFSpringAnim;
import com.android.systemui.shared.system.QuickStepContract;
+import java.lang.ref.WeakReference;
+
/**
* Controls the animation of swiping back and returning to launcher.
*
@@ -105,7 +107,7 @@
private boolean mAnimatorSetInProgress = false;
private float mBackProgress = 0;
private boolean mBackInProgress = false;
- private IOnBackInvokedCallback mBackCallback;
+ private OnBackInvokedCallbackStub mBackCallback;
private IRemoteAnimationFinishedCallback mAnimationFinishedCallback;
private BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
private SurfaceControl mScrimLayer;
@@ -137,65 +139,111 @@
* @param handler Handler to the thread to run the animations on.
*/
public void registerBackCallbacks(Handler handler) {
- mBackCallback = new IOnBackInvokedCallback.Stub() {
- @Override
- public void onBackCancelled() {
- handler.post(() -> {
+ mBackCallback = new OnBackInvokedCallbackStub(handler, mProgressAnimator, this);
+ SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback,
+ new RemoteAnimationRunnerStub(this));
+ }
+
+ private static class OnBackInvokedCallbackStub extends IOnBackInvokedCallback.Stub {
+ private Handler mHandler;
+ private BackProgressAnimator mProgressAnimator;
+ // LauncherBackAnimationController has strong reference to Launcher activity, the binder
+ // callback should not hold strong reference to it to avoid memory leak.
+ private WeakReference<LauncherBackAnimationController> mControllerRef;
+
+ private OnBackInvokedCallbackStub(
+ Handler handler,
+ BackProgressAnimator progressAnimator,
+ LauncherBackAnimationController controller) {
+ mHandler = handler;
+ mProgressAnimator = progressAnimator;
+ mControllerRef = new WeakReference<>(controller);
+ }
+
+ @Override
+ public void onBackCancelled() {
+ mHandler.post(() -> {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller != null) {
mProgressAnimator.onBackCancelled(
- LauncherBackAnimationController.this::resetPositionAnimated);
- });
- }
-
- @Override
- public void onBackInvoked() {
- handler.post(() -> {
- startTransition();
- mProgressAnimator.reset();
- });
- }
-
- @Override
- public void onBackProgressed(BackMotionEvent backEvent) {
- handler.post(() -> {
- mProgressAnimator.onBackProgressed(backEvent);
- });
- }
-
- @Override
- public void onBackStarted(BackMotionEvent backEvent) {
- handler.post(() -> {
- startBack(backEvent);
- mProgressAnimator.onBackStarted(backEvent, event -> {
- mBackProgress = event.getProgress();
- // TODO: Update once the interpolation curve spec is finalized.
- mBackProgress =
- 1 - (1 - mBackProgress) * (1 - mBackProgress) * (1
- - mBackProgress);
- updateBackProgress(mBackProgress, event);
- });
- });
- }
- };
-
- final IRemoteAnimationRunner runner = new IRemoteAnimationRunner.Stub() {
- @Override
- public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
- RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
- IRemoteAnimationFinishedCallback finishedCallback) {
- for (final RemoteAnimationTarget target : apps) {
- if (MODE_CLOSING == target.mode) {
- mBackTarget = target;
- break;
- }
+ controller::resetPositionAnimated);
}
- mAnimationFinishedCallback = finishedCallback;
+ });
+ }
+
+ @Override
+ public void onBackInvoked() {
+ mHandler.post(() -> {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller != null) {
+ controller.startTransition();
+ }
+ mProgressAnimator.reset();
+ });
+ }
+
+ @Override
+ public void onBackProgressed(BackMotionEvent backMotionEvent) {
+ mHandler.post(() -> {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller == null
+ || controller.mLauncher == null
+ || !controller.mLauncher.isStarted()) {
+ // Skip animating back progress if Launcher isn't visible yet.
+ return;
+ }
+ mProgressAnimator.onBackProgressed(backMotionEvent);
+ });
+ }
+
+ @Override
+ public void onBackStarted(BackMotionEvent backEvent) {
+ mHandler.post(() -> {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller != null) {
+ controller.startBack(backEvent);
+ mProgressAnimator.onBackStarted(backEvent, event -> {
+ float backProgress = event.getProgress();
+ // TODO: Update once the interpolation curve spec is finalized.
+ controller.mBackProgress =
+ 1 - (1 - backProgress) * (1 - backProgress) * (1
+ - backProgress);
+ controller.updateBackProgress(controller.mBackProgress, event);
+ });
+ }
+ });
+ }
+ }
+
+ private static class RemoteAnimationRunnerStub extends IRemoteAnimationRunner.Stub {
+
+ // LauncherBackAnimationController has strong reference to Launcher activity, the binder
+ // callback should not hold strong reference to it to avoid memory leak.
+ private WeakReference<LauncherBackAnimationController> mControllerRef;
+
+ private RemoteAnimationRunnerStub(LauncherBackAnimationController controller) {
+ mControllerRef = new WeakReference<>(controller);
+ }
+
+ @Override
+ public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
+ RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
+ IRemoteAnimationFinishedCallback finishedCallback) {
+ LauncherBackAnimationController controller = mControllerRef.get();
+ if (controller == null) {
+ return;
}
+ for (final RemoteAnimationTarget target : apps) {
+ if (MODE_CLOSING == target.mode) {
+ controller.mBackTarget = target;
+ break;
+ }
+ }
+ controller.mAnimationFinishedCallback = finishedCallback;
+ }
- @Override
- public void onAnimationCancelled() {}
- };
-
- SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback, runner);
+ @Override
+ public void onAnimationCancelled() {}
}
private void resetPositionAnimated() {
@@ -253,6 +301,10 @@
SurfaceControl parent = viewRootImpl != null
? viewRootImpl.getSurfaceControl()
: null;
+ if (parent == null || !parent.isValid()) {
+ // Parent surface is not ready at the moment. Retry later.
+ return;
+ }
boolean isDarkTheme = Utilities.isDarkTheme(mLauncher);
mScrimLayer = new SurfaceControl.Builder()
.setName("Back to launcher background scrim")
@@ -285,6 +337,10 @@
if (!mBackInProgress || mBackTarget == null) {
return;
}
+ if (mScrimLayer == null) {
+ // Scrim hasn't been attached yet. Let's attach it.
+ addScrimLayer();
+ }
float screenWidth = mStartRect.width();
float screenHeight = mStartRect.height();
float width = Utilities.mapRange(progress, 1, MIN_WINDOW_SCALE) * screenWidth;
@@ -363,12 +419,16 @@
AbstractFloatingView.closeAllOpenViewsExcept(mLauncher, false, TYPE_REBIND_SAFE);
float cornerRadius = Utilities.mapRange(
mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
+ final RectF resolveRectF = new RectF();
+ mQuickstepTransitionManager.transferRectToTargetCoordinate(
+ mBackTarget, mCurrentRect, true, resolveRectF);
+
Pair<RectFSpringAnim, AnimatorSet> pair =
mQuickstepTransitionManager.createWallpaperOpenAnimations(
new RemoteAnimationTarget[]{mBackTarget},
new RemoteAnimationTarget[0],
false /* fromUnlock */,
- mCurrentRect,
+ resolveRectF,
cornerRadius,
mBackInProgress /* fromPredictiveBack */);
startTransitionAnimations(pair.first, pair.second);
@@ -401,6 +461,9 @@
mScrimAlphaAnimator.cancel();
mScrimAlphaAnimator = null;
}
+ if (mScrimLayer != null) {
+ removeScrimLayer();
+ }
}
private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) {
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 42bf1ac..31fe791 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -37,6 +37,7 @@
import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.util.RunnableList;
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -78,6 +79,14 @@
*/
private int mTaskFocusIndexOverride = -1;
+ /**
+ * Whether we should incoming toggle commands while a previous toggle command is still ongoing.
+ * This serves as a rate-limiter to prevent overlapping animations that can clobber each other
+ * and prevent clean-up callbacks from running. This thus prevents a recurring set of bugs with
+ * janky recents animations and unresponsive home and overview buttons.
+ */
+ private boolean mWaitForToggleCommandComplete = false;
+
public OverviewCommandHelper(TouchInteractionService service,
OverviewComponentObserver observer,
TaskAnimationManager taskAnimationManager) {
@@ -160,15 +169,20 @@
private boolean launchTask(RecentsView recents, @Nullable TaskView taskView, CommandInfo cmd) {
RunnableList callbackList = null;
if (taskView != null) {
+ mWaitForToggleCommandComplete = true;
taskView.setEndQuickswitchCuj(true);
callbackList = taskView.launchTasks();
}
if (callbackList != null) {
- callbackList.add(() -> scheduleNextTask(cmd));
+ callbackList.add(() -> {
+ scheduleNextTask(cmd);
+ mWaitForToggleCommandComplete = false;
+ });
return false;
} else {
recents.startHome();
+ mWaitForToggleCommandComplete = false;
return true;
}
}
@@ -178,6 +192,9 @@
* task is deferred until {@link #scheduleNextTask} is called
*/
private <T extends StatefulActivity<?>> boolean executeCommand(CommandInfo cmd) {
+ if (mWaitForToggleCommandComplete && cmd.type == TYPE_TOGGLE) {
+ return true;
+ }
BaseActivityInterface<?, T> activityInterface =
mOverviewComponentObserver.getActivityInterface();
RecentsView recents = activityInterface.getVisibleRecentsView();
@@ -204,6 +221,7 @@
return true;
}
if (cmd.type == TYPE_HOME) {
+ ActiveGestureLog.INSTANCE.addLog("OverviewCommandHelper.executeCommand(TYPE_HOME)");
mService.startActivity(mOverviewComponentObserver.getHomeIntent());
return true;
}
@@ -359,6 +377,7 @@
pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
}
pw.println(" mTaskFocusIndexOverride=" + mTaskFocusIndexOverride);
+ pw.println(" mWaitForToggleCommandComplete=" + mWaitForToggleCommandComplete);
}
private static class CommandInfo {
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 60713cf..0a02e99 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -39,6 +39,7 @@
import com.android.launcher3.R;
import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.system.PackageManagerWrapper;
import java.io.PrintWriter;
@@ -276,20 +277,24 @@
/**
* Starts the intent for the current home activity.
*/
- public static void startHomeIntentSafely(@NonNull Context context, @Nullable Bundle options) {
+ public static void startHomeIntentSafely(@NonNull Context context, @Nullable Bundle options,
+ @NonNull String reason) {
RecentsAnimationDeviceState deviceState = new RecentsAnimationDeviceState(context);
OverviewComponentObserver observer = new OverviewComponentObserver(context, deviceState);
Intent intent = observer.getHomeIntent();
observer.onDestroy();
deviceState.destroy();
- startHomeIntentSafely(context, intent, options);
+ startHomeIntentSafely(context, intent, options, reason);
}
/**
* Starts the intent for the current home activity.
*/
public static void startHomeIntentSafely(
- @NonNull Context context, @NonNull Intent homeIntent, @Nullable Bundle options) {
+ @NonNull Context context, @NonNull Intent homeIntent, @Nullable Bundle options,
+ @NonNull String reason) {
+ ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
+ "OverviewComponentObserver.startHomeIntent: ").append(reason));
try {
context.startActivity(homeIntent, options);
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 031d409..221ce48 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -44,9 +44,7 @@
}
case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: {
- final float swipeHeight =
- LayoutUtils.getShelfTrackingDistance(mContext, mDeviceProfile,
- PagedOrientationHandler.PORTRAIT);
+ final float swipeHeight = mDeviceProfile.heightPx / 2f;
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
return response;
}
@@ -163,6 +161,10 @@
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
SystemUiProxy.INSTANCE.get(mContext).isDragAndDropReady());
return response;
+
+ case TestProtocol.REQUEST_REFRESH_OVERVIEW_TARGET:
+ runOnTISBinder(TouchInteractionService.TISBinder::refreshOverviewTarget);
+ return response;
}
return super.call(method, arg, extras);
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 0a6fefa..7c263b8 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -19,7 +19,8 @@
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.views.DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED;
+import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.wm.shell.util.GroupedRecentTaskInfo.TYPE_FREEFORM;
import android.annotation.TargetApi;
@@ -41,7 +42,6 @@
import com.android.systemui.shared.recents.model.Task;
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
-import com.android.wm.shell.util.SplitBounds;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -273,7 +273,7 @@
int numVisibleTasks = 0;
for (GroupedRecentTaskInfo rawTask : rawTasks) {
- if (DESKTOP_IS_PROTO2_ENABLED && rawTask.getType() == TYPE_FREEFORM) {
+ if (isDesktopModeSupported() && rawTask.getType() == TYPE_FREEFORM) {
GroupTask desktopTask = createDesktopTask(rawTask);
allTasks.add(desktopTask);
continue;
@@ -311,7 +311,7 @@
numVisibleTasks++;
}
final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
- convertSplitBounds(rawTask.getSplitBounds());
+ convertShellSplitBoundsToLauncher(rawTask.getSplitBounds());
allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
}
@@ -331,15 +331,6 @@
return new DesktopTask(tasks);
}
- private SplitConfigurationOptions.SplitBounds convertSplitBounds(
- SplitBounds shellSplitBounds) {
- return shellSplitBounds == null ?
- null :
- new SplitConfigurationOptions.SplitBounds(
- shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds,
- shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId);
- }
-
private ArrayList<GroupTask> copyOf(ArrayList<GroupTask> tasks) {
ArrayList<GroupTask> newTasks = new ArrayList<>();
for (int i = 0; i < tasks.size(); i++) {
@@ -380,7 +371,8 @@
writer.println(prefix + " ]");
}
- private static class TaskLoadResult extends ArrayList<GroupTask> {
+ @VisibleForTesting
+ static class TaskLoadResult extends ArrayList<GroupTask> {
final int mRequestId;
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 72439de..39edd70 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -18,7 +18,6 @@
import static android.os.Trace.TRACE_TAG_APP;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
-
import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
@@ -26,6 +25,7 @@
import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -37,7 +37,6 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Trace;
-import android.util.Log;
import android.view.Display;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
@@ -60,6 +59,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
@@ -67,7 +67,6 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.taskbar.TaskbarManager;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.RunnableList;
@@ -95,6 +94,7 @@
* See {@link com.android.quickstep.views.RecentsView}.
*/
public final class RecentsActivity extends StatefulActivity<RecentsState> {
+ private static final String TAG = "RecentsActivity";
public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
new ActivityTracker<>();
@@ -121,6 +121,8 @@
private final Handler mHandler = new Handler();
private final Runnable mAnimationStartTimeoutRunnable = this::onAnimationStartTimeout;
private SplitSelectStateController mSplitSelectStateController;
+ @Nullable
+ private DesktopRecentsTransitionController mDesktopRecentsTransitionController;
/**
* Init drag layer and overview panel views.
@@ -133,12 +135,21 @@
mFallbackRecentsView = findViewById(R.id.overview_panel);
mActionsView = findViewById(R.id.overview_actions_view);
getRootView().getSysUiScrim().getSysUIProgress().updateValue(0);
+ SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
mSplitSelectStateController =
new SplitSelectStateController(this, mHandler, getStateManager(),
null /* depthController */, getStatsLogManager(),
- SystemUiProxy.INSTANCE.get(this), RecentsModel.INSTANCE.get(this));
+ systemUiProxy, RecentsModel.INSTANCE.get(this),
+ null /*activityBackCallback*/);
mDragLayer.recreateControllers();
- mFallbackRecentsView.init(mActionsView, mSplitSelectStateController);
+ if (isDesktopModeSupported()) {
+ mDesktopRecentsTransitionController = new DesktopRecentsTransitionController(
+ getStateManager(), systemUiProxy, getIApplicationThread(),
+ null /* depthController */
+ );
+ }
+ mFallbackRecentsView.init(mActionsView, mSplitSelectStateController,
+ mDesktopRecentsTransitionController);
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
}
@@ -405,7 +416,6 @@
}
public void startHome() {
- Log.d(TestProtocol.INCORRECT_HOME_STATE, "start home from recents activity");
RecentsView recentsView = getOverviewPanel();
recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true,
this::startHomeInternal));
@@ -418,7 +428,7 @@
new RemoteAnimationAdapter(runner, HOME_APPEAR_DURATION, 0),
new RemoteTransition(runner.toRemoteTransition(), getIApplicationThread(),
"StartHomeFromRecents"));
- startHomeIntentSafely(this, options.toBundle());
+ startHomeIntentSafely(this, options.toBundle(), TAG);
}
private final RemoteAnimationFactory mAnimationToHomeFactory =
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 2256cbf..5d26ec0 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -19,10 +19,12 @@
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.CANCEL_RECENTS_ANIMATION;
-import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_CANCEL_RECENTS_ANIMATION;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_FINISH_RECENTS_ANIMATION;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_START_RECENTS_ANIMATION;
import android.graphics.Rect;
+import android.os.Bundle;
import android.util.ArraySet;
import android.view.RemoteAnimationTarget;
@@ -92,9 +94,9 @@
@Deprecated
public final void onAnimationStart(RecentsAnimationControllerCompat controller,
RemoteAnimationTarget[] appTargets, Rect homeContentInsets,
- Rect minimizedHomeBounds) {
+ Rect minimizedHomeBounds, Bundle extras) {
onAnimationStart(controller, appTargets, new RemoteAnimationTarget[0],
- homeContentInsets, minimizedHomeBounds);
+ homeContentInsets, minimizedHomeBounds, extras);
}
// Called only in R+ platform
@@ -102,7 +104,7 @@
public final void onAnimationStart(RecentsAnimationControllerCompat animationController,
RemoteAnimationTarget[] appTargets,
RemoteAnimationTarget[] wallpaperTargets,
- Rect homeContentInsets, Rect minimizedHomeBounds) {
+ Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) {
long appCount = Arrays.stream(appTargets)
.filter(app -> app.mode == MODE_CLOSING)
.count();
@@ -111,9 +113,10 @@
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "RecentsAnimationCallbacks.onAnimationStart (canceled)",
/* extras= */ 0,
- /* gestureEvent= */ START_RECENTS_ANIMATION);
+ /* gestureEvent= */ ON_START_RECENTS_ANIMATION);
notifyAnimationCanceled();
- animationController.finish(false /* toHome */, false /* sendUserLeaveHint */);
+ animationController.finish(false /* toHome */, false /* sendUserLeaveHint */,
+ null /* finishCb */);
return;
}
@@ -137,13 +140,14 @@
nonAppTargets = new RemoteAnimationTarget[0];
}
final RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
- wallpaperTargets, nonAppTargets, homeContentInsets, minimizedHomeBounds);
+ wallpaperTargets, nonAppTargets, homeContentInsets, minimizedHomeBounds,
+ extras);
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "RecentsAnimationCallbacks.onAnimationStart",
/* extras= */ targets.apps.length,
- /* gestureEvent= */ START_RECENTS_ANIMATION);
+ /* gestureEvent= */ ON_START_RECENTS_ANIMATION);
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(mController, targets);
}
@@ -157,7 +161,7 @@
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "RecentsAnimationCallbacks.onAnimationCanceled",
- /* gestureEvent= */ CANCEL_RECENTS_ANIMATION);
+ /* gestureEvent= */ ON_CANCEL_RECENTS_ANIMATION);
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationCanceled(thumbnailDatas);
}
@@ -191,7 +195,8 @@
private final void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "RecentsAnimationCallbacks.onAnimationFinished");
+ /* event= */ "RecentsAnimationCallbacks.onAnimationFinished",
+ ON_FINISH_RECENTS_ANIMATION);
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationFinished(controller);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 8972dc8..341e18c 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -21,6 +21,7 @@
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FINISH_RECENTS_ANIMATION;
import android.content.Context;
+import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.IRecentsAnimationController;
@@ -32,6 +33,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
+import com.android.internal.os.IResultReceiver;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
import com.android.quickstep.util.ActiveGestureErrorDetector;
@@ -172,12 +174,19 @@
mFinishTargetIsLauncher = toRecents;
mOnFinishedListener.accept(this);
Runnable finishCb = () -> {
- mController.finish(toRecents, sendUserLeaveHint);
+ mController.finish(toRecents, sendUserLeaveHint, new IResultReceiver.Stub() {
+ @Override
+ public void send(int i, Bundle bundle) throws RemoteException {
+ ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation-callback");
+ MAIN_EXECUTOR.execute(() -> {
+ mPendingFinishCallbacks.executeAllAndDestroy();
+ });
+ }
+ });
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
InteractionJankMonitorWrapper.end(
InteractionJankMonitorWrapper.CUJ_APP_SWIPE_TO_RECENTS);
- MAIN_EXECUTOR.execute(mPendingFinishCallbacks::executeAllAndDestroy);
};
if (forceFinish) {
finishCb.run();
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 1448a52..db5ad82 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -19,12 +19,13 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
-import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -54,23 +55,28 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.util.Log;
+import android.view.ISystemGestureExclusionListener;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
+import android.view.WindowManagerGlobal;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
+import com.android.launcher3.LauncherPrefs;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
-import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -82,15 +88,34 @@
*/
public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
+ private static final String TAG = "RecentsAnimationDeviceState";
+
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
// TODO: Move to quickstep contract
- private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 9;
- private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 2;
+ private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
+ private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 1.414f;
private final Context mContext;
private final DisplayController mDisplayController;
private final int mDisplayId;
+
+ private final ISystemGestureExclusionListener mGestureExclusionListener =
+ new ISystemGestureExclusionListener.Stub() {
+ @BinderThread
+ @Override
+ public void onSystemGestureExclusionChanged(int displayId,
+ Region systemGestureExclusionRegion, Region unrestrictedOrNull) {
+ if (displayId != mDisplayId) {
+ return;
+ }
+ // Assignments are atomic, it should be safe on binder thread. Also we don't
+ // think systemGestureExclusionRegion can be null but just in case, don't let
+ // mExclusionRegion be null.
+ mExclusionRegion = systemGestureExclusionRegion != null
+ ? systemGestureExclusionRegion : new Region();
+ }
+ };
private final RotationTouchHelper mRotationTouchHelper;
private final TaskStackChangeListener mPipListener;
// Cache for better performance since it doesn't change at runtime.
@@ -114,7 +139,7 @@
private int mGestureBlockingTaskId = -1;
private @NonNull Region mExclusionRegion = new Region();
- private SystemGestureExclusionListenerCompat mExclusionListener;
+ private boolean mExclusionListenerRegistered;
public RecentsAnimationDeviceState(Context context) {
this(context, false);
@@ -138,19 +163,7 @@
}
// Register for exclusion updates
- mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) {
- @Override
- @BinderThread
- public void onExclusionChanged(Region region) {
- if (region == null) {
- // Don't think this is possible but just in case, don't let it be null.
- region = new Region();
- }
- // Assignments are atomic, it should be safe on binder thread
- mExclusionRegion = region;
- }
- };
- runOnDestroy(mExclusionListener::unregister);
+ runOnDestroy(() -> unregisterExclusionListener());
// Register for display changes changes
mDisplayController.addChangeListener(this);
@@ -239,16 +252,58 @@
public void onDisplayInfoChanged(Context context, Info info, int flags) {
if ((flags & (CHANGE_ROTATION | CHANGE_NAVIGATION_MODE)) != 0) {
mMode = info.navigationMode;
+ ActiveGestureLog.INSTANCE.setIsFullyGesturalNavMode(isFullyGesturalNavMode());
mNavBarPosition = new NavBarPosition(mMode, info);
if (mMode == NO_BUTTON) {
- mExclusionListener.register();
+ registerExclusionListener();
} else {
- mExclusionListener.unregister();
+ unregisterExclusionListener();
}
}
}
+ /**
+ * Registers {@link mGestureExclusionListener} for getting exclusion rect changes. Note that we
+ * make binder call on {@link UI_HELPER_EXECUTOR} to avoid jank.
+ */
+ public void registerExclusionListener() {
+ UI_HELPER_EXECUTOR.execute(() -> {
+ if (mExclusionListenerRegistered) {
+ return;
+ }
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .registerSystemGestureExclusionListener(
+ mGestureExclusionListener, mDisplayId);
+ mExclusionListenerRegistered = true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register window manager callbacks", e);
+ }
+ });
+ }
+
+ /**
+ * Unregisters {@link mGestureExclusionListener} if previously registered. We make binder call
+ * on same {@link UI_HELPER_EXECUTOR} as in {@link #registerExclusionListener()} so that
+ * read/write {@link mExclusionListenerRegistered} field is thread safe.
+ */
+ public void unregisterExclusionListener() {
+ UI_HELPER_EXECUTOR.execute(() -> {
+ if (!mExclusionListenerRegistered) {
+ return;
+ }
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .unregisterSystemGestureExclusionListener(
+ mGestureExclusionListener, mDisplayId);
+ mExclusionListenerRegistered = false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to unregister window manager callbacks", e);
+ }
+ });
+ }
+
public void onOneHandedModeChanged(int newGesturalHeight) {
mRotationTouchHelper.setGesturalHeight(newGesturalHeight);
}
@@ -275,13 +330,6 @@
}
/**
- * @return whether the current nav mode is 2-button-based.
- */
- public boolean isTwoButtonNavMode() {
- return mMode == TWO_BUTTONS;
- }
-
- /**
* @return whether the current nav mode is button-based.
*/
public boolean isButtonNavMode() {
@@ -386,13 +434,6 @@
}
/**
- * @return whether notification panel is expanded
- */
- public boolean isNotificationPanelExpanded() {
- return (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
- }
-
- /**
* @return whether the global actions dialog is showing
*/
public boolean isSystemUiDialogShowing() {
@@ -544,15 +585,31 @@
/**
* Returns the touch slop for {@link InputConsumer}s to compare against before pilfering
- * pointers. Note that this is squared because it expects to be compared against
- * {@link com.android.launcher3.Utilities#squaredHypot} (to avoid square root on each event).
+ * pointers.
*/
- public float getSquaredTouchSlop() {
+ public float getTouchSlop() {
float slopMultiplier = isFullyGesturalNavMode()
? QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL
: QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
- return slopMultiplier * touchSlop * touchSlop;
+
+ if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
+ float customSlopMultiplier =
+ LauncherPrefs.get(mContext).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
+ return customSlopMultiplier * slopMultiplier * touchSlop;
+ } else {
+ return slopMultiplier * touchSlop;
+ }
+ }
+
+ /**
+ * Returns the squared touch slop for {@link InputConsumer}s to compare against before pilfering
+ * pointers. Note that this is squared because it expects to be compared against
+ * {@link com.android.launcher3.Utilities#squaredHypot} (to avoid square root on each event).
+ */
+ public float getSquaredTouchSlop() {
+ float touchSlop = getTouchSlop();
+ return touchSlop * touchSlop;
}
public String getSystemUiStateString() {
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
index 15e1365..556dd7e 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
@@ -17,13 +17,13 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.app.WindowConfiguration;
import android.graphics.Rect;
+import android.os.Bundle;
import android.view.RemoteAnimationTarget;
-import com.android.quickstep.views.DesktopTaskView;
-
/**
* Extension of {@link RemoteAnimationTargets} with additional information about swipe
* up animation
@@ -35,8 +35,8 @@
public RecentsAnimationTargets(RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
- Rect homeContentInsets, Rect minimizedHomeBounds) {
- super(apps, wallpapers, nonApps, MODE_CLOSING);
+ Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) {
+ super(apps, wallpapers, nonApps, MODE_CLOSING, extras);
this.homeContentInsets = homeContentInsets;
this.minimizedHomeBounds = minimizedHomeBounds;
}
@@ -52,7 +52,7 @@
* @return {@code true} if at least one target app is a desktop task
*/
public boolean hasDesktopTasks() {
- if (!DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (!isDesktopModeSupported()) {
return false;
}
for (RemoteAnimationTarget target : apps) {
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index d798e62..89351aa 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -17,15 +17,18 @@
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.KeyguardManager;
+import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Configuration;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
@@ -36,6 +39,7 @@
import com.android.launcher3.icons.IconProvider.IconChangeListener;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SafeCloseable;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.TaskVisualsChangeListener;
import com.android.systemui.shared.recents.model.Task;
@@ -57,7 +61,7 @@
*/
@TargetApi(Build.VERSION_CODES.O)
public class RecentsModel implements IconChangeListener, TaskStackChangeListener,
- TaskVisualsChangeListener {
+ TaskVisualsChangeListener, SafeCloseable {
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
@@ -72,19 +76,52 @@
private final RecentTasksList mTaskList;
private final TaskIconCache mIconCache;
private final TaskThumbnailCache mThumbnailCache;
+ private final ComponentCallbacks mCallbacks;
+
+ private final TaskStackChangeListeners mTaskStackChangeListeners;
private RecentsModel(Context context) {
+ this(context, new IconProvider(context));
+ }
+
+ private RecentsModel(Context context, IconProvider iconProvider) {
+ this(context,
+ new RecentTasksList(MAIN_EXECUTOR,
+ context.getSystemService(KeyguardManager.class),
+ SystemUiProxy.INSTANCE.get(context)),
+ new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider),
+ new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR),
+ iconProvider,
+ TaskStackChangeListeners.getInstance());
+ }
+
+ @VisibleForTesting
+ RecentsModel(Context context, RecentTasksList taskList, TaskIconCache iconCache,
+ TaskThumbnailCache thumbnailCache, IconProvider iconProvider,
+ TaskStackChangeListeners taskStackChangeListeners) {
mContext = context;
- mTaskList = new RecentTasksList(MAIN_EXECUTOR,
- context.getSystemService(KeyguardManager.class),
- SystemUiProxy.INSTANCE.get(context));
-
- IconProvider iconProvider = new IconProvider(context);
- mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
+ mTaskList = taskList;
+ mIconCache = iconCache;
mIconCache.registerTaskVisualsChangeListener(this);
- mThumbnailCache = new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR);
+ mThumbnailCache = thumbnailCache;
+ if (enableGridOnlyOverview()) {
+ mCallbacks = new ComponentCallbacks() {
+ @Override
+ public void onConfigurationChanged(Configuration configuration) {
+ updateCacheSizeAndPreloadIfNeeded();
+ }
- TaskStackChangeListeners.getInstance().registerTaskStackListener(this);
+ @Override
+ public void onLowMemory() {
+ }
+ };
+ context.registerComponentCallbacks(mCallbacks);
+ } else {
+ mCallbacks = null;
+ }
+
+ mTaskStackChangeListeners = taskStackChangeListeners;
+ mTaskStackChangeListeners.registerTaskStackListener(this);
iconProvider.registerIconChangeListener(this, MAIN_EXECUTOR.getHandler());
}
@@ -109,7 +146,6 @@
RecentsFilterState.DEFAULT_FILTER);
}
-
/**
* Fetches the list of recent tasks, based on a filter
*
@@ -183,8 +219,8 @@
// time the user next enters overview
continue;
}
- mThumbnailCache.updateThumbnailInCache(group.task1);
- mThumbnailCache.updateThumbnailInCache(group.task2);
+ mThumbnailCache.updateThumbnailInCache(group.task1, /* lowResolution= */ true);
+ mThumbnailCache.updateThumbnailInCache(group.task2, /* lowResolution= */ true);
}
});
}
@@ -281,6 +317,56 @@
}
/**
+ * Preloads cache if enableGridOnlyOverview is true, preloading is enabled and
+ * highResLoadingState is enabled
+ */
+ public void preloadCacheIfNeeded() {
+ if (!enableGridOnlyOverview()) {
+ return;
+ }
+
+ if (!mThumbnailCache.isPreloadingEnabled()) {
+ // Skip if we aren't preloading.
+ return;
+ }
+
+ if (!mThumbnailCache.getHighResLoadingState().isEnabled()) {
+ // Skip if high-res loading state is disabled.
+ return;
+ }
+
+ mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), taskGroups -> {
+ for (GroupTask group : taskGroups) {
+ mThumbnailCache.updateThumbnailInCache(group.task1, /* lowResolution= */ false);
+ mThumbnailCache.updateThumbnailInCache(group.task2, /* lowResolution= */ false);
+ }
+ });
+ }
+
+ /**
+ * Updates cache size and preloads more tasks if cache size increases
+ */
+ public void updateCacheSizeAndPreloadIfNeeded() {
+ if (!enableGridOnlyOverview()) {
+ return;
+ }
+
+ // If new size is larger than original size, preload more cache to fill the gap
+ if (mThumbnailCache.updateCacheSizeAndRemoveExcess()) {
+ preloadCacheIfNeeded();
+ }
+ }
+
+ @Override
+ public void close() {
+ if (mCallbacks != null) {
+ mContext.unregisterComponentCallbacks(mCallbacks);
+ }
+ mIconCache.removeTaskVisualsChangeListener();
+ mTaskStackChangeListeners.unregisterTaskStackListener(this);
+ }
+
+ /**
* Listener for receiving running tasks changes
*/
public interface RunningTasksListener {
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index 80aaad0..e0c7403 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -19,6 +19,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import android.os.Bundle;
import android.view.RemoteAnimationTarget;
import java.util.ArrayList;
@@ -35,6 +36,7 @@
public final RemoteAnimationTarget[] apps;
public final RemoteAnimationTarget[] wallpapers;
public final RemoteAnimationTarget[] nonApps;
+ public final Bundle extras;
public final int targetMode;
public final boolean hasRecents;
@@ -42,7 +44,7 @@
public RemoteAnimationTargets(RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
- int targetMode) {
+ int targetMode, Bundle extras) {
ArrayList<RemoteAnimationTarget> filteredApps = new ArrayList<>();
boolean hasRecents = false;
if (apps != null) {
@@ -61,6 +63,13 @@
this.targetMode = targetMode;
this.hasRecents = hasRecents;
this.nonApps = nonApps;
+ this.extras = extras;
+ }
+
+ public RemoteAnimationTargets(RemoteAnimationTarget[] apps,
+ RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
+ int targetMode) {
+ this(apps, wallpapers, nonApps, targetMode, new Bundle());
}
public RemoteAnimationTarget findTask(int taskId) {
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 84246e9..98d0ece 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -16,7 +16,10 @@
package com.android.quickstep;
-import android.app.WindowConfiguration;
+import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
+import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
+
import android.content.Context;
import android.graphics.Rect;
import android.util.Log;
@@ -24,11 +27,11 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
-import com.android.quickstep.views.DesktopTaskView;
+import com.android.wm.shell.util.SplitBounds;
import java.util.ArrayList;
import java.util.Arrays;
@@ -43,7 +46,7 @@
private static final int DEFAULT_NUM_HANDLES = 2;
private RemoteTargetHandle[] mRemoteTargetHandles;
- private SplitBounds mSplitBounds;
+ private SplitConfigurationOptions.SplitBounds mSplitBounds;
/**
* Use this constructor if remote targets are split-screen independent
@@ -58,7 +61,7 @@
* running tasks
*/
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
// TODO(279931899): binder call, only for prototyping. Creating the gluer should be
// postponed so we can create it when we have the remote animation targets ready.
int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount(
@@ -111,6 +114,16 @@
}
/**
+ * Calls {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)} with SplitBounds
+ * information specified.
+ */
+ public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets,
+ SplitConfigurationOptions.SplitBounds splitBounds) {
+ mSplitBounds = splitBounds;
+ return assignTargetsForSplitScreen(targets);
+ }
+
+ /**
* Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this assigns the
* apps in {@code targets.apps} to the {@link #mRemoteTargetHandles} with index 0 will being
* the left/top task, index 1 right/bottom.
@@ -129,10 +142,17 @@
mRemoteTargetHandles = newHandles;
}
- boolean containsSplitTargets = Arrays.stream(targets.apps)
- .anyMatch(remoteAnimationTarget ->
- remoteAnimationTarget.windowConfiguration.getWindowingMode()
- == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+ // If we are in a true split screen case (2 apps running on screen), either:
+ // a) mSplitBounds was already set (from the clicked GroupedTaskView)
+ // b) A SplitBounds was passed up from shell (via AbsSwipeUpHandler)
+ // If both of these are null, we are in a 1-app or 1-app-plus-assistant case.
+ if (mSplitBounds == null) {
+ SplitBounds shellSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS,
+ SplitBounds.class);
+ mSplitBounds = convertShellSplitBoundsToLauncher(shellSplitBounds);
+ }
+
+ boolean containsSplitTargets = mSplitBounds != null;
Log.d(TAG, "containsSplitTargets? " + containsSplitTargets + " handleLength: " +
mRemoteTargetHandles.length + " appsLength: " + targets.apps.length);
@@ -154,40 +174,12 @@
}
} else {
// Split apps (+ maybe assistant)
- RemoteAnimationTarget topLeftTarget = Arrays.stream(targets.apps)
- .filter(remoteAnimationTarget ->
- remoteAnimationTarget.windowConfiguration.getWindowingMode()
- == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW)
- .findFirst().get();
-
- // Fetch the adjacent target for split screen.
- RemoteAnimationTarget bottomRightTarget = null;
- for (int i = 0; i < targets.apps.length; i++) {
- final RemoteAnimationTarget target = targets.apps[i];
- if (target.windowConfiguration.getWindowingMode() !=
- WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW ||
- target == topLeftTarget) {
- continue;
- }
- Rect topLeftBounds = getStartBounds(topLeftTarget);
- Rect bounds = getStartBounds(target);
- if (topLeftBounds.left > bounds.right || topLeftBounds.top > bounds.bottom) {
- bottomRightTarget = topLeftTarget;
- topLeftTarget = target;
- break;
- } else if (topLeftBounds.right < bounds.left || topLeftBounds.bottom < bounds.top) {
- bottomRightTarget = target;
- break;
- }
- }
+ RemoteAnimationTarget topLeftTarget = targets.findTask(mSplitBounds.leftTopTaskId);
+ RemoteAnimationTarget bottomRightTarget = targets.findTask(
+ mSplitBounds.rightBottomTaskId);
// remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude,
// vice versa
- mSplitBounds = new SplitBounds(
- getStartBounds(topLeftTarget),
- getStartBounds(bottomRightTarget),
- topLeftTarget.taskId,
- bottomRightTarget.taskId);
mRemoteTargetHandles[0].mTransformParams.setTargetSet(
createRemoteAnimationTargetsForTarget(targets, bottomRightTarget));
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget,
@@ -291,7 +283,7 @@
return mRemoteTargetHandles;
}
- public SplitBounds getSplitBounds() {
+ public SplitConfigurationOptions.SplitBounds getSplitBounds() {
return mSplitBounds;
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index fae929a..00d8008 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -17,8 +17,11 @@
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
+import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.RECENT_TASKS_MISSING;
import static com.android.quickstep.util.LogUtils.splitFailureMessage;
import android.app.ActivityManager;
@@ -31,6 +34,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -59,9 +63,10 @@
import com.android.internal.logging.InstanceId;
import com.android.internal.util.ScreenshotRequest;
import com.android.internal.view.AppearanceRegion;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.AssistUtils;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -75,6 +80,7 @@
import com.android.wm.shell.back.IBackAnimation;
import com.android.wm.shell.bubbles.IBubbles;
import com.android.wm.shell.bubbles.IBubblesListener;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.desktopmode.IDesktopMode;
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import com.android.wm.shell.draganddrop.IDragAndDrop;
@@ -88,9 +94,11 @@
import com.android.wm.shell.splitscreen.ISplitSelectListener;
import com.android.wm.shell.startingsurface.IStartingWindow;
import com.android.wm.shell.startingsurface.IStartingWindowListener;
+import com.android.wm.shell.transition.IHomeTransitionListener;
import com.android.wm.shell.transition.IShellTransitions;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
@@ -133,6 +141,7 @@
private ISplitSelectListener mSplitSelectListener;
private IStartingWindowListener mStartingWindowListener;
private ILauncherUnlockAnimationController mLauncherUnlockAnimationController;
+ private String mLauncherActivityClass;
private IRecentTasksListener mRecentTasksListener;
private IUnfoldTransitionListener mUnfoldAnimationListener;
private IDesktopTaskListener mDesktopTaskListener;
@@ -142,6 +151,7 @@
private IOnBackInvokedCallback mBackToLauncherCallback;
private IRemoteAnimationRunner mBackToLauncherRunner;
private IDragAndDrop mDragAndDrop;
+ private IHomeTransitionListener mHomeTransitionListener;
// Used to dedupe calls to SystemUI
private int mLastShelfHeight;
@@ -243,8 +253,10 @@
setBubblesListener(mBubblesListener);
registerSplitScreenListener(mSplitScreenListener);
registerSplitSelectListener(mSplitSelectListener);
+ setHomeTransitionListener(mHomeTransitionListener);
setStartingWindowListener(mStartingWindowListener);
- setLauncherUnlockAnimationController(mLauncherUnlockAnimationController);
+ setLauncherUnlockAnimationController(
+ mLauncherActivityClass, mLauncherUnlockAnimationController);
new LinkedHashMap<>(mRemoteTransitions).forEach(this::registerRemoteTransition);
setupTransactionQueue();
registerRecentTasksListener(mRecentTasksListener);
@@ -388,6 +400,17 @@
}
@Override
+ public void animateNavBarLongPress(boolean isTouchDown, long durationMs) {
+ if (mSystemUiProxy != null) {
+ try {
+ mSystemUiProxy.animateNavBarLongPress(isTouchDown, durationMs);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call animateNavBarLongPress", e);
+ }
+ }
+ }
+
+ @Override
public void notifyAccessibilityButtonClicked(int displayId) {
if (mSystemUiProxy != null) {
try {
@@ -731,6 +754,18 @@
}
}
+ /**
+ * Tells SysUI to show user education relative to the reference point provided.
+ * @param position the bubble bar top center position in Screen coordinates.
+ */
+ public void showUserEducation(Point position) {
+ try {
+ mBubbles.showUserEducation(position.x, position.y);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call showUserEducation");
+ }
+ }
+
//
// Splitscreen
//
@@ -781,12 +816,12 @@
/** Start multiple tasks in split-screen simultaneously. */
public void startTasks(int taskId1, Bundle options1, int taskId2, Bundle options2,
- @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio,
+ @StagePosition int splitPosition, @PersistentSnapPosition int snapPosition,
RemoteTransition remoteTransition, InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startTasks(taskId1, options1, taskId2, options2, splitPosition,
- splitRatio, remoteTransition, instanceId);
+ snapPosition, remoteTransition, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage("startTasks", "RemoteException"), e);
}
@@ -794,12 +829,13 @@
}
public void startIntentAndTask(PendingIntent pendingIntent, int userId1, Bundle options1,
- int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition,
- float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) {
+ int taskId, Bundle options2, @StagePosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, RemoteTransition remoteTransition,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startIntentAndTask(pendingIntent, userId1, options1, taskId, options2,
- splitPosition, splitRatio, remoteTransition, instanceId);
+ splitPosition, snapPosition, remoteTransition, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage("startIntentAndTask", "RemoteException"), e);
}
@@ -809,13 +845,13 @@
public void startIntents(PendingIntent pendingIntent1, int userId1,
@Nullable ShortcutInfo shortcutInfo1, Bundle options1, PendingIntent pendingIntent2,
int userId2, @Nullable ShortcutInfo shortcutInfo2, Bundle options2,
- @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio,
+ @StagePosition int splitPosition, @PersistentSnapPosition int snapPosition,
RemoteTransition remoteTransition, InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startIntents(pendingIntent1, userId1, shortcutInfo1, options1,
- pendingIntent2, userId2, shortcutInfo2, options2, splitPosition, splitRatio,
- remoteTransition, instanceId);
+ pendingIntent2, userId2, shortcutInfo2, options2, splitPosition,
+ snapPosition, remoteTransition, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage("startIntents", "RemoteException"), e);
}
@@ -823,12 +859,13 @@
}
public void startShortcutAndTask(ShortcutInfo shortcutInfo, Bundle options1, int taskId,
- Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition,
- float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) {
+ Bundle options2, @StagePosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, RemoteTransition remoteTransition,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startShortcutAndTask(shortcutInfo, options1, taskId, options2,
- splitPosition, splitRatio, remoteTransition, instanceId);
+ splitPosition, snapPosition, remoteTransition, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage("startShortcutAndTask", "RemoteException"), e);
}
@@ -839,12 +876,13 @@
* Start multiple tasks in split-screen simultaneously.
*/
public void startTasksWithLegacyTransition(int taskId1, Bundle options1, int taskId2,
- Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition,
- float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+ Bundle options2, @StagePosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startTasksWithLegacyTransition(taskId1, options1, taskId2, options2,
- splitPosition, splitRatio, adapter, instanceId);
+ splitPosition, snapPosition, adapter, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage(
"startTasksWithLegacyTransition", "RemoteException"), e);
@@ -853,13 +891,14 @@
}
public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
- Bundle options1, int taskId, Bundle options2,
- @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio,
- RemoteAnimationAdapter adapter, InstanceId instanceId) {
+ Bundle options1, int taskId, Bundle options2, @StagePosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, userId1,
- options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId);
+ options1, taskId, options2, splitPosition, snapPosition, adapter,
+ instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage(
"startIntentAndTaskWithLegacyTransition", "RemoteException"), e);
@@ -868,12 +907,13 @@
}
public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, Bundle options1,
- int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition,
- float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+ int taskId, Bundle options2, @StagePosition int splitPosition,
+ @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, options1,
- taskId, options2, splitPosition, splitRatio, adapter, instanceId);
+ taskId, options2, splitPosition, snapPosition, adapter, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage(
"startShortcutAndTaskWithLegacyTransition", "RemoteException"), e);
@@ -888,13 +928,14 @@
public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, int userId1,
@Nullable ShortcutInfo shortcutInfo1, @Nullable Bundle options1,
PendingIntent pendingIntent2, int userId2, @Nullable ShortcutInfo shortcutInfo2,
- @Nullable Bundle options2, @SplitConfigurationOptions.StagePosition int sidePosition,
- float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) {
+ @Nullable Bundle options2, @StagePosition int sidePosition,
+ @PersistentSnapPosition int snapPosition, RemoteAnimationAdapter adapter,
+ InstanceId instanceId) {
if (mSystemUiProxy != null) {
try {
mSplitScreen.startIntentsWithLegacyTransition(pendingIntent1, userId1,
shortcutInfo1, options1, pendingIntent2, userId2, shortcutInfo2, options2,
- sidePosition, splitRatio, adapter, instanceId);
+ sidePosition, snapPosition, adapter, instanceId);
} catch (RemoteException e) {
Log.w(TAG, splitFailureMessage(
"startIntentsWithLegacyTransition", "RemoteException"), e);
@@ -1019,6 +1060,24 @@
mRemoteTransitions.remove(remoteTransition);
}
+ public void setHomeTransitionListener(IHomeTransitionListener listener) {
+ if (!FeatureFlags.enableHomeTransitionListener()) {
+ return;
+ }
+
+ mHomeTransitionListener = listener;
+
+ if (mShellTransitions != null) {
+ try {
+ mShellTransitions.setHomeTransitionListener(listener);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call setHomeTransitionListener", e);
+ }
+ } else {
+ Log.w(TAG, "Unable to call setHomeTransitionListener because ShellTransitions is null");
+ }
+ }
+
/**
* Use SystemUI's transaction-queue instead of Launcher's independent one. This is necessary
* if Launcher and SystemUI need to coordinate transactions (eg. for shell transitions).
@@ -1092,11 +1151,11 @@
* changes).
*/
public void setLauncherUnlockAnimationController(
- ILauncherUnlockAnimationController controller) {
+ String activityClass, ILauncherUnlockAnimationController controller) {
if (mSysuiUnlockAnimationController != null) {
try {
- mSysuiUnlockAnimationController.setLauncherUnlockController(controller);
-
+ mSysuiUnlockAnimationController.setLauncherUnlockController(
+ activityClass, controller);
if (controller != null) {
controller.dispatchSmartspaceStateToSysui();
}
@@ -1104,7 +1163,7 @@
Log.w(TAG, "Failed call setLauncherUnlockAnimationController", e);
}
}
-
+ mLauncherActivityClass = activityClass;
mLauncherUnlockAnimationController = controller;
}
@@ -1203,19 +1262,21 @@
}
public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
- if (mRecentTasks != null) {
- try {
- final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
- RECENT_IGNORE_UNAVAILABLE, userId);
- if (rawTasks == null) {
- return new ArrayList<>();
- }
- return new ArrayList<>(Arrays.asList(rawTasks));
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call getRecentTasks", e);
- }
+ if (mRecentTasks == null) {
+ Log.w(TAG, "getRecentTasks() failed due to null mRecentTasks");
+ return new ArrayList<>();
}
- return new ArrayList<>();
+ try {
+ final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
+ RECENT_IGNORE_UNAVAILABLE, userId);
+ if (rawTasks == null) {
+ return new ArrayList<>();
+ }
+ return new ArrayList<>(Arrays.asList(rawTasks));
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call getRecentTasks", e);
+ return new ArrayList<>();
+ }
}
/**
@@ -1251,10 +1312,10 @@
//
/** Call shell to show all apps active on the desktop */
- public void showDesktopApps(int displayId) {
+ public void showDesktopApps(int displayId, @Nullable RemoteTransition transition) {
if (mDesktopMode != null) {
try {
- mDesktopMode.showDesktopApps(displayId);
+ mDesktopMode.showDesktopApps(displayId, transition);
} catch (RemoteException e) {
Log.w(TAG, "Failed call showDesktopApps", e);
}
@@ -1359,15 +1420,21 @@
public boolean startRecentsActivity(Intent intent, ActivityOptions options,
RecentsAnimationListener listener) {
if (mRecentTasks == null) {
+ ActiveGestureLog.INSTANCE.addLog("Null mRecentTasks", RECENT_TASKS_MISSING);
return false;
}
final IRecentsAnimationRunner runner = new IRecentsAnimationRunner.Stub() {
@Override
public void onAnimationStart(IRecentsAnimationController controller,
RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
- Rect homeContentInsets, Rect minimizedHomeBounds) {
+ Rect homeContentInsets, Rect minimizedHomeBounds, Bundle extras) {
+ // Aidl bundles need to explicitly set class loader
+ // https://developer.android.com/guide/components/aidl#Bundles
+ if (extras != null) {
+ extras.setClassLoader(getClass().getClassLoader());
+ }
listener.onAnimationStart(new RecentsAnimationControllerCompat(controller), apps,
- wallpapers, homeContentInsets, minimizedHomeBounds);
+ wallpapers, homeContentInsets, minimizedHomeBounds, extras);
}
@Override
@@ -1411,4 +1478,35 @@
return false;
}
}
+
+ public void dump(PrintWriter pw) {
+ pw.println(TAG + ":");
+
+ pw.println("\tmSystemUiProxy=" + mSystemUiProxy);
+ pw.println("\tmPip=" + mPip);
+ pw.println("\tmPipAnimationListener=" + mPipAnimationListener);
+ pw.println("\tmBubbles=" + mBubbles);
+ pw.println("\tmBubblesListener=" + mBubblesListener);
+ pw.println("\tmSplitScreen=" + mSplitScreen);
+ pw.println("\tmSplitScreenListener=" + mSplitScreenListener);
+ pw.println("\tmSplitSelectListener=" + mSplitSelectListener);
+ pw.println("\tmOneHanded=" + mOneHanded);
+ pw.println("\tmShellTransitions=" + mShellTransitions);
+ pw.println("\tmHomeTransitionListener=" + mHomeTransitionListener);
+ pw.println("\tmStartingWindow=" + mStartingWindow);
+ pw.println("\tmStartingWindowListener=" + mStartingWindowListener);
+ pw.println("\tmSysuiUnlockAnimationController=" + mSysuiUnlockAnimationController);
+ pw.println("\tmLauncherActivityClass=" + mLauncherActivityClass);
+ pw.println("\tmLauncherUnlockAnimationController=" + mLauncherUnlockAnimationController);
+ pw.println("\tmRecentTasks=" + mRecentTasks);
+ pw.println("\tmRecentTasksListener=" + mRecentTasksListener);
+ pw.println("\tmBackAnimation=" + mBackAnimation);
+ pw.println("\tmBackToLauncherCallback=" + mBackToLauncherCallback);
+ pw.println("\tmBackToLauncherRunner=" + mBackToLauncherRunner);
+ pw.println("\tmDesktopMode=" + mDesktopMode);
+ pw.println("\tmDesktopTaskListener=" + mDesktopTaskListener);
+ pw.println("\tmUnfoldAnimation=" + mUnfoldAnimation);
+ pw.println("\tmUnfoldAnimationListener=" + mUnfoldAnimationListener);
+ pw.println("\tmDragAndDrop=" + mDragAndDrop);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 2896fe0..0bc44e1 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
+import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION;
@@ -38,11 +39,8 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.util.ActiveGestureLog;
-import com.android.quickstep.views.DesktopTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -119,7 +117,8 @@
}
}
// But force-finish it anyways
- finishRunningRecentsAnimation(false /* toHome */, true /* forceFinish */);
+ finishRunningRecentsAnimation(false /* toHome */, true /* forceFinish */,
+ null /* forceFinishCb */);
if (mCallbacks != null) {
// If mCallbacks still != null, that means we are getting this startRecentsAnimation()
@@ -154,6 +153,24 @@
mLastAppearedTaskTargets[i] = task;
}
mLastGestureState.updateLastAppearedTaskTargets(mLastAppearedTaskTargets);
+
+ if (ENABLE_SHELL_TRANSITIONS && mTargets.hasRecents
+ // The filtered (MODE_CLOSING) targets only contain 1 home activity.
+ && mTargets.apps.length == 1
+ && mTargets.apps[0].windowConfiguration.getActivityType()
+ == ACTIVITY_TYPE_HOME) {
+ // This is launching RecentsActivity on top of a 3p launcher. There are no
+ // other apps need to keep visible so finish the animating state after the
+ // enter animation of overview is done. Then 3p launcher can be stopped.
+ mLastGestureState.runOnceAtState(STATE_END_TARGET_ANIMATION_FINISHED, () -> {
+ // Only finish if the end target is RECENTS. Otherwise, if the target is
+ // NEW_TASK, startActivityFromRecents will be skipped.
+ if (mLastGestureState.getEndTarget() == RECENTS) {
+ finishRunningRecentsAnimation(false /* toHome */,
+ true /* forceFinish */, null /* forceFinishCb */);
+ }
+ });
+ }
}
@Override
@@ -181,9 +198,6 @@
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
if (recentsView != null) {
- Log.d(TestProtocol.INCORRECT_HOME_STATE,
- "finish recents animation on "
- + compat.taskInfo.description);
recentsView.finishRecentsAnimation(true, null);
}
return;
@@ -201,8 +215,9 @@
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
if (recentsView != null) {
- ActiveGestureLog.INSTANCE.addLog("Launching side task id="
- + appearedTaskTarget.taskId);
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Launching side task id=")
+ .append(appearedTaskTarget.taskId));
recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId,
appearedTaskTargets,
new RemoteAnimationTarget[0] /* wallpaper */,
@@ -255,21 +270,8 @@
if (ENABLE_SHELL_TRANSITIONS) {
final ActivityOptions options = ActivityOptions.makeBasic();
- // Allowing to pause Home if Home is top activity and Recents is not Home. So when user
- // start home when recents animation is playing, the home activity can be resumed again
- // to let the transition controller collect Home activity.
- CachedTaskInfo cti = gestureState.getRunningTask();
- boolean homeIsOnTop = cti != null && cti.isHomeTask();
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
- if (cti != null && cti.isFreeformTask()) {
- // No transient launch when desktop task is on top
- homeIsOnTop = true;
- }
- }
- if (activityInterface.allowAllAppsFromOverview()) {
- homeIsOnTop = true;
- }
- if (!homeIsOnTop) {
+ // Use regular (non-transient) launch for all apps page to control IME.
+ if (!activityInterface.allowAllAppsFromOverview()) {
options.setTransientLaunch();
}
options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
@@ -324,19 +326,20 @@
* Finishes the running recents animation.
*/
public void finishRunningRecentsAnimation(boolean toHome) {
- finishRunningRecentsAnimation(toHome, false /* forceFinish */);
+ finishRunningRecentsAnimation(toHome, false /* forceFinish */, null /* forceFinishCb */);
}
/**
* Finishes the running recents animation.
* @param forceFinish will synchronously finish the controller
*/
- public void finishRunningRecentsAnimation(boolean toHome, boolean forceFinish) {
+ public void finishRunningRecentsAnimation(boolean toHome, boolean forceFinish,
+ Runnable forceFinishCb) {
if (mController != null) {
ActiveGestureLog.INSTANCE.addLog(
/* event= */ "finishRunningRecentsAnimation", toHome);
if (forceFinish) {
- mController.finishController(toHome, null, false /* sendUserLeaveHint */,
+ mController.finishController(toHome, forceFinishCb, false /* sendUserLeaveHint */,
true /* forceFinish */);
} else {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), toHome
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 164a366..20a751b 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
import android.annotation.Nullable;
@@ -40,6 +41,7 @@
import com.android.launcher3.icons.BaseIconFactory.IconOptions;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconProvider;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
@@ -119,6 +121,7 @@
public void handleResult(TaskCacheEntry result) {
task.icon = result.icon;
task.titleDescription = result.contentDescription;
+ task.title = result.title;
callback.accept(task);
dispatchIconUpdate(task.key.id);
}
@@ -189,6 +192,10 @@
if (activityInfo != null) {
entry.contentDescription = getBadgedContentDescription(
activityInfo, task.key.userId, task.taskDescription);
+ if (enableOverviewIconMenu()) {
+ entry.title = Utilities.trim(
+ activityInfo.applicationInfo.loadLabel(mContext.getPackageManager()));
+ }
}
mIconCache.put(task.key, entry);
@@ -233,7 +240,9 @@
} else {
try (BaseIconFactory li = getIconFactory()) {
BitmapInfo info = mDefaultIconBase.withFlags(
- li.getBitmapFlagOp(new IconOptions().setUser(UserHandle.of(userId))));
+ li.getBitmapFlagOp(new IconOptions()
+ .setUser(UserCache.INSTANCE.get(mContext)
+ .getUserInfo(UserHandle.of(userId)))));
mDefaultIcons.put(userId, info);
return info.newIcon(mContext);
}
@@ -249,7 +258,9 @@
// User version code O, so that the icon is always wrapped in an adaptive icon container
return bif.createBadgedIconBitmap(drawable,
- new IconOptions().setUser(UserHandle.of(userId))
+ new IconOptions()
+ .setUser(UserCache.INSTANCE.get(mContext)
+ .getUserInfo(UserHandle.of(userId)))
.setInstantApp(isInstantApp)
.setExtractedColor(0));
}
@@ -275,6 +286,7 @@
private static class TaskCacheEntry {
public Drawable icon;
public String contentDescription = "";
+ public String title = "";
}
void registerTaskVisualsChangeListener(TaskVisualsChangeListener newListener) {
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 076f4b1..312cdc9 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -34,8 +34,8 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.Flags;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
@@ -80,7 +80,7 @@
boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
boolean isTablet = activity.getDeviceProfile().isTablet;
- boolean isGridOnlyOverview = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get();
+ boolean isGridOnlyOverview = isTablet && Flags.enableGridOnlyOverview();
// Add overview actions to the menu when in in-place rotate landscape mode, or in
// grid-only overview.
if ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview) {
@@ -190,6 +190,8 @@
*/
public void endLiveTileMode(@NonNull Runnable callback) {
RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView();
+ // Task has already been dismissed
+ if (recentsView == null) return;
recentsView.switchToScreenshot(
() -> recentsView.finishRecentsAnimation(true /* toRecents */,
false /* shouldPip */, callback));
@@ -210,6 +212,8 @@
private void enterSplitSelect() {
RecentsView overviewPanel = mThumbnailView.getTaskView().getRecentsView();
+ // Task has already been dismissed
+ if (overviewPanel == null) return;
overviewPanel.initiateSplitSelect(mThumbnailView.getTaskView());
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 901690b..96e39c4 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -20,6 +20,7 @@
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.app.Activity;
import android.app.ActivityOptions;
@@ -29,7 +30,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
-import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.WindowInsets;
@@ -49,6 +50,7 @@
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
@@ -127,12 +129,12 @@
/**
* A menu item, "Save app pair", that allows the user to preserve the current app combination as
- * a single persistent icon on the Home screen, allowing for quick split screen initialization.
+ * one persistent icon on the Home screen, allowing for quick split screen launching.
*/
class SaveAppPairSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
- private final TaskView mTaskView;
+ private final GroupedTaskView mTaskView;
- public SaveAppPairSystemShortcut(BaseDraggingActivity activity, TaskView taskView) {
+ public SaveAppPairSystemShortcut(BaseDraggingActivity activity, GroupedTaskView taskView) {
super(R.drawable.ic_save_app_pair, R.string.save_app_pair, activity,
taskView.getItemInfo(), taskView);
mTaskView = taskView;
@@ -313,11 +315,12 @@
TaskIdAttributeContainer taskContainer) {
final TaskView taskView = taskContainer.getTaskView();
- if (!FeatureFlags.ENABLE_APP_PAIRS.get() || !taskView.containsMultipleTasks()) {
+ if (!FeatureFlags.enableAppPairs() || !taskView.containsMultipleTasks()) {
return null;
}
- return Collections.singletonList(new SaveAppPairSystemShortcut(activity, taskView));
+ return Collections.singletonList(
+ new SaveAppPairSystemShortcut(activity, (GroupedTaskView) taskView));
}
@Override
@@ -345,9 +348,10 @@
}
private boolean isAvailable(BaseDraggingActivity activity, int displayId) {
- return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity)
- && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false)
- && !SystemProperties.getBoolean("persist.wm.debug.desktop_mode_2", false);
+ return Settings.Global.getInt(
+ activity.getContentResolver(),
+ Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0
+ && !isDesktopModeSupported();
}
};
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 3175ba8..e5fca4b 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -15,12 +15,18 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
+
import android.content.Context;
import android.content.res.Resources;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.R;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.CancellableTask;
+import com.android.quickstep.util.TaskKeyByLastActiveTimeCache;
+import com.android.quickstep.util.TaskKeyCache;
import com.android.quickstep.util.TaskKeyLruCache;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
@@ -34,11 +40,10 @@
public class TaskThumbnailCache {
private final Executor mBgExecutor;
-
- private final int mCacheSize;
- private final TaskKeyLruCache<ThumbnailData> mCache;
+ private final TaskKeyCache<ThumbnailData> mCache;
private final HighResLoadingState mHighResLoadingState;
private final boolean mEnableTaskSnapshotPreloading;
+ private final Context mContext;
public static class HighResLoadingState {
private boolean mForceHighResThumbnails;
@@ -91,26 +96,39 @@
}
public TaskThumbnailCache(Context context, Executor bgExecutor) {
+ this(context, bgExecutor,
+ context.getResources().getInteger(R.integer.recentsThumbnailCacheSize));
+ }
+
+ private TaskThumbnailCache(Context context, Executor bgExecutor, int cacheSize) {
+ this(context, bgExecutor,
+ enableGridOnlyOverview() ? new TaskKeyByLastActiveTimeCache<>(cacheSize)
+ : new TaskKeyLruCache<>(cacheSize));
+ }
+
+ @VisibleForTesting
+ TaskThumbnailCache(Context context, Executor bgExecutor, TaskKeyCache<ThumbnailData> cache) {
mBgExecutor = bgExecutor;
mHighResLoadingState = new HighResLoadingState(context);
+ mContext = context;
Resources res = context.getResources();
- mCacheSize = res.getInteger(R.integer.recentsThumbnailCacheSize);
mEnableTaskSnapshotPreloading = res.getBoolean(R.bool.config_enableTaskSnapshotPreloading);
- mCache = new TaskKeyLruCache<>(mCacheSize);
+ mCache = cache;
}
/**
- * Synchronously fetches the thumbnail for the given {@param task} and puts it in the cache.
+ * Synchronously fetches the thumbnail for the given task at the specified resolution level, and
+ * puts it in the cache.
*/
- public void updateThumbnailInCache(Task task) {
+ public void updateThumbnailInCache(Task task, boolean lowResolution) {
if (task == null) {
return;
}
Preconditions.assertUIThread();
// Fetch the thumbnail for this task and put it in the cache
if (task.thumbnail == null) {
- updateThumbnailInBackground(task.key, true /* lowResolution */,
+ updateThumbnailInBackground(task.key, lowResolution,
t -> task.thumbnail = t);
}
}
@@ -148,6 +166,23 @@
});
}
+ /**
+ * Updates cache size and remove excess entries if current size is more than new cache size.
+ *
+ * @return whether cache size has increased
+ */
+ public boolean updateCacheSizeAndRemoveExcess() {
+ int newSize = mContext.getResources().getInteger(R.integer.recentsThumbnailCacheSize);
+ int oldSize = mCache.getMaxSize();
+ if (newSize == oldSize) {
+ // Return if no change in size
+ return false;
+ }
+
+ mCache.updateCacheSizeAndRemoveExcess(newSize);
+ return newSize > oldSize;
+ }
+
private CancellableTask updateThumbnailInBackground(TaskKey key, boolean lowResolution,
Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
@@ -169,6 +204,16 @@
@Override
public void handleResult(ThumbnailData result) {
+ // Avoid an async timing issue that a low res entry replaces an existing high res
+ // entry in high res enabled state, so we check before putting it to cache
+ if (enableGridOnlyOverview() && result.reducedResolution
+ && getHighResLoadingState().isEnabled()) {
+ ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
+ if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
+ && !cachedThumbnail.reducedResolution) {
+ return;
+ }
+ }
mCache.put(key, result);
callback.accept(result);
}
@@ -195,7 +240,7 @@
* @return The cache size.
*/
public int getCacheSize() {
- return mCacheSize;
+ return mCache.getMaxSize();
}
/**
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index af49774..3d8191d 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -38,10 +38,8 @@
import static com.android.launcher3.QuickstepTransitionManager.SPLIT_DIVIDER_ANIM_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.SPLIT_LAUNCH_DURATION;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
-import static com.android.launcher3.testing.shared.TestProtocol.LAUNCH_SPLIT_PAIR;
-import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
-import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -187,13 +185,14 @@
// Re-use existing handles
remoteTargetHandles = recentsViewHandles;
} else {
- boolean forDesktop = DESKTOP_MODE_SUPPORTED && v instanceof DesktopTaskView;
+ boolean forDesktop = isDesktopModeSupported() && v instanceof DesktopTaskView;
RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
recentsView.getSizeStrategy(), targets, forDesktop);
if (forDesktop) {
remoteTargetHandles = gluer.assignTargetsForDesktop(targets);
} else if (v.containsMultipleTasks()) {
- remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets);
+ remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets,
+ ((GroupedTaskView) v).getSplitBoundsConfig());
} else {
remoteTargetHandles = gluer.assignTargets(targets);
}
@@ -427,7 +426,6 @@
int initialTaskId, int secondTaskId, @NonNull TransitionInfo transitionInfo,
SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
if (launchingTaskView != null) {
- testLogD(LAUNCH_SPLIT_PAIR, "composeRecentsSplitLaunchAnimator taskView not-null");
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
@@ -461,7 +459,6 @@
for (int i = 0; i < transitionInfo.getChanges().size(); ++i) {
final TransitionInfo.Change change = transitionInfo.getChanges().get(i);
if (change.getTaskInfo() == null) {
- testLogD(LAUNCH_SPLIT_PAIR, "changeTaskInfo null; change: " + change);
continue;
}
final int taskId = change.getTaskInfo().taskId;
@@ -616,6 +613,42 @@
animator.start();
}
+ /**
+ * Start recents to desktop animation
+ */
+ public static void composeRecentsDesktopLaunchAnimator(
+ @NonNull DesktopTaskView launchingTaskView,
+ @NonNull StateManager stateManager, @Nullable DepthController depthController,
+ @NonNull TransitionInfo transitionInfo,
+ SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ t.apply();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishCallback.run();
+ }
+ });
+
+ final RemoteAnimationTarget[] apps = RemoteAnimationTargetCompat.wrapApps(
+ transitionInfo, t, null /* leashMap */);
+ final RemoteAnimationTarget[] wallpaper = RemoteAnimationTargetCompat.wrapNonApps(
+ transitionInfo, true /* wallpapers */, t, null /* leashMap */);
+ final RemoteAnimationTarget[] nonApps = RemoteAnimationTargetCompat.wrapNonApps(
+ transitionInfo, false /* wallpapers */, t, null /* leashMap */);
+
+ composeRecentsLaunchAnimator(animatorSet, launchingTaskView, apps, wallpaper, nonApps,
+ true /* launcherClosing */, stateManager, launchingTaskView.getRecentsView(),
+ depthController);
+
+ animatorSet.start();
+ }
+
public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
@NonNull RemoteAnimationTarget[] appTargets,
@NonNull RemoteAnimationTarget[] wallpaperTargets,
@@ -660,15 +693,17 @@
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE);
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
- windowAnimEndListener = new AnimatorListenerAdapter() {
+ windowAnimEndListener = new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
recentsView.onTaskLaunchedInLiveTileMode();
}
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
+ // This should only be run onAnimationSuccess, otherwise finishRecentsAnimation will
+ // interfere with a rapid swipe up to home in the live tile + running task case.
@Override
- public void onAnimationEnd(Animator animation) {
+ public void onAnimationSuccess(Animator animation) {
recentsView.finishRecentsAnimation(false /* toRecents */, () -> {
recentsView.post(() -> {
stateManager.moveToRestState();
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 5baf6d4..b4fe5e4 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -24,10 +24,12 @@
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
+import static com.android.launcher3.LauncherPrefs.backedUpItem;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRACKPAD_GESTURE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.quickstep.GestureState.TrackpadGestureType.getTrackpadGestureType;
@@ -60,7 +62,6 @@
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Region;
import android.graphics.drawable.Icon;
@@ -84,7 +85,9 @@
import androidx.annotation.UiThread;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.EncryptionType;
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
@@ -100,8 +103,8 @@
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.LockedUserState;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.SafeCloseable;
+import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
@@ -157,7 +160,8 @@
private static final String TAG = "TouchInteractionService";
- private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
+ private static final ConstantItem<Boolean> HAS_ENABLED_QUICKSTEP_ONCE = backedUpItem(
+ "launcher.has_enabled_quickstep_once", false, EncryptionType.ENCRYPTED);
private final TISBinder mTISBinder = new TISBinder(this);
@@ -408,18 +412,16 @@
* Sets a proxy to bypass swipe up behavior
*/
public void setSwipeUpProxy(Function<GestureState, AnimatedFloat> proxy) {
- TouchInteractionService tis = mTis.get();
- if (tis == null) return;
- tis.mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null);
+ executeForTouchInteractionService(
+ tis -> tis.mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null));
}
/**
* Sets the task id where gestures should be blocked
*/
public void setGestureBlockedTaskId(int taskId) {
- TouchInteractionService tis = mTis.get();
- if (tis == null) return;
- tis.mDeviceState.setGestureBlockingTaskId(taskId);
+ executeForTouchInteractionService(
+ tis -> tis.mDeviceState.setGestureBlockingTaskId(taskId));
}
/** Sets a listener to be run on Overview Target updates. */
@@ -433,6 +435,12 @@
mOnOverviewTargetChangeListener = null;
}
}
+
+ /** Refreshes the current overview target. */
+ public void refreshOverviewTarget() {
+ executeForTouchInteractionService(tis -> tis.onOverviewTargetChange(
+ tis.mOverviewComponentObserver.isHomeAndOverviewSame()));
+ }
}
private static boolean sConnected = false;
@@ -452,6 +460,8 @@
private final AbsSwipeUpHandler.Factory mFallbackSwipeHandlerFactory =
this::createFallbackSwipeHandler;
+ private final ScreenOnTracker.ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
+
private ActivityManagerWrapper mAM;
private OverviewCommandHelper mOverviewCommandHelper;
private OverviewComponentObserver mOverviewComponentObserver;
@@ -488,6 +498,8 @@
LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
sConnected = true;
+
+ ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
}
private void disposeEventHandlers(String reason) {
@@ -560,12 +572,11 @@
}
// Reset home bounce seen on quick step enabled for first time
- SharedPreferences sharedPrefs = LauncherPrefs.getPrefs(this);
- if (!sharedPrefs.getBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)) {
- sharedPrefs.edit()
- .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
- .putBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN, false)
- .apply();
+ LauncherPrefs prefs = LauncherPrefs.get(this);
+ if (!prefs.get(HAS_ENABLED_QUICKSTEP_ONCE)) {
+ prefs.put(
+ HAS_ENABLED_QUICKSTEP_ONCE.to(true),
+ HOME_BOUNCE_SEEN.to(false));
}
}
@@ -660,6 +671,8 @@
mTaskbarManager.destroy();
sConnected = false;
+
+ ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();
}
@@ -669,6 +682,17 @@
return mTISBinder;
}
+ protected void onScreenOnChanged(boolean isOn) {
+ if (isOn) {
+ return;
+ }
+ long currentTime = SystemClock.uptimeMillis();
+ MotionEvent cancelEvent = MotionEvent.obtain(
+ currentTime, currentTime, ACTION_CANCEL, 0f, 0f, 0);
+ onInputEvent(cancelEvent);
+ cancelEvent.recycle();
+ }
+
private void onInputEvent(InputEvent ev) {
if (!(ev instanceof MotionEvent)) {
Log.e(TAG, "Unknown event " + ev);
@@ -732,29 +756,42 @@
}
if (mUncheckedConsumer != InputConsumer.NO_OP) {
- switch (event.getActionMasked()) {
+ switch (action) {
case ACTION_DOWN:
// fall through
case ACTION_UP:
ActiveGestureLog.INSTANCE.addLog(
- /* event= */ "onMotionEvent(" + (int) event.getRawX() + ", "
- + (int) event.getRawY() + "): "
- + MotionEvent.actionToString(event.getActionMasked()) + ", "
- + MotionEvent.classificationToString(event.getClassification()),
- /* gestureEvent= */ event.getActionMasked() == ACTION_DOWN
+ new CompoundString("onMotionEvent(")
+ .append((int) event.getRawX())
+ .append(", ")
+ .append((int) event.getRawY())
+ .append("): ")
+ .append(MotionEvent.actionToString(action))
+ .append(", ")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())),
+ /* gestureEvent= */ action == ACTION_DOWN
? MOTION_DOWN
: MOTION_UP);
break;
case ACTION_MOVE:
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification())
- + ", pointerCount: " + event.getPointerCount(), MOTION_MOVE);
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification()))
+ .append(", pointerCount: ")
+ .append(event.getPointerCount()),
+ MOTION_MOVE);
break;
default: {
- ActiveGestureLog.INSTANCE.addLog("onMotionEvent: "
- + MotionEvent.actionToString(event.getActionMasked()) + ","
- + MotionEvent.classificationToString(event.getClassification()));
+ ActiveGestureLog.INSTANCE.addLog(
+ new CompoundString("onMotionEvent: ")
+ .append(MotionEvent.actionToString(action))
+ .append(",")
+ .append(MotionEvent.classificationToString(
+ event.getClassification())));
}
}
}
@@ -892,8 +929,8 @@
handleOrientationSetup(base);
}
if (mDeviceState.isFullyGesturalNavMode() || newGestureState.isTrackpadGesture()) {
- String reasonPrefix = "device is in gesture navigation mode or 3-button mode with a"
- + " trackpad gesture";
+ String reasonPrefix =
+ "device is in gesture navigation mode or 3-button mode with a trackpad gesture";
if (mDeviceState.canTriggerAssistantAction(event)) {
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
@@ -914,8 +951,8 @@
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
.append(SUBSTRING_PREFIX)
- .append("TaskbarActivityContext != null, "
- + "using TaskbarUnstashInputConsumer");
+ .append("TaskbarActivityContext != null, ")
+ .append("using TaskbarUnstashInputConsumer");
base = new TaskbarUnstashInputConsumer(this, base, mInputMonitorCompat, tac,
mOverviewCommandHelper);
}
@@ -924,9 +961,10 @@
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
.append(SUBSTRING_PREFIX)
- .append("Long press nav handle enabled, "
- + "using NavHandleLongPressInputConsumer");
- base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat);
+ .append("Long press nav handle enabled, ")
+ .append("using NavHandleLongPressInputConsumer");
+ base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat,
+ mDeviceState);
}
if (mDeviceState.isBubblesExpanded()) {
@@ -1124,8 +1162,8 @@
if ((mDeviceState.isFullyGesturalNavMode() || gestureState.isTrackpadGesture())
&& gestureState.getRunningTask() != null) {
reasonString.append(SUBSTRING_PREFIX)
- .append("device is in gesture nav mode or 3-button mode with a trackpad gesture"
- + "and running task != null")
+ .append("device is in gesture nav mode or 3-button mode with a trackpad")
+ .append(" gesture and running task != null")
.append(", using DeviceLockedInputConsumer");
return new DeviceLockedInputConsumer(
this, mDeviceState, mTaskAnimationManager, gestureState, mInputMonitorCompat);
@@ -1261,6 +1299,7 @@
Log.i(TAG, "preloadOverview: forSUWAllSet=" + forSUWAllSet
+ ", isHomeAndOverviewSame=" + mOverviewComponentObserver.isHomeAndOverviewSame());
+ ActiveGestureLog.INSTANCE.addLog("preloadRecentsAnimation");
mTaskAnimationManager.preloadRecentsAnimation(overviewIntent);
}
@@ -1335,6 +1374,7 @@
mTaskbarManager.dumpLogs("", pw);
pw.println("AssistStateManager:");
AssistStateManager.INSTANCE.get(this).dump(" ", pw);
+ SystemUiProxy.INSTANCE.get(this).dump(pw);
}
private AbsSwipeUpHandler createLauncherSwipeHandler(
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 95d88cd..95ce406 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -36,6 +36,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.util.SplitConfigurationOptions;
@@ -73,8 +74,9 @@
}
@Override
- public void init(OverviewActionsView actionsView, SplitSelectStateController splitController) {
- super.init(actionsView, splitController);
+ public void init(OverviewActionsView actionsView, SplitSelectStateController splitController,
+ @Nullable DesktopRecentsTransitionController desktopRecentsTransitionController) {
+ super.init(actionsView, splitController, desktopRecentsTransitionController);
setOverviewStateEnabled(true);
setOverlayEnabled(true);
}
@@ -252,7 +254,7 @@
setOverviewSelectEnabled(false);
}
if (finalState != OVERVIEW_SPLIT_SELECT) {
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.resetState();
} else {
resetFromSplitSelectionState();
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
index 63771f0..5557639 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
@@ -48,6 +48,14 @@
*/
protected abstract String getDelegatorName();
+ @Override
+ public <T extends InputConsumer> T getInputConsumerOfClass(Class<T> c) {
+ if (getClass().equals(c)) {
+ return c.cast(this);
+ }
+ return mDelegate.getInputConsumerOfClass(c);
+ }
+
protected void setActive(MotionEvent ev) {
ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(getDelegatorName())
.append(" became active"));
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 2a35584..1b3d759 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -68,6 +68,7 @@
*/
public class DeviceLockedInputConsumer implements InputConsumer,
RecentsAnimationCallbacks.RecentsAnimationListener, BuilderProxy {
+ private final String TAG = "DeviceLockedInputConsumer";
private static final String[] STATE_NAMES = DEBUG_STATES ? new String[2] : null;
private static int getFlagForIndex(int index, String name) {
@@ -220,7 +221,7 @@
} else if (dismissTask) {
// For now, just start the home intent so user is prompted to
// unlock the device.
- startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null);
+ startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null, TAG);
mHomeLaunched = true;
}
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
index 7a2b343..14305cf 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
@@ -46,4 +46,19 @@
public @Nullable Runnable getLongPressRunnable() {
return null;
}
+
+ /**
+ * Called when nav handle gesture starts. Returns true if long press nav handle is enabled and
+ * supported.
+ */
+ public boolean canStartTouch() {
+ return false;
+ }
+
+ /**
+ * Called when nav handle gesture is finished by the user lifting their finger or the system
+ * cancelling the touch for some other reason.
+ */
+ public void onTouchFinished() {
+ }
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index f824210..07c85bb 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -15,16 +15,19 @@
*/
package com.android.quickstep.inputconsumers;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.InputConsumer;
+import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -32,33 +35,29 @@
*/
public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
- private final GestureDetector mLongPressDetector;
private final NavHandleLongPressHandler mNavHandleLongPressHandler;
private final float mNavHandleWidth;
private final float mScreenWidth;
+ private final Runnable mTriggerLongPress = this::triggerLongPress;
+ private final float mTouchSlopSquared;
+ private final int mLongPressTimeout;
+
+ private MotionEvent mCurrentDownEvent;
+
public NavHandleLongPressInputConsumer(Context context, InputConsumer delegate,
- InputMonitorCompat inputMonitor) {
+ InputMonitorCompat inputMonitor, RecentsAnimationDeviceState deviceState) {
super(delegate, inputMonitor);
mNavHandleWidth = context.getResources().getDimensionPixelSize(
R.dimen.navigation_home_handle_width);
mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
-
+ if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
+ mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
+ } else {
+ mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
+ }
+ mTouchSlopSquared = deviceState.getSquaredTouchSlop();
mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
-
- mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() {
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- if (isInArea(motionEvent.getRawX())) {
- Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
- if (longPressRunnable != null) {
- setActive(motionEvent);
-
- MAIN_EXECUTOR.getHandler().postDelayed(longPressRunnable, 50);
- }
- }
- }
- });
}
@Override
@@ -68,13 +67,75 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- mLongPressDetector.onTouchEvent(ev);
+ if (mDelegate.allowInterceptByParent()) {
+ handleMotionEvent(ev);
+ } else if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
+ cancelLongPress();
+ }
+
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
}
}
- protected boolean isInArea(float x) {
+ private void handleMotionEvent(MotionEvent ev) {
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN -> {
+ if (mCurrentDownEvent != null) {
+ mCurrentDownEvent.recycle();
+ }
+ mCurrentDownEvent = MotionEvent.obtain(ev);
+ if (isInNavBarHorizontalArea(ev.getRawX())
+ && mNavHandleLongPressHandler.canStartTouch()) {
+ MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress,
+ mLongPressTimeout);
+ }
+ }
+ case MotionEvent.ACTION_MOVE -> {
+ if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
+ break;
+ }
+
+ float touchSlopSquared = mTouchSlopSquared;
+ float dx = ev.getX() - mCurrentDownEvent.getX();
+ float dy = ev.getY() - mCurrentDownEvent.getY();
+ double distanceSquared = (dx * dx) + (dy * dy);
+ if (distanceSquared > touchSlopSquared) {
+ cancelLongPress();
+ }
+ }
+ case MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> cancelLongPress();
+ }
+
+ // If the gesture is deep press then trigger long press asap
+ if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
+ && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS) {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
+ }
+ }
+
+ private void triggerLongPress() {
+ Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
+ if (longPressRunnable != null) {
+ OtherActivityInputConsumer oaic = getInputConsumerOfClass(
+ OtherActivityInputConsumer.class);
+ if (oaic != null) {
+ oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
+ setActive(mCurrentDownEvent);
+ } else {
+ setActive(mCurrentDownEvent);
+ MAIN_EXECUTOR.post(longPressRunnable);
+ }
+ }
+ }
+
+ private void cancelLongPress() {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ mNavHandleLongPressHandler.onTouchFinished();
+ }
+
+ private boolean isInNavBarHorizontalArea(float x) {
float areaFromMiddle = mNavHandleWidth / 2.0f;
float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 7e61167..e724547 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -40,7 +40,6 @@
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
-import android.view.ViewConfiguration;
import androidx.annotation.UiThread;
@@ -125,6 +124,9 @@
// Might be displacement in X or Y, depending on the direction we are swiping from the nav bar.
private float mStartDisplacement;
+ // The callback called upon finishing the recents transition if it was force-canceled
+ private Runnable mForceFinishRecentsTransitionCallback;
+
public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
@@ -151,7 +153,7 @@
boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
- mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
+ mTouchSlop = mDeviceState.getTouchSlop();
mSquaredTouchSlop = mDeviceState.getSquaredTouchSlop();
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
@@ -444,7 +446,7 @@
// animateToProgress so we have to manually finish here. In the case of
// ACTION_CANCEL, someone else may be doing something so finish synchronously.
mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */,
- isCanceled /* forceFinish */);
+ isCanceled /* forceFinish */, mForceFinishRecentsTransitionCallback);
} else {
// The animation hasn't started yet, so insert a replacement handler into the
// callbacks which immediately finishes the animation after it starts.
@@ -513,6 +515,14 @@
}
/**
+ * Sets a callback to be called when the recents transition is force-canceled by another input
+ * consumer being made active.
+ */
+ public void setForceFinishRecentsTransitionCallback(Runnable r) {
+ mForceFinishRecentsTransitionCallback = r;
+ }
+
+ /**
* A listener which just finishes the animation immediately after starting. Replaces
* AbsSwipeUpHandler if the gesture itself finishes before the animation even starts.
*/
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 3388642..7d3a860 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -21,7 +21,9 @@
import android.media.session.MediaSessionManager;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.Utilities;
@@ -52,6 +54,7 @@
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
private boolean mHasSetTouchModeForFirstDPadEvent;
+ private boolean mIsWaitingForAttachToWindow;
public OverviewInputConsumer(GestureState gestureState, T activity,
@Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
@@ -118,21 +121,47 @@
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (!mHasSetTouchModeForFirstDPadEvent) {
- // When Overview is launched via meta+tab or swipe up from an app, the touch
- // mode somehow is not changed to false by the Android framework. The subsequent
- // key events (e.g. DPAD_LEFT, DPAD_RIGHT) can only be dispatched to focused
- // views, while focus can only be requested in
- // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To
- // note, here we launch overview with live tile.
- mHasSetTouchModeForFirstDPadEvent = true;
- mActivity.getRootView().getViewRootImpl().touchModeChanged(false);
+ if (mHasSetTouchModeForFirstDPadEvent) {
+ break;
}
+ View viewRoot = mActivity.getRootView();
+ if (viewRoot.isAttachedToWindow()) {
+ setTouchModeChanged(viewRoot);
+ break;
+ }
+ if (mIsWaitingForAttachToWindow) {
+ break;
+ }
+ mIsWaitingForAttachToWindow = true;
+ viewRoot.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ view.removeOnAttachStateChangeListener(this);
+ mIsWaitingForAttachToWindow = false;
+ setTouchModeChanged(viewRoot);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // Do nothing
+ }
+ });
break;
default:
break;
}
mActivity.dispatchKeyEvent(ev);
}
+
+ private void setTouchModeChanged(@NonNull View viewRoot) {
+ // When Overview is launched via meta+tab or swipe up from an app, the touch
+ // mode somehow is not changed to false by the Android framework. The
+ // subsequent key events (e.g. DPAD_LEFT, DPAD_RIGHT) can only be dispatched
+ // to focused views, while focus can only be requested in
+ // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To
+ // note, here we launch overview with live tile.
+ mHasSetTouchModeForFirstDPadEvent = true;
+ viewRoot.getViewRootImpl().touchModeChanged(false);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
index b70fe8e..41730bb 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
@@ -37,6 +37,7 @@
public class OverviewWithoutFocusInputConsumer implements InputConsumer,
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
+ private static final String TAG = "OverviewWithoutFocusInputConsumer";
private final Context mContext;
private final InputMonitorCompat mInputMonitor;
@@ -77,7 +78,7 @@
@Override
public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
- startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null);
+ startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null, TAG);
BaseActivity activity = BaseDraggingActivity.fromContext(mContext);
int state = (mGestureState != null && mGestureState.getEndTarget() != null)
? mGestureState.getEndTarget().containerType
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index c9c64b6..6dcb7bc 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -53,6 +53,7 @@
public class ProgressDelegateInputConsumer implements InputConsumer,
RecentsAnimationCallbacks.RecentsAnimationListener,
SingleAxisSwipeDetector.Listener {
+ private static final String TAG = "ProgressDelegateInputConsumer";
private static final float SWIPE_DISTANCE_THRESHOLD = 0.2f;
@@ -165,7 +166,7 @@
mRecentsAnimationController.finishController(endToRecents /* toRecents */,
null /* callback */, false /* sendUserLeaveHint */);
} else if (endToRecents) {
- startHomeIntentSafely(mContext, null);
+ startHomeIntentSafely(mContext, null, TAG);
}
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
index 28ac65b..12a8bd9 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
@@ -15,11 +15,14 @@
*/
package com.android.quickstep.inputconsumers;
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
import static com.android.launcher3.Utilities.squaredHypot;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_TOUCHING;
import android.content.Context;
@@ -30,6 +33,7 @@
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.InputDevice;
import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import androidx.annotation.Nullable;
@@ -68,6 +72,9 @@
private final boolean mIsTaskbarAllAppsOpen;
private boolean mHasPassedTaskbarNavThreshold;
private boolean mIsInBubbleBarArea;
+ private boolean mIsVerticalGestureOverBubbleBar;
+ private boolean mIsPassedBubbleBarSlop;
+ private final int mTouchSlop;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
@@ -91,6 +98,7 @@
mOverviewCommandHelper = overviewCommandHelper;
// TODO(b/270395798): remove this when cleaning up old Persistent Taskbar code.
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mScreenWidth = taskbarActivityContext.getDeviceProfile().widthPx;
Resources res = context.getResources();
@@ -99,8 +107,7 @@
taskbarActivityContext.getDeviceProfile());
mTaskbarNavThresholdY = taskbarActivityContext.getDeviceProfile().heightPx
- mTaskbarNavThreshold;
- mIsTaskbarAllAppsOpen =
- mTaskbarActivityContext != null && mTaskbarActivityContext.isTaskbarAllAppsOpen();
+ mIsTaskbarAllAppsOpen = mTaskbarActivityContext.isTaskbarAllAppsOpen();
mIsTransientTaskbar = DisplayController.isTransientTaskbar(context);
@@ -132,12 +139,8 @@
if (mState != STATE_ACTIVE) {
boolean isStashedTaskbarHovered = isMouseEvent(ev)
&& isStashedTaskbarHovered((int) ev.getX(), (int) ev.getY());
- if (!isStashedTaskbarHovered) {
- mDelegate.onMotionEvent(ev);
- }
-
// Only show the transient task bar if the touch events are on the screen.
- if (mTaskbarActivityContext != null && !isTrackpadMotionEvent(ev)) {
+ if (!isTrackpadMotionEvent(ev)) {
final float x = ev.getRawX();
final float y = ev.getRawY();
switch (ev.getAction()) {
@@ -193,14 +196,28 @@
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+ float dX = mLastPos.x - mDownPos.x;
+ float dY = mLastPos.y - mDownPos.y;
+
+ if (!mIsPassedBubbleBarSlop && mIsInBubbleBarArea) {
+ boolean passedSlop =
+ Math.abs(dY) > mTouchSlop || Math.abs(dX) > mTouchSlop;
+ if (passedSlop) {
+ mIsPassedBubbleBarSlop = true;
+ mIsVerticalGestureOverBubbleBar = Math.abs(dY) > Math.abs(dX);
+ if (mIsVerticalGestureOverBubbleBar) {
+ setActive(ev);
+ }
+ }
+ }
+
if (mIsTransientTaskbar) {
- float dY = mLastPos.y - mDownPos.y;
boolean passedTaskbarNavThreshold = dY < 0
&& Math.abs(dY) >= mTaskbarNavThreshold;
if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) {
mHasPassedTaskbarNavThreshold = true;
- if (mIsInBubbleBarArea) {
+ if (mIsInBubbleBarArea && mIsVerticalGestureOverBubbleBar) {
mTaskbarActivityContext.onSwipeToOpenBubblebar();
} else {
mTaskbarActivityContext.onSwipeToUnstashTaskbar();
@@ -217,17 +234,7 @@
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (!mIsTransientTaskbar && !mCanceledUnstashHint) {
- mTaskbarActivityContext.startTaskbarUnstashHint(
- /* animateForward = */ false);
- }
- mTaskbarActivityContext.setAutohideSuspendFlag(
- FLAG_AUTOHIDE_SUSPEND_TOUCHING, false);
- if (mTransitionCallback != null) {
- mTransitionCallback.onActionEnd();
- }
- mHasPassedTaskbarNavThreshold = false;
- mIsInBubbleBarArea = false;
+ cleanupAfterMotionEvent();
break;
case MotionEvent.ACTION_BUTTON_RELEASE:
if (isStashedTaskbarHovered) {
@@ -236,9 +243,61 @@
break;
}
}
+ boolean isMovingInBubbleBarArea = mIsInBubbleBarArea && ev.getAction() == ACTION_MOVE;
+ if (!isStashedTaskbarHovered) {
+ // if we're moving in the bubble bar area but we haven't passed the slop yet, don't
+ // propagate to the delegate, until we can determine the direction of the gesture.
+ if (!isMovingInBubbleBarArea || mIsPassedBubbleBarSlop) {
+ mDelegate.onMotionEvent(ev);
+ }
+ }
+ } else if (mIsVerticalGestureOverBubbleBar) {
+ // if we get here then this gesture is a vertical swipe over the bubble bar.
+ // we're also active and there's no need to delegate any additional motion events. the
+ // rest of the gesture will be handled here.
+ switch (ev.getAction()) {
+ case ACTION_MOVE:
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == INVALID_POINTER_ID) {
+ break;
+ }
+ mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+
+ float dY = mLastPos.y - mDownPos.y;
+
+ // bubble bar swipe gesture uses the same threshold as the taskbar.
+ boolean passedTaskbarNavThreshold = dY < 0
+ && Math.abs(dY) >= mTaskbarNavThreshold;
+
+ if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) {
+ mHasPassedTaskbarNavThreshold = true;
+ mTaskbarActivityContext.onSwipeToOpenBubblebar();
+ }
+ break;
+ case ACTION_UP:
+ case ACTION_CANCEL:
+ cleanupAfterMotionEvent();
+ break;
+ }
}
}
+ private void cleanupAfterMotionEvent() {
+ if (!mIsTransientTaskbar && !mCanceledUnstashHint) {
+ mTaskbarActivityContext.startTaskbarUnstashHint(
+ /* animateForward = */ false);
+ }
+ mTaskbarActivityContext.setAutohideSuspendFlag(
+ FLAG_AUTOHIDE_SUSPEND_TOUCHING, false);
+ if (mTransitionCallback != null) {
+ mTransitionCallback.onActionEnd();
+ }
+ mHasPassedTaskbarNavThreshold = false;
+ mIsInBubbleBarArea = false;
+ mIsVerticalGestureOverBubbleBar = false;
+ mIsPassedBubbleBarSlop = false;
+ }
+
private boolean isInTaskbarArea(float x) {
float areaFromMiddle = mUnstashArea / 2.0f;
float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x);
@@ -246,13 +305,19 @@
}
private boolean isInBubbleBarArea(float x) {
- if (mTaskbarActivityContext != null && mIsTransientTaskbar) {
- BubbleControllers controllers = mTaskbarActivityContext.getBubbleControllers();
- if (controllers == null) return false;
+ if (mTaskbarActivityContext == null || !mIsTransientTaskbar) {
+ return false;
+ }
+ BubbleControllers controllers = mTaskbarActivityContext.getBubbleControllers();
+ if (controllers == null) {
+ return false;
+ }
+ if (controllers.bubbleStashController.isStashed()) {
+ return controllers.bubbleStashedHandleViewController.containsX((int) x);
+ } else {
Rect bubbleBarBounds = controllers.bubbleBarViewController.getBubbleBarBounds();
return x >= bubbleBarBounds.left && x <= bubbleBarBounds.right;
}
- return false;
}
private void onLongPressDetected(MotionEvent motionEvent) {
@@ -276,7 +341,7 @@
*/
@Override
public void onHoverEvent(MotionEvent ev) {
- if (!ENABLE_CURSOR_HOVER_STATES.get() || mTaskbarActivityContext == null
+ if (!enableCursorHoverStates() || mTaskbarActivityContext == null
|| !mTaskbarActivityContext.isTaskbarStashed()) {
return;
}
@@ -331,7 +396,7 @@
private boolean isStashedTaskbarHovered(int x, int y) {
if (!mTaskbarActivityContext.isTaskbarStashed()
|| mTaskbarActivityContext.isTaskbarAllAppsOpen()
- || !ENABLE_CURSOR_HOVER_STATES.get()) {
+ || !enableCursorHoverStates()) {
return false;
}
DeviceProfile dp = mTaskbarActivityContext.getDeviceProfile();
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 6e06f38..fce188f 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -83,6 +83,7 @@
* for the gestural system navigation.
*/
public class AllSetActivity extends Activity {
+ private static final String TAG = "AllSetActivity";
private static final String LOG_TAG = "AllSetActivity";
private static final String URI_SYSTEM_NAVIGATION_SETTING =
@@ -374,7 +375,7 @@
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == AccessibilityAction.ACTION_CLICK.getId()) {
- startHomeIntentSafely(AllSetActivity.this, null);
+ startHomeIntentSafely(AllSetActivity.this, null, TAG);
finish();
return true;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index a28cf58..69c15a5 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -84,6 +84,7 @@
private DeviceProfile mDeviceProfile;
private boolean mIsLargeScreen;
private boolean mIsFoldable;
+ private boolean mOnAttachedToWindowPendingCreate;
public static TutorialFragment newInstance(
TutorialType tutorialType, boolean gestureComplete, boolean fromTutorialMenu) {
@@ -174,6 +175,11 @@
.getDeviceProfile(getContext());
mIsLargeScreen = mDeviceProfile.isTablet;
mIsFoldable = mDeviceProfile.isTwoPanels;
+
+ if (mOnAttachedToWindowPendingCreate) {
+ mOnAttachedToWindowPendingCreate = false;
+ onAttachedToWindow();
+ }
}
public boolean isLargeScreen() {
@@ -373,6 +379,10 @@
@Override
void onAttachedToWindow() {
+ if (mEdgeBackGestureHandler == null) {
+ mOnAttachedToWindowPendingCreate = true;
+ return;
+ }
StatsLogManager statsLogManager = getStatsLogManager();
if (statsLogManager != null) {
logTutorialStepShown(statsLogManager);
@@ -382,6 +392,7 @@
@Override
void onDetachedFromWindow() {
+ mOnAttachedToWindowPendingCreate = false;
mEdgeBackGestureHandler.setViewGroupParent(null);
}
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index d3a01f2..f8d695c 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -26,7 +26,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_ENABLED;
import static com.android.launcher3.model.DeviceGridState.KEY_WORKSPACE_SIZE;
-import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE;
+import static com.android.launcher3.model.PredictionUpdateTask.LAST_PREDICTION_ENABLED;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
import static com.android.launcher3.util.Themes.KEY_THEMED_ICONS;
@@ -155,13 +155,12 @@
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (LAST_PREDICTION_ENABLED_STATE.equals(key)
+ if (LAST_PREDICTION_ENABLED.getSharedPrefKey().equals(key)
|| KEY_WORKSPACE_SIZE.equals(key)
|| KEY_THEMED_ICONS.equals(key)
|| mLoggablePrefs.containsKey(key)) {
- mHomeScreenSuggestionEvent = getDevicePrefs(mContext)
- .getBoolean(LAST_PREDICTION_ENABLED_STATE, true)
+ mHomeScreenSuggestionEvent = LauncherPrefs.get(mContext).get(LAST_PREDICTION_ENABLED)
? LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED
: LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index b1daac4..71673f3 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -224,6 +224,7 @@
private LauncherAtom.Slice mSlice;
private Optional<Integer> mCardinality = Optional.empty();
private int mInputType = SysUiStatsLog.LAUNCHER_UICHANGED__INPUT_TYPE__UNKNOWN;
+ private Optional<Integer> mFeatures = Optional.empty();
StatsCompatLogger(Context context, ActivityContext activityContext) {
mContext = context;
@@ -323,6 +324,12 @@
}
@Override
+ public StatsLogger withFeatures(int feature) {
+ this.mFeatures = Optional.of(feature);
+ return this;
+ }
+
+ @Override
public void log(EventEnum event) {
if (!Utilities.ATLEAST_R) {
return;
@@ -451,6 +458,7 @@
return;
}
int cardinality = mCardinality.orElseGet(() -> getCardinality(atomInfo));
+ int features = mFeatures.orElseGet(() -> getFeatures(atomInfo));
SysUiStatsLog.write(
SysUiStatsLog.LAUNCHER_EVENT,
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
@@ -477,7 +485,7 @@
atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */,
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
cardinality /* cardinality */,
- getFeatures(atomInfo) /* features */,
+ features /* features */,
getSearchAttributes(atomInfo) /* searchAttributes */,
getAttributes(atomInfo) /* attributes */,
inputType /* input_type */
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 8335523..ee72144 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -34,10 +34,12 @@
public enum GestureEvent {
MOTION_DOWN, MOTION_UP, MOTION_MOVE, SET_END_TARGET, SET_END_TARGET_HOME,
SET_END_TARGET_NEW_TASK, SET_END_TARGET_ALL_APPS, ON_SETTLED_ON_END_TARGET,
+ ON_START_RECENTS_ANIMATION, ON_FINISH_RECENTS_ANIMATION, ON_CANCEL_RECENTS_ANIMATION,
START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION,
SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
- FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
+ FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED, RECENT_TASKS_MISSING,
+ INVALID_VELOCITY_ON_SWIPE_UP,
/**
* These GestureEvents are specifically associated to state flags that get set in
@@ -65,16 +67,24 @@
private ActiveGestureErrorDetector() {}
+ private static final long ON_START_RECENT_ANIMATION_TIME_LIMIT = 500;
+
protected static void analyseAndDump(
@NonNull String prefix,
@NonNull PrintWriter writer,
@NonNull ActiveGestureLog.EventLog eventLog) {
writer.println(prefix + "Error messages for gesture ID: " + eventLog.logId);
+ if (!eventLog.mIsFullyGesturalNavMode) {
+ writer.println(prefix
+ + "\tSkipping gesture error detection because gesture navigation not enabled");
+ return;
+ }
boolean errorDetected = false;
// Use a Set since the order is inherently checked in the loop.
final Set<GestureEvent> encounteredEvents = new ArraySet<>();
// Set flags and check order of operations.
+ long lastStartRecentAnimationEventEntryTime = 0;
for (ActiveGestureLog.EventEntry eventEntry : eventLog.eventEntries) {
GestureEvent gestureEvent = eventEntry.getGestureEvent();
if (gestureEvent == null) {
@@ -218,12 +228,65 @@
+ "set before/without startRecentsAnimation.",
writer);
break;
+ case RECENT_TASKS_MISSING:
+ errorDetected |= printErrorIfTrue(
+ true,
+ prefix,
+ /* errorMessage= */ "SystemUiProxy.mRecentTasks missing,"
+ + " couldn't start the recents activity",
+ writer);
+ break;
+ case ON_START_RECENTS_ANIMATION:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.START_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */ "ON_START_RECENTS_ANIMATION "
+ + "onAnimationStart callback ran before startRecentsAnimation",
+ writer);
+ errorDetected |= printErrorIfTrue(
+ eventEntry.getTime() - lastStartRecentAnimationEventEntryTime
+ > ON_START_RECENT_ANIMATION_TIME_LIMIT,
+ prefix,
+ /* errorMessage= */"ON_START_RECENTS_ANIMATION "
+ + "startRecentsAnimation was never called or onAnimationStart "
+ + "callback was called more than 500 ms after "
+ + "startRecentsAnimation.",
+ writer);
+ lastStartRecentAnimationEventEntryTime = 0;
+ break;
+ case ON_CANCEL_RECENTS_ANIMATION:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.ON_START_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */ "ON_CANCEL_RECENTS_ANIMATION "
+ + "onAnimationCanceled callback ran before onAnimationStart "
+ + "callback",
+ writer);
+ break;
+ case ON_FINISH_RECENTS_ANIMATION:
+ errorDetected |= printErrorIfTrue(
+ !encounteredEvents.contains(GestureEvent.ON_START_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */ "ON_FINISH_RECENTS_ANIMATION "
+ + "onAnimationFinished callback ran before onAnimationStart "
+ + "callback",
+ writer);
+ break;
+ case INVALID_VELOCITY_ON_SWIPE_UP:
+ errorDetected |= printErrorIfTrue(
+ true,
+ prefix,
+ /* errorMessage= */ "invalid velocity on swipe up gesture.",
+ writer);
+ break;
+ case START_RECENTS_ANIMATION:
+ lastStartRecentAnimationEventEntryTime = eventEntry.getTime();
+ break;
case MOTION_DOWN:
case SET_END_TARGET:
case SET_END_TARGET_HOME:
case SET_END_TARGET_ALL_APPS:
case SET_END_TARGET_NEW_TASK:
- case START_RECENTS_ANIMATION:
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
case CANCEL_CURRENT_ANIMATION:
case FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER:
@@ -349,6 +412,30 @@
/* errorMessage= */ "onTaskAppeared was expected to be called but wasn't.",
writer);
+ errorDetected |= printErrorIfTrue(
+ /* condition= */ encounteredEvents.contains(GestureEvent.START_RECENTS_ANIMATION)
+ && !encounteredEvents.contains(GestureEvent.ON_START_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */
+ "startRecentAnimation was called but onAnimationStart callback was not",
+ writer);
+ errorDetected |= printErrorIfTrue(
+ /* condition= */
+ encounteredEvents.contains(GestureEvent.FINISH_RECENTS_ANIMATION)
+ && !encounteredEvents.contains(GestureEvent.ON_FINISH_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */
+ "finishController was called but onAnimationFinished callback was not",
+ writer);
+ errorDetected |= printErrorIfTrue(
+ /* condition= */
+ encounteredEvents.contains(GestureEvent.CANCEL_RECENTS_ANIMATION)
+ && !encounteredEvents.contains(GestureEvent.ON_CANCEL_RECENTS_ANIMATION),
+ prefix,
+ /* errorMessage= */
+ "onRecentsAnimationCanceled was called but onAnimationCanceled was not",
+ writer);
+
if (!errorDetected) {
writer.println(prefix + "\tNo errors detected.");
}
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
index cca4d52..80dd373 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
@@ -31,10 +31,12 @@
*/
public class ActiveGestureLog {
- private static final int MAX_GESTURES_TRACKED = 10;
+ private static final int MAX_GESTURES_TRACKED = 15;
public static final ActiveGestureLog INSTANCE = new ActiveGestureLog();
+ private boolean mIsFullyGesturalNavMode;
+
/**
* NOTE: This value should be kept same as
* ActivityTaskManagerService#INTENT_EXTRA_LOG_TRACE_ID in platform
@@ -46,7 +48,7 @@
private static final int TYPE_INTEGER = 2;
private static final int TYPE_BOOL_TRUE = 3;
private static final int TYPE_BOOL_FALSE = 4;
- private static final int TYPE_INPUT_CONSUMER = 5;
+ private static final int TYPE_COMPOUND_STRING = 5;
private static final int TYPE_GESTURE_EVENT = 6;
private final EventLog[] logs;
@@ -81,7 +83,13 @@
}
public void addLog(CompoundString compoundString) {
- addLog(TYPE_INPUT_CONSUMER, "", 0, compoundString, null);
+ addLog(TYPE_COMPOUND_STRING, "", 0, compoundString, null);
+ }
+
+ public void addLog(
+ CompoundString compoundString,
+ @Nullable ActiveGestureErrorDetector.GestureEvent gestureEvent) {
+ addLog(TYPE_COMPOUND_STRING, "", 0, compoundString, gestureEvent);
}
/**
@@ -121,7 +129,7 @@
@Nullable ActiveGestureErrorDetector.GestureEvent gestureEvent) {
EventLog lastEventLog = logs[(nextIndex + logs.length - 1) % logs.length];
if (lastEventLog == null || mCurrentLogId != lastEventLog.logId) {
- EventLog eventLog = new EventLog(mCurrentLogId);
+ EventLog eventLog = new EventLog(mCurrentLogId, mIsFullyGesturalNavMode);
EventEntry eventEntry = new EventEntry();
eventEntry.update(type, event, extras, compoundString, gestureEvent);
@@ -185,7 +193,7 @@
case TYPE_INTEGER:
msg.append(": ").append((int) eventEntry.extras);
break;
- case TYPE_INPUT_CONSUMER:
+ case TYPE_COMPOUND_STRING:
msg.append(eventEntry.mCompoundString);
break;
case TYPE_GESTURE_EVENT:
@@ -208,6 +216,10 @@
return mCurrentLogId++;
}
+ public void setIsFullyGesturalNavMode(boolean isFullyGesturalNavMode) {
+ mIsFullyGesturalNavMode = isFullyGesturalNavMode;
+ }
+
/** Returns the current log ID. This should be used when a log trace is being reused. */
public int getLogId() {
return mCurrentLogId;
@@ -260,6 +272,10 @@
time = System.currentTimeMillis();
duplicateCount = 0;
}
+
+ public long getTime() {
+ return time;
+ }
}
/** An entire log of entries associated with a single log ID */
@@ -267,9 +283,11 @@
protected final List<EventEntry> eventEntries = new ArrayList<>();
protected final int logId;
+ protected final boolean mIsFullyGesturalNavMode;
- private EventLog(int logId) {
+ private EventLog(int logId, boolean isFullyGesturalNavMode) {
this.logId = logId;
+ mIsFullyGesturalNavMode = isFullyGesturalNavMode;
}
}
@@ -314,6 +332,15 @@
return this;
}
+ public CompoundString append(int num) {
+ if (mIsNoOp) {
+ return this;
+ }
+ mSubstrings.add(Integer.toString(num));
+
+ return this;
+ }
+
@Override
public String toString() {
if (mIsNoOp) {
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index 1a7099d..cc3b54b 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -20,48 +20,48 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_PAIR_LAUNCH;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.isPersistentSnapPosition;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import java.util.Arrays;
/**
- * Mini controller class that handles app pair interactions: saving, modifying, deleting, etc.
+ * Controller class that handles app pair interactions: saving, modifying, deleting, etc.
+ * <br>
+ * App pairs contain two "member" apps, which are determined at the time of app pair creation
+ * and never modified. The member apps are WorkspaceItemInfos, but use the "rank" attribute
+ * differently from other ItemInfos -- we use it to store information about the split position and
+ * ratio.
*/
public class AppPairsController {
+ // Used for encoding and decoding the "rank" attribute
+ private static final int BITMASK_SIZE = 16;
+ private static final int BITMASK_FOR_SNAP_POSITION = (1 << BITMASK_SIZE) - 1;
- private static final int POINT_THREE_RATIO = 0;
- private static final int POINT_FIVE_RATIO = 1;
- private static final int POINT_SEVEN_RATIO = 2;
- /**
- * Used to calculate {@link #complement(int)}
- */
- private static final int FULL_RATIO = 2;
-
- private static final int LEFT_TOP = 0;
- private static final int RIGHT_BOTTOM = 1 << 2;
-
- // TODO (jeremysim b/274189428): Support saving different ratios in future.
- public int DEFAULT_RATIO = POINT_FIVE_RATIO;
-
- private final Context mContext;
+ private Context mContext;
private final SplitSelectStateController mSplitSelectStateController;
private final StatsLogManager mStatsLogManager;
public AppPairsController(Context context,
@@ -72,20 +72,28 @@
mStatsLogManager = statsLogManager;
}
+ void onDestroy() {
+ mContext = null;
+ }
+
/**
* Creates a new app pair ItemInfo and adds it to the workspace
*/
- public void saveAppPair(TaskView taskView) {
- TaskView.TaskIdAttributeContainer[] attributes = taskView.getTaskIdAttributeContainers();
+ public void saveAppPair(GroupedTaskView gtv) {
+ TaskView.TaskIdAttributeContainer[] attributes = gtv.getTaskIdAttributeContainers();
WorkspaceItemInfo app1 = attributes[0].getItemInfo().clone();
WorkspaceItemInfo app2 = attributes[1].getItemInfo().clone();
app1.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
app2.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
- app1.rank = DEFAULT_RATIO + LEFT_TOP;
- app2.rank = complement(DEFAULT_RATIO) + RIGHT_BOTTOM;
+
+ @PersistentSnapPosition int snapPosition = gtv.getSnapPosition();
+ if (!isPersistentSnapPosition(snapPosition)) {
+ throw new RuntimeException("tried to save an app pair with illegal snapPosition");
+ }
+
+ app1.rank = encodeRank(SPLIT_POSITION_TOP_OR_LEFT, snapPosition);
+ app2.rank = encodeRank(SPLIT_POSITION_BOTTOM_OR_RIGHT, snapPosition);
FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2);
- // TODO (jeremysim b/274189428): Generate default title here.
- newAppPair.title = "App pair 1";
IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache();
MODEL_EXECUTOR.execute(() -> {
@@ -94,6 +102,8 @@
member.bitmap = iconCache.getDefaultIcon(newAppPair.user);
iconCache.getTitleAndIcon(member, member.usingLowResIcon());
});
+ newAppPair.title = getDefaultTitle(newAppPair.contents.get(0).title,
+ newAppPair.contents.get(1).title);
MAIN_EXECUTOR.execute(() -> {
LauncherAccessibilityDelegate delegate =
Launcher.getLauncher(mContext).getAccessibilityDelegate();
@@ -128,7 +138,7 @@
}
mSplitSelectStateController.setInitialTaskSelect(task1Intent,
- SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
+ AppPairsController.convertRankToStagePosition(app1.rank),
app1,
LAUNCHER_APP_PAIR_LAUNCH,
task1Id);
@@ -141,18 +151,42 @@
app2.intent, app2.user);
}
- mSplitSelectStateController.launchSplitTasks();
+ mSplitSelectStateController.launchSplitTasks(
+ AppPairsController.convertRankToSnapPosition(app1.rank));
});
}
/**
- * Used to calculate the "opposite" side of the split ratio, so we can know how big the split
- * apps are supposed to be. This math works because POINT_THREE_RATIO is internally represented
- * by 0, POINT_FIVE_RATIO is represented by 1, and POINT_SEVEN_RATIO is represented by 2. There
- * are no other supported ratios for now.
+ * App pair members have a "rank" attribute that contains information about the split position
+ * and ratio. We implement this by splitting the int in half (e.g. 16 bits each), then use one
+ * half to store splitPosition (left vs right) and the other half to store snapPosition
+ * (30-70 split vs 50-50 split)
*/
- private int complement(int ratio1) {
- int ratio2 = FULL_RATIO - ratio1;
- return ratio2;
+ @VisibleForTesting
+ public int encodeRank(int splitPosition, int snapPosition) {
+ return (splitPosition << BITMASK_SIZE) + snapPosition;
+ }
+
+ /**
+ * Returns the desired stage position for the app pair to be launched in (decoded from the
+ * "rank" integer).
+ */
+ public static int convertRankToStagePosition(int rank) {
+ return rank >> BITMASK_SIZE;
+ }
+
+ /**
+ * Returns the desired split ratio for the app pair to be launched in (decoded from the "rank"
+ * integer).
+ */
+ public static int convertRankToSnapPosition(int rank) {
+ return rank & BITMASK_FOR_SNAP_POSITION;
+ }
+
+ /**
+ * Returns a formatted default title for the app pair.
+ */
+ public String getDefaultTitle(CharSequence app1, CharSequence app2) {
+ return mContext.getString(R.string.app_pair_default_title, app1, app2);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
index 0dee5b3..cda87c0 100644
--- a/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
+++ b/quickstep/src/com/android/quickstep/util/AsyncClockEventDelegate.java
@@ -32,6 +32,8 @@
import androidx.annotation.WorkerThread;
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SettingsCache.OnChangeListener;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -42,7 +44,11 @@
/**
* Extension of {@link ClockEventDelegate} to support async event registration
*/
-public class AsyncClockEventDelegate extends ClockEventDelegate implements OnChangeListener {
+public class AsyncClockEventDelegate extends ClockEventDelegate
+ implements OnChangeListener, SafeCloseable {
+
+ public static final MainThreadInitializedObject<AsyncClockEventDelegate> INSTANCE =
+ new MainThreadInitializedObject<>(AsyncClockEventDelegate::new);
private final Context mContext;
private final SimpleBroadcastReceiver mReceiver =
@@ -55,7 +61,7 @@
private boolean mFormatRegistered = false;
private boolean mDestroyed = false;
- public AsyncClockEventDelegate(Context context) {
+ private AsyncClockEventDelegate(Context context) {
super(context);
mContext = context;
@@ -79,6 +85,9 @@
@Override
public void registerFormatChangeObserver(ContentObserver observer, int userHandle) {
+ if (mDestroyed) {
+ return;
+ }
synchronized (mFormatObservers) {
if (!mFormatRegistered && !mDestroyed) {
SettingsCache.INSTANCE.get(mContext).register(mFormatUri, this);
@@ -114,10 +123,8 @@
}
}
- /**
- * Unregisters all system callbacks and destroys this delegate
- */
- public void onDestroy() {
+ @Override
+ public void close() {
mDestroyed = true;
SettingsCache.INSTANCE.get(mContext).unregister(mFormatUri, this);
UI_HELPER_EXECUTOR.execute(() -> mReceiver.unregisterReceiverSafely(mContext));
diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.java b/quickstep/src/com/android/quickstep/util/BorderAnimator.java
deleted file mode 100644
index 7563187..0000000
--- a/quickstep/src/com/android/quickstep/util/BorderAnimator.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.util;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.annotation.ColorInt;
-import android.annotation.Nullable;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.animation.Interpolator;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Px;
-
-import com.android.app.animation.Interpolators;
-import com.android.launcher3.anim.AnimatedFloat;
-import com.android.launcher3.anim.AnimatorListeners;
-
-/**
- * Utility class for drawing a rounded-rect border around a view.
- * <p>
- * To use this class:
- * 1. Create an instance in the target view. NOTE: The border will animate outwards from the
- * provided border bounds. See {@link SimpleParams} and {@link ScalingParams} to determine
- * which would be best for your target view.
- * 2. Override the target view's {@link android.view.View#draw(Canvas)} method and call
- * {@link BorderAnimator#drawBorder(Canvas)} after {@code super.draw(canvas)}.
- * 3. Call {@link BorderAnimator#buildAnimator(boolean)} and start the animation or call
- * {@link BorderAnimator#setBorderVisible(boolean)} where appropriate.
- */
-public final class BorderAnimator {
-
- public static final int DEFAULT_BORDER_COLOR = Color.WHITE;
-
- private static final long DEFAULT_APPEARANCE_ANIMATION_DURATION_MS = 300;
- private static final long DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS = 133;
- private static final Interpolator DEFAULT_INTERPOLATOR = Interpolators.EMPHASIZED_DECELERATE;
-
- @NonNull private final AnimatedFloat mBorderAnimationProgress = new AnimatedFloat(
- this::updateOutline);
- @Px private final int mBorderRadiusPx;
- @NonNull private final BorderAnimationParams mBorderAnimationParams;
- private final long mAppearanceDurationMs;
- private final long mDisappearanceDurationMs;
- @NonNull private final Interpolator mInterpolator;
- @NonNull private final Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- @Nullable private Animator mRunningBorderAnimation;
-
- public BorderAnimator(
- @Px int borderRadiusPx,
- @ColorInt int borderColor,
- @NonNull BorderAnimationParams borderAnimationParams) {
- this(borderRadiusPx,
- borderColor,
- borderAnimationParams,
- DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
- DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS,
- DEFAULT_INTERPOLATOR);
- }
-
- /**
- * @param borderRadiusPx the radius of the border's corners, in pixels
- * @param borderColor the border's color
- * @param borderAnimationParams params for handling different target view layout situation.
- * @param appearanceDurationMs appearance animation duration, in milliseconds
- * @param disappearanceDurationMs disappearance animation duration, in milliseconds
- * @param interpolator animation interpolator
- */
- public BorderAnimator(
- @Px int borderRadiusPx,
- @ColorInt int borderColor,
- @NonNull BorderAnimationParams borderAnimationParams,
- long appearanceDurationMs,
- long disappearanceDurationMs,
- @NonNull Interpolator interpolator) {
- mBorderRadiusPx = borderRadiusPx;
- mBorderAnimationParams = borderAnimationParams;
- mAppearanceDurationMs = appearanceDurationMs;
- mDisappearanceDurationMs = disappearanceDurationMs;
- mInterpolator = interpolator;
-
- mBorderPaint.setColor(borderColor);
- mBorderPaint.setStyle(Paint.Style.STROKE);
- mBorderPaint.setAlpha(0);
- }
-
- private void updateOutline() {
- float interpolatedProgress = mInterpolator.getInterpolation(
- mBorderAnimationProgress.value);
-
- mBorderAnimationParams.setProgress(interpolatedProgress);
- mBorderPaint.setAlpha(Math.round(255 * interpolatedProgress));
- mBorderPaint.setStrokeWidth(mBorderAnimationParams.getBorderWidth());
- mBorderAnimationParams.mTargetView.invalidate();
- }
-
- /**
- * Draws the border on the given canvas.
- * <p>
- * Call this method in the target view's {@link android.view.View#draw(Canvas)} method after
- * calling super.
- */
- public void drawBorder(Canvas canvas) {
- float alignmentAdjustment = mBorderAnimationParams.getAlignmentAdjustment();
- canvas.drawRoundRect(
- /* left= */ mBorderAnimationParams.mBorderBounds.left + alignmentAdjustment,
- /* top= */ mBorderAnimationParams.mBorderBounds.top + alignmentAdjustment,
- /* right= */ mBorderAnimationParams.mBorderBounds.right - alignmentAdjustment,
- /* bottom= */ mBorderAnimationParams.mBorderBounds.bottom - alignmentAdjustment,
- /* rx= */ mBorderRadiusPx + mBorderAnimationParams.getRadiusAdjustment(),
- /* ry= */ mBorderRadiusPx + mBorderAnimationParams.getRadiusAdjustment(),
- /* paint= */ mBorderPaint);
- }
-
- /**
- * Builds the border appearance/disappearance animation.
- */
- @NonNull
- public Animator buildAnimator(boolean isAppearing) {
- mRunningBorderAnimation = mBorderAnimationProgress.animateToValue(isAppearing ? 1f : 0f);
- mRunningBorderAnimation.setDuration(
- isAppearing ? mAppearanceDurationMs : mDisappearanceDurationMs);
-
- mRunningBorderAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mBorderAnimationParams.onShowBorder();
- }
- });
- mRunningBorderAnimation.addListener(
- AnimatorListeners.forEndCallback(() -> {
- mRunningBorderAnimation = null;
- if (isAppearing) {
- return;
- }
- mBorderAnimationParams.onHideBorder();
- }));
-
- return mRunningBorderAnimation;
- }
-
- /**
- * Immediately shows/hides the border without an animation.
- * <p>
- * To animate the appearance/disappearance, see {@link BorderAnimator#buildAnimator(boolean)}
- */
- public void setBorderVisible(boolean visible) {
- if (mRunningBorderAnimation != null) {
- mRunningBorderAnimation.end();
- }
- if (visible) {
- mBorderAnimationParams.onShowBorder();
- }
- mBorderAnimationProgress.updateValue(visible ? 1f : 0f);
- if (!visible) {
- mBorderAnimationParams.onHideBorder();
- }
- }
-
- /**
- * Callback to update the border bounds when building this animation.
- */
- public interface BorderBoundsBuilder {
-
- /**
- * Sets the given rect to the most up-to-date bounds.
- */
- void updateBorderBounds(Rect rect);
- }
-
- /**
- * Params for handling different target view layout situation.
- */
- private abstract static class BorderAnimationParams {
-
- @NonNull private final Rect mBorderBounds = new Rect();
- @NonNull private final BorderBoundsBuilder mBoundsBuilder;
-
- @NonNull final View mTargetView;
- @Px final int mBorderWidthPx;
-
- private float mAnimationProgress = 0f;
- @Nullable private View.OnLayoutChangeListener mLayoutChangeListener;
-
- /**
- * @param borderWidthPx the width of the border, in pixels
- * @param boundsBuilder callback to update the border bounds
- * @param targetView the view that will be drawing the border
- */
- private BorderAnimationParams(
- @Px int borderWidthPx,
- @NonNull BorderBoundsBuilder boundsBuilder,
- @NonNull View targetView) {
- mBorderWidthPx = borderWidthPx;
- mBoundsBuilder = boundsBuilder;
- mTargetView = targetView;
- }
-
- private void setProgress(float progress) {
- mAnimationProgress = progress;
- }
-
- private float getBorderWidth() {
- return mBorderWidthPx * mAnimationProgress;
- }
-
- float getAlignmentAdjustment() {
- // Outset the border by half the width to create an outwards-growth animation
- return (-getBorderWidth() / 2f) + getAlignmentAdjustmentInset();
- }
-
-
- void onShowBorder() {
- if (mLayoutChangeListener == null) {
- mLayoutChangeListener =
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
- onShowBorder();
- mTargetView.invalidate();
- };
- mTargetView.addOnLayoutChangeListener(mLayoutChangeListener);
- }
- mBoundsBuilder.updateBorderBounds(mBorderBounds);
- }
-
- void onHideBorder() {
- if (mLayoutChangeListener != null) {
- mTargetView.removeOnLayoutChangeListener(mLayoutChangeListener);
- mLayoutChangeListener = null;
- }
- }
-
- abstract int getAlignmentAdjustmentInset();
-
- abstract float getRadiusAdjustment();
- }
-
- /**
- * Use an instance of this {@link BorderAnimationParams} if the border can be drawn outside the
- * target view's bounds without any additional logic.
- */
- public static final class SimpleParams extends BorderAnimationParams {
-
- public SimpleParams(
- @Px int borderWidthPx,
- @NonNull BorderBoundsBuilder boundsBuilder,
- @NonNull View targetView) {
- super(borderWidthPx, boundsBuilder, targetView);
- }
-
- @Override
- int getAlignmentAdjustmentInset() {
- return 0;
- }
-
- @Override
- float getRadiusAdjustment() {
- return -getAlignmentAdjustment();
- }
- }
-
- /**
- * Use an instance of this {@link BorderAnimationParams} if the border would other be clipped by
- * the target view's bound.
- * <p>
- * Note: using these params will set the scales and pivots of the
- * container and content views, however will only reset the scales back to 1.
- */
- public static final class ScalingParams extends BorderAnimationParams {
-
- @NonNull private final View mContentView;
-
- /**
- * @param targetView the view that will be drawing the border. this view will be scaled up
- * to make room for the border
- * @param contentView the view around which the border will be drawn. this view will be
- * scaled down reciprocally to keep its original size and location.
- */
- public ScalingParams(
- @Px int borderWidthPx,
- @NonNull BorderBoundsBuilder boundsBuilder,
- @NonNull View targetView,
- @NonNull View contentView) {
- super(borderWidthPx, boundsBuilder, targetView);
- mContentView = contentView;
- }
-
- @Override
- void onShowBorder() {
- super.onShowBorder();
- float width = mTargetView.getWidth();
- float height = mTargetView.getHeight();
- // Scale up just enough to make room for the border. Fail fast and fix the scaling
- // onLayout.
- float scaleX = width == 0 ? 1f : 1f + ((2 * mBorderWidthPx) / width);
- float scaleY = height == 0 ? 1f : 1f + ((2 * mBorderWidthPx) / height);
-
- mTargetView.setPivotX(width / 2);
- mTargetView.setPivotY(height / 2);
- mTargetView.setScaleX(scaleX);
- mTargetView.setScaleY(scaleY);
-
- mContentView.setPivotX(mContentView.getWidth() / 2f);
- mContentView.setPivotY(mContentView.getHeight() / 2f);
- mContentView.setScaleX(1f / scaleX);
- mContentView.setScaleY(1f / scaleY);
- }
-
- @Override
- void onHideBorder() {
- super.onHideBorder();
- mTargetView.setPivotX(mTargetView.getWidth());
- mTargetView.setPivotY(mTargetView.getHeight());
- mTargetView.setScaleX(1f);
- mTargetView.setScaleY(1f);
-
- mContentView.setPivotX(mContentView.getWidth() / 2f);
- mContentView.setPivotY(mContentView.getHeight() / 2f);
- mContentView.setScaleX(1f);
- mContentView.setScaleY(1f);
- }
-
- @Override
- int getAlignmentAdjustmentInset() {
- // Inset the border since we are scaling the container up
- return mBorderWidthPx;
- }
-
- @Override
- float getRadiusAdjustment() {
- // Increase the radius since we are scaling the container up
- return getAlignmentAdjustment();
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.kt b/quickstep/src/com/android/quickstep/util/BorderAnimator.kt
new file mode 100644
index 0000000..44eb070
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/BorderAnimator.kt
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util
+
+import android.animation.Animator
+import android.annotation.ColorInt
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Rect
+import android.view.View
+import android.view.View.OnLayoutChangeListener
+import android.view.animation.Interpolator
+import androidx.annotation.Px
+import androidx.core.animation.doOnEnd
+import androidx.core.animation.doOnStart
+import com.android.app.animation.Interpolators
+import com.android.launcher3.anim.AnimatedFloat
+import kotlin.math.roundToInt
+
+/**
+ * Utility class for drawing a rounded-rect border around a view.
+ *
+ * To use this class:
+ * 1. Create an instance in the target view. NOTE: The border will animate outwards from the
+ * provided border bounds.
+ * 2. Override the target view's [View.draw] method and call [drawBorder] after
+ * `super.draw(canvas)`.
+ * 3. Call [buildAnimator] and start the animation or call [setBorderVisibility] where appropriate.
+ */
+class BorderAnimator
+private constructor(
+ @field:Px @param:Px private val borderRadiusPx: Int,
+ @ColorInt borderColor: Int,
+ private val borderAnimationParams: BorderAnimationParams,
+ private val appearanceDurationMs: Long,
+ private val disappearanceDurationMs: Long,
+ private val interpolator: Interpolator,
+) {
+ private val borderAnimationProgress = AnimatedFloat { updateOutline() }
+ private val borderPaint =
+ Paint(Paint.ANTI_ALIAS_FLAG).apply {
+ color = borderColor
+ style = Paint.Style.STROKE
+ alpha = 0
+ }
+ private var runningBorderAnimation: Animator? = null
+
+ companion object {
+ const val DEFAULT_BORDER_COLOR = Color.WHITE
+ private const val DEFAULT_APPEARANCE_ANIMATION_DURATION_MS = 300L
+ private const val DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS = 133L
+ private val DEFAULT_INTERPOLATOR = Interpolators.EMPHASIZED_DECELERATE
+
+ /**
+ * Creates a BorderAnimator that simply draws the border outside the bound of the target
+ * view.
+ *
+ * Use this method if the border can be drawn outside the target view's bounds without any
+ * additional logic.
+ *
+ * @param borderRadiusPx the radius of the border's corners, in pixels
+ * @param borderWidthPx the width of the border, in pixels
+ * @param boundsBuilder callback to update the border bounds
+ * @param targetView the view that will be drawing the border
+ * @param borderColor the border's color
+ * @param appearanceDurationMs appearance animation duration, in milliseconds
+ * @param disappearanceDurationMs disappearance animation duration, in milliseconds
+ * @param interpolator animation interpolator
+ */
+ @JvmOverloads
+ @JvmStatic
+ fun createSimpleBorderAnimator(
+ @Px borderRadiusPx: Int,
+ @Px borderWidthPx: Int,
+ boundsBuilder: (rect: Rect?) -> Unit,
+ targetView: View,
+ @ColorInt borderColor: Int = DEFAULT_BORDER_COLOR,
+ appearanceDurationMs: Long = DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
+ disappearanceDurationMs: Long = DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS,
+ interpolator: Interpolator = DEFAULT_INTERPOLATOR,
+ ): BorderAnimator {
+ return BorderAnimator(
+ borderRadiusPx,
+ borderColor,
+ SimpleParams(borderWidthPx, boundsBuilder, targetView),
+ appearanceDurationMs,
+ disappearanceDurationMs,
+ interpolator,
+ )
+ }
+
+ /**
+ * Creates a BorderAnimator that scales the target and content views to draw the border
+ * within the target's bounds without obscuring the content.
+ *
+ * Use this method if the border would otherwise be clipped by the target view's bound.
+ *
+ * Note: using this method will set the scales and pivots of the container and content
+ * views, however will only reset the scales back to 1.
+ *
+ * @param borderRadiusPx the radius of the border's corners, in pixels
+ * @param borderWidthPx the width of the border, in pixels
+ * @param boundsBuilder callback to update the border bounds
+ * @param targetView the view that will be drawing the border
+ * @param contentView the view around which the border will be drawn. this view will be
+ * scaled down reciprocally to keep its original size and location.
+ * @param borderColor the border's color
+ * @param appearanceDurationMs appearance animation duration, in milliseconds
+ * @param disappearanceDurationMs disappearance animation duration, in milliseconds
+ * @param interpolator animation interpolator
+ */
+ @JvmOverloads
+ @JvmStatic
+ fun createScalingBorderAnimator(
+ @Px borderRadiusPx: Int,
+ @Px borderWidthPx: Int,
+ boundsBuilder: (rect: Rect?) -> Unit,
+ targetView: View,
+ contentView: View,
+ @ColorInt borderColor: Int = DEFAULT_BORDER_COLOR,
+ appearanceDurationMs: Long = DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
+ disappearanceDurationMs: Long = DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS,
+ interpolator: Interpolator = DEFAULT_INTERPOLATOR,
+ ): BorderAnimator {
+ return BorderAnimator(
+ borderRadiusPx,
+ borderColor,
+ ScalingParams(borderWidthPx, boundsBuilder, targetView, contentView),
+ appearanceDurationMs,
+ disappearanceDurationMs,
+ interpolator,
+ )
+ }
+ }
+
+ private fun updateOutline() {
+ val interpolatedProgress = interpolator.getInterpolation(borderAnimationProgress.value)
+ borderAnimationParams.animationProgress = interpolatedProgress
+ borderPaint.alpha = (255 * interpolatedProgress).roundToInt()
+ borderPaint.strokeWidth = borderAnimationParams.borderWidth
+ borderAnimationParams.targetView.invalidate()
+ }
+
+ /**
+ * Draws the border on the given canvas.
+ *
+ * Call this method in the target view's [View.draw] method after calling super.
+ */
+ fun drawBorder(canvas: Canvas) {
+ with(borderAnimationParams) {
+ val radius = borderRadiusPx + radiusAdjustment
+ canvas.drawRoundRect(
+ /* left= */ borderBounds.left + alignmentAdjustment,
+ /* top= */ borderBounds.top + alignmentAdjustment,
+ /* right= */ borderBounds.right - alignmentAdjustment,
+ /* bottom= */ borderBounds.bottom - alignmentAdjustment,
+ /* rx= */ radius,
+ /* ry= */ radius,
+ /* paint= */ borderPaint
+ )
+ }
+ }
+
+ /** Builds the border appearance/disappearance animation. */
+ fun buildAnimator(isAppearing: Boolean): Animator {
+ return borderAnimationProgress.animateToValue(if (isAppearing) 1f else 0f).apply {
+ duration = if (isAppearing) appearanceDurationMs else disappearanceDurationMs
+ doOnStart {
+ runningBorderAnimation?.cancel()
+ runningBorderAnimation = this
+ borderAnimationParams.onShowBorder()
+ }
+ doOnEnd {
+ runningBorderAnimation = null
+ if (!isAppearing) {
+ borderAnimationParams.onHideBorder()
+ }
+ }
+ }
+ }
+
+ /** Shows/hides the border, optionally with an animation. */
+ fun setBorderVisibility(visible: Boolean, animated: Boolean) {
+ if (animated) {
+ buildAnimator(visible).start()
+ return
+ }
+ runningBorderAnimation?.end()
+ if (visible) {
+ borderAnimationParams.onShowBorder()
+ }
+ borderAnimationProgress.updateValue(if (visible) 1f else 0f)
+ if (!visible) {
+ borderAnimationParams.onHideBorder()
+ }
+ }
+
+ /** Params for handling different target view layout situations. */
+ private abstract class BorderAnimationParams(
+ @field:Px @param:Px val borderWidthPx: Int,
+ private val boundsBuilder: (rect: Rect) -> Unit,
+ val targetView: View,
+ ) {
+ val borderBounds = Rect()
+ var animationProgress = 0f
+ private var layoutChangeListener: OnLayoutChangeListener? = null
+
+ abstract val alignmentAdjustmentInset: Int
+ abstract val radiusAdjustment: Float
+
+ val borderWidth: Float
+ get() = borderWidthPx * animationProgress
+ val alignmentAdjustment: Float
+ // Outset the border by half the width to create an outwards-growth animation
+ get() = -borderWidth / 2f + alignmentAdjustmentInset
+
+ open fun onShowBorder() {
+ if (layoutChangeListener == null) {
+ layoutChangeListener = OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
+ onShowBorder()
+ targetView.invalidate()
+ }
+ targetView.addOnLayoutChangeListener(layoutChangeListener)
+ }
+ boundsBuilder(borderBounds)
+ }
+
+ open fun onHideBorder() {
+ if (layoutChangeListener != null) {
+ targetView.removeOnLayoutChangeListener(layoutChangeListener)
+ layoutChangeListener = null
+ }
+ }
+ }
+
+ /** BorderAnimationParams that simply draws the border outside the bounds of the target view. */
+ private class SimpleParams(
+ @Px borderWidthPx: Int,
+ boundsBuilder: (rect: Rect?) -> Unit,
+ targetView: View,
+ ) : BorderAnimationParams(borderWidthPx, boundsBuilder, targetView) {
+ override val alignmentAdjustmentInset = 0
+ override val radiusAdjustment: Float
+ get() = -alignmentAdjustment
+ }
+
+ /**
+ * BorderAnimationParams that scales the target and content views to draw the border within the
+ * target's bounds without obscuring the content.
+ */
+ private class ScalingParams(
+ @Px borderWidthPx: Int,
+ boundsBuilder: (rect: Rect?) -> Unit,
+ targetView: View,
+ private val contentView: View,
+ ) : BorderAnimationParams(borderWidthPx, boundsBuilder, targetView) {
+ // Inset the border since we are scaling the container up
+ override val alignmentAdjustmentInset = borderWidthPx
+ override val radiusAdjustment: Float
+ // Increase the radius since we are scaling the container up
+ get() = alignmentAdjustment
+
+ override fun onShowBorder() {
+ super.onShowBorder()
+ val tvWidth = targetView.width.toFloat()
+ val tvHeight = targetView.height.toFloat()
+ // Scale up just enough to make room for the border. Fail fast and fix the scaling
+ // onLayout.
+ val newScaleX = if (tvWidth == 0f) 1f else 1f + 2 * borderWidthPx / tvWidth
+ val newScaleY = if (tvHeight == 0f) 1f else 1f + 2 * borderWidthPx / tvHeight
+ with(targetView) {
+ pivotX = width / 2f
+ pivotY = height / 2f
+ scaleX = newScaleX
+ scaleY = newScaleY
+ }
+ with(contentView) {
+ pivotX = width / 2f
+ pivotY = height / 2f
+ scaleX = 1f / newScaleX
+ scaleY = 1f / newScaleY
+ }
+ }
+
+ override fun onHideBorder() {
+ super.onHideBorder()
+ with(targetView) {
+ pivotX = width.toFloat()
+ pivotY = height.toFloat()
+ scaleX = 1f
+ scaleY = 1f
+ }
+ with(contentView) {
+ pivotX = width / 2f
+ pivotY = height / 2f
+ scaleX = 1f
+ scaleY = 1f
+ }
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt b/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
index 59ff81d..5cce728 100644
--- a/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
+++ b/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
@@ -83,4 +83,7 @@
Executors.MAIN_EXECUTOR.execute { anim.start() }
}
+
+ override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index e0b5272..61ba5ac 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -35,6 +35,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.HorizontalInsettableView;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.unfold.LauncherJankMonitorTransitionProgressListener;
import com.android.quickstep.util.unfold.PreemptiveUnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
@@ -91,6 +92,8 @@
}
unfoldTransitionProgressProvider.addCallback(mExternalTransitionStatusProvider);
+ unfoldTransitionProgressProvider.addCallback(
+ new LauncherJankMonitorTransitionProgressListener(launcher::getRootView));
mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher,
windowManager, rotationChangeProvider);
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index 4bc41bc..a8a96ce 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.util;
+import static com.android.launcher3.testing.shared.TestProtocol.PAUSE_DETECTED_MESSAGE;
+
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
@@ -201,7 +203,8 @@
ActiveGestureLog.INSTANCE.addLog(logString);
boolean isFirstDetectedPause = !mHasEverBeenPaused && mIsPaused;
if (mIsPaused) {
- AccessibilityManagerCompat.sendPauseDetectedEventToTest(mContext);
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(mContext,
+ PAUSE_DETECTED_MESSAGE);
mHasEverBeenPaused = true;
}
if (mOnMotionPauseListener != null) {
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index ef7d7a9..9df568e 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -22,9 +22,12 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
+import static com.android.launcher3.util.OnboardingPrefs.HOTSEAT_DISCOVERY_TIP_COUNT;
-import android.content.SharedPreferences;
-
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
@@ -34,30 +37,30 @@
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.quickstep.views.AllAppsEduView;
/**
- * Extends {@link OnboardingPrefs} for quickstep-specific onboarding data.
+ * Class to setup onboarding behavior for quickstep launcher
*/
-public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher> {
+public class QuickstepOnboardingPrefs {
- public QuickstepOnboardingPrefs(QuickstepLauncher launcher, SharedPreferences sharedPrefs) {
- super(launcher, sharedPrefs);
-
+ /**
+ * Sets up the initial onboarding behavior for the launcher
+ */
+ public static void setup(QuickstepLauncher launcher) {
StateManager<LauncherState> stateManager = launcher.getStateManager();
- if (!getBoolean(HOME_BOUNCE_SEEN)) {
+ if (!HOME_BOUNCE_SEEN.get(launcher)) {
stateManager.addStateListener(new StateListener<LauncherState>() {
@Override
public void onStateTransitionComplete(LauncherState finalState) {
boolean swipeUpEnabled =
- DisplayController.getNavigationMode(mLauncher).hasGestures;
+ DisplayController.getNavigationMode(launcher).hasGestures;
LauncherState prevState = stateManager.getLastState();
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
&& finalState == ALL_APPS && prevState == NORMAL) ||
- hasReachedMaxCount(HOME_BOUNCE_COUNT))) {
- mSharedPrefs.edit().putBoolean(HOME_BOUNCE_SEEN, true).apply();
+ HOME_BOUNCE_COUNT.hasReachedMax(launcher))) {
+ LauncherPrefs.get(launcher).put(HOME_BOUNCE_SEEN, true);
stateManager.removeStateListener(this);
}
}
@@ -65,21 +68,21 @@
}
if (!Utilities.isRunningInTestHarness()
- && !hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
+ && !HOTSEAT_DISCOVERY_TIP_COUNT.hasReachedMax(launcher)) {
stateManager.addStateListener(new StateListener<LauncherState>() {
boolean mFromAllApps = false;
@Override
public void onStateTransitionStart(LauncherState toState) {
- mFromAllApps = mLauncher.getStateManager().getCurrentStableState() == ALL_APPS;
+ mFromAllApps = launcher.getStateManager().getCurrentStableState() == ALL_APPS;
}
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- HotseatPredictionController client = mLauncher.getHotseatPredictionController();
+ HotseatPredictionController client = launcher.getHotseatPredictionController();
if (mFromAllApps && finalState == NORMAL && client.hasPredictions()) {
- if (!mLauncher.getDeviceProfile().isTablet
- && incrementEventCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
+ if (!launcher.getDeviceProfile().isTablet
+ && HOTSEAT_DISCOVERY_TIP_COUNT.increment(launcher)) {
client.showEdu();
stateManager.removeStateListener(this);
}
@@ -109,7 +112,7 @@
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == NORMAL) {
if (mCount >= MAX_NUM_SWIPES_TO_TRIGGER_EDU) {
- if (getOpenView(mLauncher, TYPE_ALL_APPS_EDU) == null) {
+ if (getOpenView(launcher, TYPE_ALL_APPS_EDU) == null) {
AllAppsEduView.show(launcher);
}
mCount = 0;
@@ -124,7 +127,7 @@
}
if (finalState == ALL_APPS) {
- AllAppsEduView view = getOpenView(mLauncher, TYPE_ALL_APPS_EDU);
+ AllAppsEduView view = getOpenView(launcher, TYPE_ALL_APPS_EDU);
if (view != null) {
view.close(false);
}
@@ -133,20 +136,20 @@
});
}
- if (!hasReachedMaxCount(ALL_APPS_VISITED_COUNT)) {
- mLauncher.getStateManager().addStateListener(new StateListener<LauncherState>() {
+ if (!ALL_APPS_VISITED_COUNT.hasReachedMax(launcher)) {
+ launcher.getStateManager().addStateListener(new StateListener<LauncherState>() {
@Override
public void onStateTransitionComplete(LauncherState finalState) {
if (finalState == ALL_APPS) {
- incrementEventCount(ALL_APPS_VISITED_COUNT);
+ ALL_APPS_VISITED_COUNT.increment(launcher);
return;
}
- boolean hasReachedMaxCount = hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
- mLauncher.getAppsView().getFloatingHeaderView().findFixedRowByType(
+ boolean hasReachedMaxCount = ALL_APPS_VISITED_COUNT.hasReachedMax(launcher);
+ launcher.getAppsView().getFloatingHeaderView().findFixedRowByType(
AppsDividerView.class).setShowAllAppsLabel(!hasReachedMaxCount);
if (hasReachedMaxCount) {
- mLauncher.getStateManager().removeStateListener(this);
+ launcher.getStateManager().removeStateListener(this);
}
}
});
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index c3774eb..6ee65d4 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -30,16 +30,18 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.Utilities
import com.android.launcher3.anim.PendingAnimation
+import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.statemanager.StatefulActivity
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
import com.android.launcher3.views.BaseDragLayer
import com.android.quickstep.views.FloatingTaskView
-import com.android.quickstep.views.IconView
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.SplitInstructionsView
import com.android.quickstep.views.TaskThumbnailView
import com.android.quickstep.views.TaskView
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
+import com.android.quickstep.views.TaskViewIcon
+import java.util.Optional
import java.util.function.Supplier
/**
@@ -82,7 +84,7 @@
return SplitAnimInitProps(container.thumbnailView,
container.thumbnailView.thumbnail, drawable!!,
fadeWithThumbnail = true, isStagedTask = true,
- iconView = container.iconView
+ iconView = container.iconView.asView()
)
}
}
@@ -94,7 +96,7 @@
val drawable = getDrawable(taskView.iconView, splitSelectSource)
return SplitAnimInitProps(taskView.thumbnail, taskView.thumbnail.thumbnail,
drawable!!, fadeWithThumbnail = true, isStagedTask = true,
- taskView.iconView
+ taskView.iconView.asView()
)
}
}
@@ -105,7 +107,7 @@
* TaskView's icon drawable can be null if the TaskView is scrolled far enough off screen
* @return [Drawable]
*/
- fun getDrawable(iconView: IconView, splitSelectSource: SplitSelectSource?) : Drawable? {
+ fun getDrawable(iconView: TaskViewIcon, splitSelectSource: SplitSelectSource?) : Drawable? {
if (iconView.drawable == null && splitSelectSource != null) {
return splitSelectSource.drawable
}
@@ -129,7 +131,7 @@
taskViewWidth: Int, taskViewHeight: Int,
isPrimaryTaskSplitting: Boolean) {
val thumbnail = taskIdAttributeContainer.thumbnailView
- val iconView: View = taskIdAttributeContainer.iconView
+ val iconView: View = taskIdAttributeContainer.iconView.asView()
builder.add(ObjectAnimator.ofFloat(thumbnail, TaskThumbnailView.SPLASH_ALPHA, 1f))
thumbnail.setShowSplashForSplitSelection(true)
if (deviceProfile.isLandscape) {
@@ -270,6 +272,45 @@
safeRemoveViewFromDragLayer(launcher, splitSelectStateController.splitInstructionsView)
}
+ /**
+ * Animates the first placeholder view to fullscreen and launches its task.
+ * TODO(b/276361926): Remove the [resetCallback] option once contextual launches
+ */
+ fun playAnimPlaceholderToFullscreen(launcher: StatefulActivity<*>, view: View,
+ resetCallback: Optional<Runnable>) {
+ val stagedTaskView = view as FloatingTaskView
+
+ val isTablet: Boolean = launcher.deviceProfile.isTablet
+ val duration = if (isTablet) SplitAnimationTimings.TABLET_CONFIRM_DURATION else
+ SplitAnimationTimings.PHONE_CONFIRM_DURATION
+ val pendingAnimation = PendingAnimation(duration.toLong())
+ val firstTaskStartingBounds = Rect()
+ val firstTaskEndingBounds = Rect()
+
+ stagedTaskView.getBoundsOnScreen(firstTaskStartingBounds)
+ launcher.dragLayer.getBoundsOnScreen(firstTaskEndingBounds)
+ splitSelectStateController.setLaunchingFirstAppFullscreen()
+
+ stagedTaskView.addConfirmAnimation(
+ pendingAnimation,
+ RectF(firstTaskStartingBounds),
+ firstTaskEndingBounds,
+ false /* fadeWithThumbnail */,
+ true /* isStagedTask */)
+
+ pendingAnimation.addEndListener {
+ splitSelectStateController.launchInitialAppFullscreen {
+ if (FeatureFlags.enableSplitContextually()) {
+ splitSelectStateController.resetState()
+ } else if (resetCallback.isPresent) {
+ resetCallback.get().run()
+ }
+ }
+ }
+
+ pendingAnimation.buildAnim().start()
+ }
+
private fun safeRemoveViewFromDragLayer(launcher: StatefulActivity<*>, view: View?) {
if (view != null) {
launcher.dragLayer.removeView(view)
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt
new file mode 100644
index 0000000..596bb47
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenUtils.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.util
+
+import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.wm.shell.util.SplitBounds
+
+class SplitScreenUtils {
+ companion object {
+ // TODO(b/254378592): Remove these methods when the two classes are reunited
+ /** Converts the shell version of SplitBounds to the launcher version */
+ @JvmStatic
+ fun convertShellSplitBoundsToLauncher(
+ shellSplitBounds: SplitBounds?
+ ): SplitConfigurationOptions.SplitBounds? {
+ return if (shellSplitBounds == null) {
+ null
+ } else {
+ SplitConfigurationOptions.SplitBounds(
+ shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds,
+ shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId,
+ shellSplitBounds.snapPosition
+ )
+ }
+ }
+
+ /** Converts the launcher version of SplitBounds to the shell version */
+ @JvmStatic
+ fun convertLauncherSplitBoundsToShell(
+ launcherSplitBounds: SplitConfigurationOptions.SplitBounds?
+ ): SplitBounds? {
+ return if (launcherSplitBounds == null) {
+ null
+ } else {
+ SplitBounds(
+ launcherSplitBounds.leftTopBounds,
+ launcherSplitBounds.rightBottomBounds,
+ launcherSplitBounds.leftTopTaskId,
+ launcherSplitBounds.rightBottomTaskId,
+ launcherSplitBounds.snapPosition
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
index 69c4197..423ba43 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectDataHolder.kt
@@ -54,7 +54,7 @@
* state
*/
class SplitSelectDataHolder(
- val context: Context
+ var context: Context?
) {
val TAG = SplitSelectDataHolder::class.simpleName
@@ -100,6 +100,10 @@
private var initialShortcut: ShortcutInfo? = null
private var secondShortcut: ShortcutInfo? = null
+ fun onDestroy() {
+ context = null
+ }
+
/**
* @param alreadyRunningTask if set to [android.app.ActivityTaskManager.INVALID_TASK_ID]
* then @param intent will be used to launch the initial task
@@ -164,18 +168,15 @@
}
private fun getShortcutInfo(intent: Intent?, user: UserHandle?): ShortcutInfo? {
- val intentPackage = intent?.getPackage()
- if (intentPackage == null) {
- return null
- }
+ val intentPackage = intent?.getPackage() ?: return null
val shortcutId = intent.getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID)
?: return null
try {
val context: Context =
if (user != null) {
- context.createPackageContextAsUser(intentPackage, 0 /* flags */, user)
+ context!!.createPackageContextAsUser(intentPackage, 0 /* flags */, user)
} else {
- context.createPackageContext(intentPackage, 0 /* *flags */)
+ context!!.createPackageContext(intentPackage, 0 /* *flags */)
}
return ShortcutInfo.Builder(context, shortcutId).build()
} catch (e: PackageManager.NameNotFoundException) {
@@ -368,7 +369,8 @@
}
private fun isInitialTaskIntentSet(): Boolean {
- return initialTaskId != INVALID_TASK_ID || initialIntent != null
+ return initialTaskId != INVALID_TASK_ID || initialIntent != null ||
+ initialPendingIntent != null
}
fun getInitialTaskId(): Int {
@@ -404,6 +406,7 @@
secondUser = null
initialIntent = null
secondIntent = null
+ initialPendingIntent = null
secondPendingIntent = null
itemInfo = null
splitEvent = null
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index d4ddf76..145707b 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -17,14 +17,10 @@
package com.android.quickstep.util;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DESKTOP_MODE_SPLIT_LEFT_TOP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DESKTOP_MODE_SPLIT_RIGHT_BOTTOM;
-import static com.android.launcher3.testing.shared.TestProtocol.LAUNCH_SPLIT_PAIR;
-import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_PENDINGINTENT;
import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_PENDINGINTENT_TASK;
@@ -35,15 +31,17 @@
import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_PENDINGINTENT;
import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_SHORTCUT;
import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_TASK;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
+import android.annotation.UiThread;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
@@ -78,8 +76,10 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.util.BackPressHandler;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.quickstep.OverviewComponentObserver;
@@ -94,11 +94,12 @@
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.GroupedTaskView;
-import com.android.quickstep.views.SplitInstructionsView;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.SplitInstructionsView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import com.android.wm.shell.splitscreen.ISplitSelectListener;
import java.io.PrintWriter;
@@ -114,9 +115,11 @@
public class SplitSelectStateController {
private static final String TAG = "SplitSelectStateCtor";
- private Context mContext;
+ private StatefulActivity mContext;
private final Handler mHandler;
private final RecentsModel mRecentTasksModel;
+ @Nullable
+ private Runnable mActivityBackCallback;
private final SplitAnimationController mSplitAnimationController;
private final AppPairsController mAppPairsController;
private final SplitSelectDataHolder mSplitSelectDataHolder;
@@ -138,14 +141,35 @@
@Nullable
private GroupedTaskView mLaunchingTaskView;
+ /** True when the first selected split app is being launched in fullscreen. */
+ private boolean mLaunchingFirstAppFullscreen;
+
private FloatingTaskView mFirstFloatingTaskView;
private SplitInstructionsView mSplitInstructionsView;
private final List<SplitSelectionListener> mSplitSelectionListeners = new ArrayList<>();
- public SplitSelectStateController(Context context, Handler handler, StateManager stateManager,
- DepthController depthController, StatsLogManager statsLogManager,
- SystemUiProxy systemUiProxy, RecentsModel recentsModel) {
+ private final BackPressHandler mSplitBackHandler = new BackPressHandler() {
+ @Override
+ public boolean canHandleBack() {
+ return FeatureFlags.enableSplitContextually() && isSplitSelectActive();
+ }
+
+ @Override
+ public void onBackInvoked() {
+ // When exiting from split selection, leave current context to go to
+ // homescreen as well
+ getSplitAnimationController().playPlaceholderDismissAnim(mContext);
+ if (mActivityBackCallback != null) {
+ mActivityBackCallback.run();
+ }
+ }
+ };
+
+ public SplitSelectStateController(StatefulActivity context, Handler handler,
+ StateManager stateManager, DepthController depthController,
+ StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel,
+ Runnable activityBackCallback) {
mContext = context;
mHandler = handler;
mStatsLogManager = statsLogManager;
@@ -153,6 +177,7 @@
mStateManager = stateManager;
mDepthController = depthController;
mRecentTasksModel = recentsModel;
+ mActivityBackCallback = activityBackCallback;
mSplitAnimationController = new SplitAnimationController(this);
mAppPairsController = new AppPairsController(context, this, statsLogManager);
mSplitSelectDataHolder = new SplitSelectDataHolder(mContext);
@@ -160,6 +185,9 @@
public void onDestroy() {
mContext = null;
+ mActivityBackCallback = null;
+ mAppPairsController.onDestroy();
+ mSplitSelectDataHolder.onDestroy();
}
/**
@@ -267,11 +295,11 @@
* To be called when the both split tasks are ready to be launched. Call after launcher side
* animations are complete.
*/
- public void launchSplitTasks(@Nullable Consumer<Boolean> callback) {
+ public void launchSplitTasks(@PersistentSnapPosition int snapPosition,
+ @Nullable Consumer<Boolean> callback) {
Pair<InstanceId, com.android.launcher3.logging.InstanceId> instanceIds =
LogUtils.getShellShareableInstanceId();
- launchTasks(callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO,
- instanceIds.first);
+ launchTasks(callback, false /* freezeTaskList */, snapPosition, instanceIds.first);
mStatsLogManager.logger()
.withItemInfo(mSplitSelectDataHolder.getItemInfo())
@@ -280,11 +308,26 @@
}
/**
- * A version of {@link #launchTasks(Consumer, boolean, float, InstanceId)} with no success
+ * A version of {@link #launchTasks(Consumer, boolean, int, InstanceId)} with no success
* callback.
*/
+ public void launchSplitTasks(@PersistentSnapPosition int snapPosition) {
+ launchSplitTasks(snapPosition, /* callback */ null);
+ }
+
+ /**
+ * A version of {@link #launchSplitTasks(int, Consumer)} that launches with default split ratio.
+ */
+ public void launchSplitTasks(@Nullable Consumer<Boolean> callback) {
+ launchSplitTasks(SNAP_TO_50_50, callback);
+ }
+
+ /**
+ * A version of {@link #launchSplitTasks(int, Consumer)} that launches with a default split
+ * ratio and no callback.
+ */
public void launchSplitTasks() {
- launchSplitTasks(null);
+ launchSplitTasks(SNAP_TO_50_50, null);
}
/**
@@ -321,7 +364,7 @@
* foreground (quickswitch, launching previous pairs from overview)
*/
public void launchTasks(@Nullable Consumer<Boolean> callback, boolean freezeTaskList,
- float splitRatio, @Nullable InstanceId shellInstanceId) {
+ @PersistentSnapPosition int snapPosition, @Nullable InstanceId shellInstanceId) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "launchSplitTasks");
final ActivityOptions options1 = ActivityOptions.makeBasic();
@@ -348,33 +391,33 @@
switch (launchData.getSplitLaunchType()) {
case SPLIT_TASK_TASK ->
mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId,
- null /* options2 */, initialStagePosition, splitRatio,
+ null /* options2 */, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
case SPLIT_TASK_PENDINGINTENT ->
mSystemUiProxy.startIntentAndTask(secondPI, secondUserId, optionsBundle,
- firstTaskId, null /*options2*/, initialStagePosition, splitRatio,
+ firstTaskId, null /*options2*/, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
case SPLIT_TASK_SHORTCUT ->
mSystemUiProxy.startShortcutAndTask(secondShortcut, optionsBundle,
- firstTaskId, null /*options2*/, initialStagePosition, splitRatio,
+ firstTaskId, null /*options2*/, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
case SPLIT_PENDINGINTENT_TASK ->
mSystemUiProxy.startIntentAndTask(firstPI, firstUserId, optionsBundle,
- secondTaskId, null /*options2*/, initialStagePosition, splitRatio,
+ secondTaskId, null /*options2*/, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
case SPLIT_PENDINGINTENT_PENDINGINTENT ->
mSystemUiProxy.startIntents(firstPI, firstUserId, firstShortcut,
optionsBundle, secondPI, secondUserId, secondShortcut,
- null /*options2*/, initialStagePosition, splitRatio,
+ null /*options2*/, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
case SPLIT_SHORTCUT_TASK ->
mSystemUiProxy.startShortcutAndTask(firstShortcut, optionsBundle,
- secondTaskId, null /*options2*/, initialStagePosition, splitRatio,
+ secondTaskId, null /*options2*/, initialStagePosition, snapPosition,
remoteTransition, shellInstanceId);
}
} else {
@@ -384,40 +427,40 @@
case SPLIT_TASK_TASK ->
mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle,
secondTaskId, null /* options2 */, initialStagePosition,
- splitRatio, adapter, shellInstanceId);
+ snapPosition, adapter, shellInstanceId);
case SPLIT_TASK_PENDINGINTENT ->
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(secondPI,
secondUserId, optionsBundle, firstTaskId, null /*options2*/,
- initialStagePosition, splitRatio, adapter, shellInstanceId);
+ initialStagePosition, snapPosition, adapter, shellInstanceId);
case SPLIT_TASK_SHORTCUT ->
mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(secondShortcut,
optionsBundle, firstTaskId, null /*options2*/, initialStagePosition,
- splitRatio, adapter, shellInstanceId);
+ snapPosition, adapter, shellInstanceId);
case SPLIT_PENDINGINTENT_TASK ->
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId,
optionsBundle, secondTaskId, null /*options2*/,
- initialStagePosition, splitRatio, adapter, shellInstanceId);
+ initialStagePosition, snapPosition, adapter, shellInstanceId);
case SPLIT_PENDINGINTENT_PENDINGINTENT ->
mSystemUiProxy.startIntentsWithLegacyTransition(firstPI, firstUserId,
firstShortcut, optionsBundle, secondPI, secondUserId,
- secondShortcut, null /*options2*/, initialStagePosition, splitRatio,
- adapter, shellInstanceId);
+ secondShortcut, null /*options2*/, initialStagePosition,
+ snapPosition, adapter, shellInstanceId);
case SPLIT_SHORTCUT_TASK ->
mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(firstShortcut,
optionsBundle, secondTaskId, null /*options2*/,
- initialStagePosition, splitRatio, adapter, shellInstanceId);
+ initialStagePosition, snapPosition, adapter, shellInstanceId);
}
}
}
/**
* Used to launch split screen from a split pair that already exists (usually accessible through
- * Overview). This is different than {@link #launchTasks(Consumer, boolean, float, InstanceId)}
+ * Overview). This is different than {@link #launchTasks(Consumer, boolean, int, InstanceId)}
* in that this only launches split screen that are existing tasks. This doesn't determine which
* API should be used (i.e. launching split with existing tasks vs intents vs shortcuts, etc).
*
@@ -426,7 +469,8 @@
*/
public void launchExistingSplitPair(@Nullable GroupedTaskView groupedTaskView,
int firstTaskId, int secondTaskId, @StagePosition int stagePosition,
- Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
+ Consumer<Boolean> callback, boolean freezeTaskList,
+ @PersistentSnapPosition int snapPosition) {
mLaunchingTaskView = groupedTaskView;
final ActivityOptions options1 = ActivityOptions.makeBasic();
if (freezeTaskList) {
@@ -437,21 +481,20 @@
if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
final RemoteTransition remoteTransition = getShellRemoteTransition(firstTaskId,
secondTaskId, callback, "LaunchExistingPair");
- mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId,
- null /* options2 */, stagePosition, splitRatio,
- remoteTransition, null /*shellInstanceId*/);
+ mSystemUiProxy.startTasks(firstTaskId, optionsBundle, secondTaskId, null /* options2 */,
+ stagePosition, snapPosition, remoteTransition, null /*shellInstanceId*/);
} else {
final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId,
secondTaskId, callback);
- mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle,
- secondTaskId, null /* options2 */, stagePosition,
- splitRatio, adapter, null /*shellInstanceId*/);
+ mSystemUiProxy.startTasksWithLegacyTransition(firstTaskId, optionsBundle, secondTaskId,
+ null /* options2 */, stagePosition, snapPosition, adapter,
+ null /*shellInstanceId*/);
}
}
/**
* Launches the initially selected task/intent in fullscreen (note the same SystemUi APIs are
- * used as {@link #launchSplitTasks(Consumer)} because they are overloaded to launch both
+ * used as {@link #launchSplitTasks(int, Consumer)} because they are overloaded to launch both
* split and fullscreen tasks)
*/
public void launchInitialAppFullscreen(Consumer<Boolean> callback) {
@@ -476,14 +519,13 @@
switch (launchData.getSplitLaunchType()) {
case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasks(firstTaskId,
optionsBundle, secondTaskId, null /* options2 */, initialStagePosition,
- DEFAULT_SPLIT_RATIO, remoteTransition, instanceId);
+ SNAP_TO_50_50, remoteTransition, instanceId);
case SPLIT_SINGLE_INTENT_FULLSCREEN -> mSystemUiProxy.startIntentAndTask(firstPI,
firstUserId, optionsBundle, secondTaskId, null /*options2*/,
- initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition,
- instanceId);
+ initialStagePosition, SNAP_TO_50_50, remoteTransition, instanceId);
case SPLIT_SINGLE_SHORTCUT_FULLSCREEN -> mSystemUiProxy.startShortcutAndTask(
initialShortcut, optionsBundle, firstTaskId, null /* options2 */,
- initialStagePosition, DEFAULT_SPLIT_RATIO, remoteTransition, instanceId);
+ initialStagePosition, SNAP_TO_50_50, remoteTransition, instanceId);
}
} else {
final RemoteAnimationAdapter adapter = getLegacyRemoteAdapter(firstTaskId,
@@ -491,16 +533,15 @@
switch (launchData.getSplitLaunchType()) {
case SPLIT_SINGLE_TASK_FULLSCREEN -> mSystemUiProxy.startTasksWithLegacyTransition(
firstTaskId, optionsBundle, secondTaskId, null /* options2 */,
- initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId);
+ initialStagePosition, SNAP_TO_50_50, adapter, instanceId);
case SPLIT_SINGLE_INTENT_FULLSCREEN ->
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(firstPI, firstUserId,
optionsBundle, secondTaskId, null /*options2*/,
- initialStagePosition, DEFAULT_SPLIT_RATIO, adapter,
- instanceId);
+ initialStagePosition, SNAP_TO_50_50, adapter, instanceId);
case SPLIT_SINGLE_SHORTCUT_FULLSCREEN ->
mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(
initialShortcut, optionsBundle, firstTaskId, null /* options2 */,
- initialStagePosition, DEFAULT_SPLIT_RATIO, adapter, instanceId);
+ initialStagePosition, SNAP_TO_50_50, adapter, instanceId);
}
}
}
@@ -564,20 +605,19 @@
private final int mInitialTaskId;
private final int mSecondTaskId;
- private final Consumer<Boolean> mSuccessCallback;
+ private Consumer<Boolean> mFinishCallback;
RemoteSplitLaunchTransitionRunner(int initialTaskId, int secondTaskId,
@Nullable Consumer<Boolean> callback) {
mInitialTaskId = initialTaskId;
mSecondTaskId = secondTaskId;
- mSuccessCallback = callback;
+ mFinishCallback = callback;
}
@Override
public void startAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t,
IRemoteTransitionFinishedCallback finishedCallback) {
- testLogD(LAUNCH_SPLIT_PAIR, "Received split startAnimation");
final Runnable finishAdapter = () -> {
try {
finishedCallback.onTransitionFinished(null /* wct */, null /* sct */);
@@ -590,10 +630,7 @@
TaskViewUtils.composeRecentsSplitLaunchAnimator(mLaunchingTaskView, mStateManager,
mDepthController, mInitialTaskId, mSecondTaskId, info, t, () -> {
finishAdapter.run();
- if (mSuccessCallback != null) {
- mSuccessCallback.accept(true);
- }
- resetState();
+ cleanup(true /*success*/);
});
});
}
@@ -602,6 +639,27 @@
public void mergeAnimation(IBinder transition, TransitionInfo info,
SurfaceControl.Transaction t, IBinder mergeTarget,
IRemoteTransitionFinishedCallback finishedCallback) { }
+
+ @Override
+ public void onTransitionConsumed(IBinder transition, boolean aborted)
+ throws RemoteException {
+ MAIN_EXECUTOR.execute(() -> {
+ cleanup(false /*success*/);
+ });
+ }
+
+ /**
+ * Must be called on UI thread.
+ * @param success if launching the split apps occurred successfully or not
+ */
+ @UiThread
+ private void cleanup(boolean success) {
+ if (mFinishCallback != null) {
+ mFinishCallback.accept(success);
+ mFinishCallback = null;
+ }
+ resetState();
+ }
}
/**
@@ -652,7 +710,7 @@
/**
* To be called whenever we exit split selection state. If
- * {@link FeatureFlags#ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE} is set, this should be the
+ * {@link FeatureFlags#enableSplitContextually()} is set, this should be the
* central way split is getting reset, which should then go through the callbacks to reset
* other state.
*/
@@ -665,6 +723,7 @@
mDismissingFromSplitPair = false;
mFirstFloatingTaskView = null;
mSplitInstructionsView = null;
+ mLaunchingFirstAppFullscreen = false;
}
/**
@@ -683,6 +742,10 @@
return mSplitSelectDataHolder.isBothSplitAppsConfirmed();
}
+ public boolean isLaunchingFirstAppFullscreen() {
+ return mLaunchingFirstAppFullscreen;
+ }
+
public int getInitialTaskId() {
return mSplitSelectDataHolder.getInitialTaskId();
}
@@ -691,6 +754,9 @@
return mSplitSelectDataHolder.getSecondTaskId();
}
+ public void setLaunchingFirstAppFullscreen() {
+ mLaunchingFirstAppFullscreen = true;
+ }
public void setFirstFloatingTaskView(FloatingTaskView floatingTaskView) {
mFirstFloatingTaskView = floatingTaskView;
}
@@ -713,6 +779,10 @@
return mAppPairsController;
}
+ public BackPressHandler getSplitBackHandler() {
+ return mSplitBackHandler;
+ }
+
public void dump(String prefix, PrintWriter writer) {
if (mSplitSelectDataHolder != null) {
mSplitSelectDataHolder.dump(prefix, writer);
@@ -744,7 +814,7 @@
@Override
public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
- if (!ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE.get()) return false;
+ if (!isDesktopModeSupported()) return false;
MAIN_EXECUTOR.execute(() -> enterSplitSelect(taskInfo, splitPosition,
taskBounds));
return true;
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index 056f9aa..3748a24 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -16,9 +16,9 @@
package com.android.quickstep.util;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -30,15 +30,20 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.quickstep.views.FloatingTaskView;
import com.android.quickstep.views.RecentsView;
@@ -52,12 +57,13 @@
private final SplitSelectStateController mController;
private final int mHalfDividerSize;
+ private final IconCache mIconCache;
public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) {
mLauncher = launcher;
mDP = mLauncher.getDeviceProfile();
mController = controller;
-
+ mIconCache = LauncherAppState.getInstanceNoCreate().getIconCache();
mHalfDividerSize = mLauncher.getResources().getDimensionPixelSize(
R.dimen.multi_window_task_divider_size) / 2;
}
@@ -74,17 +80,24 @@
return false;
}
- // Convert original widgetView into bitmap to use for animation
- // TODO(b/276361926) get the icon for this widget via PackageManager?
int width = view.getWidth();
int height = view.getHeight();
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- view.draw(canvas);
+ MODEL_EXECUTOR.execute(() -> {
+ PackageItemInfo infoInOut = new PackageItemInfo(pendingIntent.getCreatorPackage(),
+ pendingIntent.getCreatorUserHandle());
+ mIconCache.getTitleAndIconForApp(infoInOut, false);
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mController.setSecondTask(pendingIntent);
+ view.post(() -> {
+ mController.setSecondTask(pendingIntent);
+ // Convert original widgetView into bitmap to use for animation
+ Canvas canvas = new Canvas(bitmap);
+ view.draw(canvas);
+ startWorkspaceAnimation(view, bitmap,
+ new BitmapDrawable(mLauncher.getResources(), infoInOut.bitmap.icon));
+ });
+ });
- startWorkspaceAnimation(view, bitmap, null /*icon*/);
return true;
}
@@ -179,8 +192,8 @@
private boolean shouldIgnoreSecondSplitLaunch() {
return (!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get()
- && !ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()
- && !ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE.get())
+ && !FeatureFlags.enableSplitContextually()
+ && !isDesktopModeSupported())
|| !mController.isSplitSelectActive();
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index bb028a7..df5765c 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -25,6 +25,8 @@
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewRootImpl;
+import androidx.annotation.NonNull;
+
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
/**
@@ -48,7 +50,7 @@
/**
* @param targetView The view in the surface that acts as synchronization anchor.
*/
- public SurfaceTransactionApplier(View targetView) {
+ public SurfaceTransactionApplier(@NonNull View targetView) {
if (targetView.isAttachedToWindow()) {
initialize(targetView);
} else {
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index 7cc2c46..fce38e1 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -145,6 +145,12 @@
sourceRectHint = null;
}
+ if (sourceRectHint != null && !appBounds.contains(sourceRectHint)) {
+ // This is a situation in which the source hint rect is outside the app bounds, so it is
+ // not a valid rectangle to use for cropping app surface
+ sourceRectHint = null;
+ }
+
if (sourceRectHint == null) {
mSourceRectHint.setEmpty();
mSourceHintRectInsets = null;
diff --git a/quickstep/src/com/android/quickstep/util/SystemActionConstants.java b/quickstep/src/com/android/quickstep/util/SystemActionConstants.java
new file mode 100644
index 0000000..522930f
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/SystemActionConstants.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.util;
+
+/**
+ * Constants for registering SystemActions.
+ *
+ * Prefer to use AccessibilityService.GLOBAL_ACTION_* if applicable.
+ */
+public final class SystemActionConstants {
+
+ public static final int SYSTEM_ACTION_ID_TASKBAR = 499;
+ public static final int SYSTEM_ACTION_ID_SEARCH_SCREEN = 500;
+
+ /**
+ * For Taskbar broadcast intent filter.
+ */
+ public static final String ACTION_SHOW_TASKBAR = "ACTION_SHOW_TASKBAR";
+
+ /**
+ * For Search Screen broadcast intent filter.
+ */
+ public static final String ACTION_SEARCH_SCREEN = "ACTION_SEARCH_SCREEN";
+
+ private SystemActionConstants() {}
+}
diff --git a/quickstep/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCache.java b/quickstep/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCache.java
new file mode 100644
index 0000000..79ca076
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCache.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.shared.recents.model.Task;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+
+/**
+ * A class to cache task id and its corresponding object (e.g. thumbnail)
+ *
+ * <p>Maximum size of the cache should be provided when creating this class. When the number of
+ * entries is larger than its max size, it would remove the entry with the smallest last active time
+ * @param <V> Type of object stored in the cache
+ */
+public class TaskKeyByLastActiveTimeCache<V> implements TaskKeyCache<V> {
+ private static final String TAG = TaskKeyByLastActiveTimeCache.class.getSimpleName();
+ private final AtomicInteger mMaxSize;
+ private final Map<Integer, Entry<V>> mMap;
+ // To sort task id by last active time
+ private final PriorityQueue<Task.TaskKey> mQueue;
+
+ public TaskKeyByLastActiveTimeCache(int maxSize) {
+ mMap = new HashMap(maxSize);
+ mQueue = new PriorityQueue<>(Comparator.comparingLong(t -> t.lastActiveTime));
+ mMaxSize = new AtomicInteger(maxSize);
+ }
+
+ /**
+ * Removes all entries from the cache
+ */
+ @Override
+ public synchronized void evictAll() {
+ mMap.clear();
+ mQueue.clear();
+ }
+
+
+ /**
+ * Removes a particular entry from the cache
+ */
+ @Override
+ public synchronized void remove(Task.TaskKey key) {
+ if (key == null) {
+ return;
+ }
+
+ Entry<V> entry = mMap.remove(key.id);
+ if (entry != null) {
+ // Use real key in map entry to handle use case of using stub key for removal
+ mQueue.remove(entry.mKey);
+ }
+ }
+
+ /**
+ * Removes all entries matching keyCheck
+ */
+ @Override
+ public synchronized void removeAll(Predicate<Task.TaskKey> keyCheck) {
+ Iterator<Task.TaskKey> iterator = mQueue.iterator();
+ while (iterator.hasNext()) {
+ Task.TaskKey key = iterator.next();
+ if (keyCheck.test(key)) {
+ mMap.remove(key.id);
+ iterator.remove();
+ }
+ }
+ }
+
+ /**
+ * Gets the entry if it is still valid
+ */
+ @Override
+ public synchronized V getAndInvalidateIfModified(Task.TaskKey key) {
+ Entry<V> entry = mMap.get(key.id);
+ if (entry != null && entry.mKey.windowingMode == key.windowingMode
+ && entry.mKey.lastActiveTime == key.lastActiveTime) {
+ return entry.mValue;
+ } else {
+ remove(key);
+ return null;
+ }
+ }
+
+ /**
+ * Adds an entry to the cache, optionally evicting the last accessed entry
+ */
+ @Override
+ public final synchronized void put(Task.TaskKey key, V value) {
+ if (key != null && value != null) {
+ Entry<V> entry = mMap.get(key.id);
+ // If the same key already exist, remove item for existing key
+ if (entry != null) {
+ mQueue.remove(entry.mKey);
+ }
+
+ mMap.put(key.id, new Entry<>(key, value));
+ mQueue.add(key);
+ removeExcessIfNeeded();
+ } else {
+ Log.e(TAG, "Unexpected null key or value: " + key + ", " + value);
+ }
+ }
+
+ /**
+ * Updates the cache entry if it is already present in the cache
+ */
+ @Override
+ public synchronized void updateIfAlreadyInCache(int taskId, V data) {
+ Entry<V> entry = mMap.get(taskId);
+ if (entry != null) {
+ entry.mValue = data;
+ }
+ }
+
+ /**
+ * Updates cache size and remove excess if the number of existing entries is larger than new
+ * cache size
+ */
+ @Override
+ public synchronized void updateCacheSizeAndRemoveExcess(int cacheSize) {
+ mMaxSize.compareAndSet(mMaxSize.get(), cacheSize);
+ removeExcessIfNeeded();
+ }
+
+ private synchronized void removeExcessIfNeeded() {
+ while (mQueue.size() > mMaxSize.get() && !mQueue.isEmpty()) {
+ Task.TaskKey key = mQueue.poll();
+ mMap.remove(key.id);
+ }
+ }
+
+ /**
+ * Get maximum size of the cache
+ */
+ @Override
+ public int getMaxSize() {
+ return mMaxSize.get();
+ }
+
+ /**
+ * Get current size of the cache
+ */
+ @Override
+ public int getSize() {
+ return mMap.size();
+ }
+
+ @VisibleForTesting
+ PriorityQueue<Task.TaskKey> getQueue() {
+ return mQueue;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/TaskKeyCache.java b/quickstep/src/com/android/quickstep/util/TaskKeyCache.java
new file mode 100644
index 0000000..8ee78ab
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TaskKeyCache.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import com.android.systemui.shared.recents.model.Task;
+
+import java.util.function.Predicate;
+
+/**
+ * An interface for caching task id and its corresponding object (e.g. thumbnail, task icon)
+ *
+ * @param <V> Type of object stored in the cache
+ */
+public interface TaskKeyCache<V> {
+
+ /**
+ * Removes all entries from the cache.
+ */
+ void evictAll();
+
+ /**
+ * Removes a particular entry from the cache.
+ */
+ void remove(Task.TaskKey key);
+
+ /**
+ * Removes all entries matching keyCheck.
+ */
+ void removeAll(Predicate<Task.TaskKey> keyCheck);
+
+ /**
+ * Gets the entry if it is still valid.
+ */
+ V getAndInvalidateIfModified(Task.TaskKey key);
+
+ /**
+ * Adds an entry to the cache, optionally evicting the last accessed entry.
+ */
+ void put(Task.TaskKey key, V value);
+
+ /**
+ * Updates the cache entry if it is already present in the cache.
+ */
+ void updateIfAlreadyInCache(int taskId, V data);
+
+ /**
+ * Updates cache size and remove excess if the number of existing entries is larger than new
+ * cache size.
+ */
+ default void updateCacheSizeAndRemoveExcess(int cacheSize) { }
+
+ /**
+ * Gets maximum size of the cache.
+ */
+ int getMaxSize();
+
+ /**
+ * Gets current size of the cache.
+ */
+ int getSize();
+
+ class Entry<V> {
+
+ final Task.TaskKey mKey;
+ V mValue;
+
+ Entry(Task.TaskKey key, V value) {
+ mKey = key;
+ mValue = value;
+ }
+
+ @Override
+ public int hashCode() {
+ return mKey.id;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java b/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
index 08a65fa..89f5d41 100644
--- a/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
+++ b/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
@@ -27,7 +27,7 @@
* A simple LRU cache for task key entries
* @param <V> The type of the value
*/
-public class TaskKeyLruCache<V> {
+public class TaskKeyLruCache<V> implements TaskKeyCache<V> {
private final MyLinkedHashMap<V> mMap;
@@ -92,20 +92,14 @@
}
}
- private static class Entry<V> {
+ @Override
+ public int getMaxSize() {
+ return mMap.mMaxSize;
+ }
- final TaskKey mKey;
- V mValue;
-
- Entry(TaskKey key, V value) {
- mKey = key;
- mValue = value;
- }
-
- @Override
- public int hashCode() {
- return mKey.id;
- }
+ @Override
+ public int getSize() {
+ return mMap.size();
}
private static class MyLinkedHashMap<V> extends LinkedHashMap<Integer, Entry<V>> {
diff --git a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
index c22e0bc..cdadd71 100644
--- a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
+++ b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
@@ -18,11 +18,13 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import android.app.Activity;
+import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
+import static com.android.launcher3.BaseActivity.EVENT_RESUMED;
+import static com.android.launcher3.BaseActivity.EVENT_STOPPED;
import androidx.annotation.NonNull;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
+import com.android.launcher3.BaseActivity;
import com.android.quickstep.RecentsModel;
/**
@@ -34,19 +36,28 @@
* If we hit either of those signals and the task is no longer valid, then the registered failure
* callback will be notified.
*/
-public class TaskRemovedDuringLaunchListener implements ActivityLifecycleCallbacksAdapter {
+public class TaskRemovedDuringLaunchListener {
- private Activity mActivity;
+ private BaseActivity mActivity;
private int mLaunchedTaskId = INVALID_TASK_ID;
private Runnable mTaskLaunchFailedCallback = null;
+ private final Runnable mUnregisterCallback = this::unregister;
+ private final Runnable mResumeCallback = this::checkTaskLaunchFailed;
+
/**
* Registers a failure listener callback if it detects a scenario in which an app launch
* failed before the transition finished.
*/
- public void register(Activity activity, int launchedTaskId,
+ public void register(BaseActivity activity, int launchedTaskId,
@NonNull Runnable taskLaunchFailedCallback) {
- activity.registerActivityLifecycleCallbacks(this);
+ // The normal task launch case, Launcher stops and updates its state correctly
+ activity.addEventCallback(EVENT_STOPPED, mUnregisterCallback);
+ // The transition hasn't finished but Launcher was resumed, check if the launch failed
+ activity.addEventCallback(EVENT_RESUMED, mResumeCallback);
+ // If we somehow don't get any of the above signals, then just unregister this listener
+ activity.addEventCallback(EVENT_DESTROYED, mUnregisterCallback);
+
mActivity = activity;
mLaunchedTaskId = launchedTaskId;
mTaskLaunchFailedCallback = taskLaunchFailedCallback;
@@ -56,7 +67,10 @@
* Unregisters the failure listener.
*/
private void unregister() {
- mActivity.unregisterActivityLifecycleCallbacks(this);
+ mActivity.removeEventCallback(EVENT_STOPPED, mUnregisterCallback);
+ mActivity.removeEventCallback(EVENT_RESUMED, mResumeCallback);
+ mActivity.removeEventCallback(EVENT_DESTROYED, mUnregisterCallback);
+
mActivity = null;
mLaunchedTaskId = INVALID_TASK_ID;
mTaskLaunchFailedCallback = null;
@@ -70,32 +84,16 @@
checkTaskLaunchFailed();
}
- @Override
- public void onActivityStopped(Activity activity) {
- // The normal task launch case, Launcher stops and updates its state correctly
- unregister();
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
- // The transition hasn't finished but Launcher was resumed, check if the launch failed
- checkTaskLaunchFailed();
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- // If we somehow don't get any of the above signals, then just unregister this listener
- unregister();
- }
-
private void checkTaskLaunchFailed() {
if (mLaunchedTaskId != INVALID_TASK_ID) {
final int launchedTaskId = mLaunchedTaskId;
final Runnable taskLaunchFailedCallback = mTaskLaunchFailedCallback;
RecentsModel.INSTANCE.getNoCreate().isTaskRemoved(mLaunchedTaskId, (taskRemoved) -> {
if (taskRemoved) {
- ActiveGestureLog.INSTANCE.addLog("Launch failed, task (id=" + launchedTaskId
- + ") finished mid transition");
+ ActiveGestureLog.INSTANCE.addLog(
+ new ActiveGestureLog.CompoundString("Launch failed, task (id=")
+ .append(launchedTaskId)
+ .append(") finished mid transition"));
taskLaunchFailedCallback.run();
}
}, (task) -> true /* filter */);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 9b2a449..5d8e53e 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -17,6 +17,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
@@ -26,6 +27,7 @@
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
+import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
import android.animation.TimeInterpolator;
import android.content.Context;
@@ -107,6 +109,7 @@
private boolean mIsDesktopTask;
private int mTaskRectTranslationX;
private int mTaskRectTranslationY;
+ private int mPivotOffsetX;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
mContext = context;
@@ -146,12 +149,6 @@
return 1;
}
- if (mIsDesktopTask) {
- mTaskRect.set(mThumbnailPosition);
- mPivot.set(mTaskRect.centerX(), mTaskRect.centerY());
- return 1;
- }
-
if (mIsGridTask) {
mSizeStrategy.calculateGridTaskSize(mContext, mDp, mTaskRect,
mOrientationState.getOrientationHandler());
@@ -169,10 +166,25 @@
mOrientationState.getOrientationHandler()
.setSplitTaskSwipeRect(mDp, mTaskRect, mSplitBounds, mStagePosition);
mTaskRect.offset(mTaskRectTranslationX, mTaskRectTranslationY);
+ } else if (mIsDesktopTask) {
+ // For desktop, tasks can take up only part of the screen size.
+ // Full task size represents the whole screen size, but scaled down to fit in recents.
+ // Task rect will represent the scaled down thumbnail position and is placed inside
+ // full task size as it is on the home screen.
+ fullTaskSize = new Rect(mTaskRect);
+ PointF fullscreenTaskDimension = new PointF();
+ BaseActivityInterface.getTaskDimension(mContext, mDp, fullscreenTaskDimension);
+ // Calculate the scale down factor used in recents
+ float scale = fullTaskSize.width() / fullscreenTaskDimension.x;
+ mTaskRect.set(mThumbnailPosition);
+ mTaskRect.scale(scale);
+ // Ensure the task rect is inside the full task rect
+ mTaskRect.offset(fullTaskSize.left, fullTaskSize.top);
} else {
- fullTaskSize = mTaskRect;
+ fullTaskSize = new Rect(mTaskRect);
+ mTaskRect.offset(mTaskRectTranslationX, mTaskRectTranslationY);
}
- fullTaskSize.offset(mTaskRectTranslationX, mTaskRectTranslationY);
+ fullTaskSize.offset(mTaskRectTranslationX + mPivotOffsetX, mTaskRectTranslationY);
return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
}
@@ -202,7 +214,8 @@
mStagePosition = mThumbnailPosition.equals(splitInfo.leftTopBounds) ?
STAGE_POSITION_TOP_OR_LEFT :
STAGE_POSITION_BOTTOM_OR_RIGHT;
- mPositionHelper.setSplitBounds(convertSplitBounds(mSplitBounds), mStagePosition);
+ mPositionHelper.setSplitBounds(convertLauncherSplitBoundsToShell(mSplitBounds),
+ mStagePosition);
}
/**
@@ -255,6 +268,11 @@
*/
public void addAppToOverviewAnim(PendingAnimation pa, TimeInterpolator interpolator) {
pa.addFloat(fullScreenProgress, AnimatedFloat.VALUE, 1, 0, interpolator);
+ if (enableGridOnlyOverview() && mDp.isTablet) {
+ int translationXToMiddle = mDp.widthPx / 2 - mTaskRect.centerX();
+ taskPrimaryTranslation.value = translationXToMiddle;
+ mPivotOffsetX = translationXToMiddle;
+ }
pa.addFloat(recentsViewScale, AnimatedFloat.VALUE, getFullScreenScale(), 1, interpolator);
}
@@ -335,8 +353,7 @@
boolean isRtlEnabled = !mIsRecentsRtl;
mPositionHelper.updateThumbnailMatrix(
mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(),
- mDp.widthPx, mDp.heightPx, mDp.taskbarHeight, mDp.isTablet,
- mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
+ mDp.isTablet, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
if (DEBUG) {
Log.d(TAG, " taskRect: " + mTaskRect);
@@ -345,7 +362,7 @@
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
mCurrentFullscreenParams.setProgress(fullScreenProgress, recentsViewScale.value,
- /* taskViewScale= */1f, mTaskRect.width(), mDp, mPositionHelper);
+ /* taskViewScale= */1f);
// Apply thumbnail matrix
float taskWidth = mTaskRect.width();
@@ -429,16 +446,4 @@
// Ideally we should use square-root. This is an optimization as one of the dimension is 0.
return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1]));
}
-
- /**
- * TODO(b/254378592): Remove this after consolidation of classes
- */
- public static com.android.wm.shell.util.SplitBounds convertSplitBounds(SplitBounds bounds) {
- return new com.android.wm.shell.util.SplitBounds(
- bounds.leftTopBounds,
- bounds.rightBottomBounds,
- bounds.leftTopTaskId,
- bounds.rightBottomTaskId
- );
- }
}
diff --git a/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt
new file mode 100644
index 0000000..4f89c7e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util.unfold
+
+import android.view.View
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import java.util.function.Supplier
+
+/** Reports beginning and end of the unfold animation to interaction jank monitor */
+class LauncherJankMonitorTransitionProgressListener(
+ private val attachedViewProvider: Supplier<View>
+) : TransitionProgressListener {
+
+ override fun onTransitionStarted() {
+ InteractionJankMonitorWrapper.begin(
+ attachedViewProvider.get(),
+ InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM
+ )
+ }
+
+ override fun onTransitionFinished() {
+ InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM)
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 19ac1f8..fba847f 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -16,7 +16,7 @@
package com.android.quickstep.views;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import android.content.Context;
import android.util.AttributeSet;
@@ -251,7 +251,7 @@
private float getOriginalTranslationY() {
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
if (deviceProfile.isTablet) {
- if (ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (enableGridOnlyOverview()) {
return (getRecentsView().getLastComputedTaskSize().height()
+ deviceProfile.overviewTaskThumbnailTopMarginPx) / 2.0f
+ deviceProfile.overviewRowSpacing;
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index dfd4390..a10d2ed 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -17,8 +17,6 @@
package com.android.quickstep.views;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import android.content.Context;
@@ -41,19 +39,19 @@
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.util.RunnableList;
import com.android.quickstep.RecentsModel;
-import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.QuickStepContract;
+import com.android.wm.shell.Flags;
import java.util.ArrayList;
import java.util.Arrays;
@@ -62,23 +60,18 @@
import java.util.List;
import java.util.function.Consumer;
+import kotlin.Unit;
+
/**
* TaskView that contains all tasks that are part of the desktop.
*/
// TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks.
public class DesktopTaskView extends TaskView {
- /** Flag to indicate whether desktop windowing proto 1 is enabled */
- private static final boolean DESKTOP_IS_PROTO1_ENABLED = SystemProperties.getBoolean(
- "persist.wm.debug.desktop_mode", false);
-
- /** Flag to indicate whether desktop windowing proto 2 is enabled */
- public static final boolean DESKTOP_IS_PROTO2_ENABLED = SystemProperties.getBoolean(
+ private static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean(
"persist.wm.debug.desktop_mode_2", false);
- /** Flags to indicate whether desktop mode is available on the device */
- public static final boolean DESKTOP_MODE_SUPPORTED =
- DESKTOP_IS_PROTO1_ENABLED || DESKTOP_IS_PROTO2_ENABLED;
+ private static final boolean ENABLE_DESKTOP_WINDOWING = Flags.enableDesktopWindowing();
private static final String TAG = DesktopTaskView.class.getSimpleName();
@@ -98,6 +91,17 @@
private View mBackgroundView;
+ /** Check whether desktop windowing is enabled */
+ public static boolean isDesktopModeSupported() {
+ // Check for aconfig flag first
+ if (ENABLE_DESKTOP_WINDOWING) {
+ return true;
+ }
+ // Fall back to sysprop flag
+ // TODO(b/304778354): remove sysprop once desktop aconfig flag supports dynamic overriding
+ return DESKTOP_MODE_SUPPORTED;
+ }
+
public DesktopTaskView(Context context) {
this(context, null);
}
@@ -150,9 +154,10 @@
}
@Override
- protected void updateBorderBounds(Rect bounds) {
+ protected Unit updateBorderBounds(@NonNull Rect bounds) {
bounds.set(mBackgroundView.getLeft(), mBackgroundView.getTop(), mBackgroundView.getRight(),
mBackgroundView.getBottom());
+ return Unit.INSTANCE;
}
@Override
@@ -335,21 +340,27 @@
}
@Override
- protected boolean showTaskMenuWithContainer(IconView iconView) {
+ protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
return false;
}
- @Override
- public RunnableList launchTasks() {
- SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(mActivity.getDisplayId());
- Launcher.getLauncher(mActivity).getStateManager().goToState(NORMAL, false /* animated */);
- return null;
- }
-
@Nullable
@Override
public RunnableList launchTaskAnimated() {
- return launchTasks();
+ RunnableList endCallback = new RunnableList();
+
+ RecentsView recentsView = getRecentsView();
+ DesktopRecentsTransitionController recentsController =
+ recentsView.getDesktopRecentsController();
+ if (recentsController != null) {
+ recentsController.launchDesktopFromRecents(this, success -> {
+ endCallback.executeAllAndDestroy();
+ });
+ }
+
+ // Callbacks get run from recentsView for case when recents animation already running
+ recentsView.addSideTaskLaunchCallback(endCallback);
+ return endCallback;
}
@Override
@@ -507,8 +518,7 @@
for (int i = 0; i < mSnapshotViewMap.size(); i++) {
if (i == 0) {
// All snapshots share the same params. Only update it with the first snapshot.
- updateFullscreenParams(mSnapshotDrawParams,
- mSnapshotView.getPreviewPositionHelper());
+ updateFullscreenParams(mSnapshotDrawParams);
}
mSnapshotViewMap.valueAt(i).setFullscreenParams(mSnapshotDrawParams);
}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index f250b8c..92ffcd0 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.quickstep.views;
import static com.android.app.animation.Interpolators.LINEAR;
@@ -47,8 +62,6 @@
* {@link #addConfirmAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}
* giving a starting and ending bounds. Currently this is set to use the split placeholder view,
* but it could be generified.
- *
- * TODO: Figure out how to copy thumbnail data from existing TaskView to this view.
*/
public class FloatingTaskView extends FrameLayout {
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 01f6ae8..5b1d614 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -2,8 +2,9 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
import android.content.Context;
import android.graphics.PointF;
@@ -11,6 +12,7 @@
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewStub;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -28,15 +30,17 @@
import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TaskViewSimulator;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
+import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
import java.util.HashMap;
import java.util.function.Consumer;
+import kotlin.Unit;
+
/**
* TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
*
@@ -52,7 +56,7 @@
@Nullable
private Task mSecondaryTask;
private TaskThumbnailView mSnapshotView2;
- private IconView mIconView2;
+ private TaskViewIcon mIconView2;
@Nullable
private CancellableTask<ThumbnailData> mThumbnailLoadRequest2;
@Nullable
@@ -76,10 +80,10 @@
}
@Override
- protected void updateBorderBounds(Rect bounds) {
+ protected Unit updateBorderBounds(@NonNull Rect bounds) {
if (mSplitBoundsConfig == null) {
super.updateBorderBounds(bounds);
- return;
+ return Unit.INSTANCE;
}
bounds.set(
Math.min(mSnapshotView.getLeft() + Math.round(mSnapshotView.getTranslationX()),
@@ -90,14 +94,21 @@
mSnapshotView2.getRight() + Math.round(mSnapshotView2.getTranslationX())),
Math.max(mSnapshotView.getBottom() + Math.round(mSnapshotView.getTranslationY()),
mSnapshotView2.getBottom() + Math.round(mSnapshotView2.getTranslationY())));
+ return Unit.INSTANCE;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
- mIconView2 = findViewById(R.id.bottomRight_icon);
- mIcon2TouchDelegate = new TransformingTouchDelegate(mIconView2);
+ ViewStub iconViewStub2 = findViewById(R.id.bottomRight_icon);
+ if (enableOverviewIconMenu()) {
+ iconViewStub2.setLayoutResource(R.layout.icon_app_chip_view);
+ } else {
+ iconViewStub2.setLayoutResource(R.layout.icon_view);
+ }
+ mIconView2 = (TaskViewIcon) iconViewStub2.inflate();
+ mIcon2TouchDelegate = new TransformingTouchDelegate(mIconView2.asView());
}
public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
@@ -114,11 +125,11 @@
if (mSplitBoundsConfig == null) {
return;
}
- mSnapshotView.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator
- .convertSplitBounds(splitBoundsConfig),
+ mSnapshotView.getPreviewPositionHelper().setSplitBounds(
+ convertLauncherSplitBoundsToShell(splitBoundsConfig),
PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT);
- mSnapshotView2.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator
- .convertSplitBounds(splitBoundsConfig),
+ mSnapshotView2.getPreviewPositionHelper().setSplitBounds(
+ convertLauncherSplitBoundsToShell(splitBoundsConfig),
PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT);
}
@@ -157,6 +168,9 @@
mIconLoadRequest2 = iconCache.updateIconInBackground(mSecondaryTask,
(task) -> {
setIcon(mIconView2, task.icon);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView2, task.title);
+ }
mDigitalWellBeingToast2.initialize(mSecondaryTask);
mDigitalWellBeingToast2.setSplitConfiguration(mSplitBoundsConfig);
mDigitalWellBeingToast.setSplitConfiguration(mSplitBoundsConfig);
@@ -171,6 +185,9 @@
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
setIcon(mIconView2, null);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView2, null);
+ }
}
}
}
@@ -180,12 +197,20 @@
invalidate();
}
- public float getSplitRatio() {
- if (mSplitBoundsConfig != null) {
- return mSplitBoundsConfig.appsStackedVertically
- ? mSplitBoundsConfig.topTaskPercent : mSplitBoundsConfig.leftTaskPercent;
+ @Nullable
+ public SplitBounds getSplitBoundsConfig() {
+ return mSplitBoundsConfig;
+ }
+
+ /**
+ * Returns the {@link PersistentSnapPosition} of this pair of tasks.
+ */
+ public @PersistentSnapPosition int getSnapPosition() {
+ if (mSplitBoundsConfig == null) {
+ throw new IllegalStateException("mSplitBoundsConfig is null");
}
- return DEFAULT_SPLIT_RATIO;
+
+ return mSplitBoundsConfig.snapPosition;
}
@Override
@@ -251,7 +276,7 @@
getRecentsView().getSplitSelectController().launchExistingSplitPair(
launchingExistingTaskView ? this : null, mTask.key.id,
mSecondaryTask.key.id, SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
- callback, isQuickswitch, getSplitRatio());
+ callback, isQuickswitch, getSnapPosition());
}
@Override
@@ -294,7 +319,7 @@
}
// Check which of the two apps was selected
- if (isCoordInView(mIconView2, mLastTouchDownPosition)
+ if (isCoordInView(mIconView2.asView(), mLastTouchDownPosition)
|| isCoordInView(mSnapshotView2, mLastTouchDownPosition)) {
return 1;
}
@@ -360,10 +385,7 @@
super.setOrientationState(orientationState);
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
boolean isGridTask = deviceProfile.isTablet && !isFocusedTask();
- int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
- : deviceProfile.overviewTaskIconDrawableSizePx;
- mIconView2.setDrawableSize(iconDrawableSize, iconDrawableSize);
- mIconView2.setRotation(getPagedOrientationHandler().getDegreesRotated());
+ mIconView2.setIconOrientation(orientationState, isGridTask);
updateIconPlacement();
updateSecondaryDwbPlacement();
}
@@ -377,7 +399,7 @@
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- getPagedOrientationHandler().setSplitIconParams(mIconView, mIconView2,
+ getPagedOrientationHandler().setSplitIconParams(mIconView.asView(), mIconView2.asView(),
taskIconHeight, mSnapshotView.getMeasuredWidth(), mSnapshotView.getMeasuredHeight(),
getMeasuredHeight(), getMeasuredWidth(), isRtl, deviceProfile,
mSplitBoundsConfig);
diff --git a/quickstep/src/com/android/quickstep/views/IconAppChipView.java b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
new file mode 100644
index 0000000..5a2e135
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/IconAppChipView.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.touch.LandscapePagedViewHandler;
+import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.touch.SeascapePagedViewHandler;
+import com.android.launcher3.views.ActivityContext;
+import com.android.quickstep.util.RecentsOrientedState;
+
+/**
+ * An icon app menu view which can be used in place of an IconView in overview TaskViews.
+ */
+public class IconAppChipView extends FrameLayout implements TaskViewIcon {
+
+ private static final int MENU_BACKGROUND_REVEAL_DURATION = 417;
+ private static final int MENU_BACKGROUND_HIDE_DURATION = 333;
+
+ private IconView mIconView;
+ private TextView mIconTextView;
+ private ImageView mIconArrowView;
+ private ImageView mIconViewBackground;
+
+ private int mMaxIconBackgroundWidth;
+ private int mMinIconBackgroundWidth;
+ private int mMaxIconBackgroundHeight;
+ private int mMinIconBackgroundHeight;
+ private int mIconTextMinWidth;
+ private int mIconTextMaxWidth;
+ private int mInnerMargin;
+ private int mIconArrowSize;
+ private int mIconMenuMarginStart;
+ private int mArrowMaxTranslationX;
+
+ public IconAppChipView(Context context) {
+ this(context, null);
+ }
+
+ public IconAppChipView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public IconAppChipView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public IconAppChipView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ mMaxIconBackgroundWidth = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_max_width);
+ mMinIconBackgroundWidth = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_min_width);
+ mMaxIconBackgroundHeight = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_max_height);
+ mMinIconBackgroundHeight = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_min_height);
+ mIconTextMaxWidth = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_text_max_width);
+ mInnerMargin = (int) getResources().getDimension(
+ R.dimen.task_thumbnail_icon_menu_arrow_margin);
+ mIconTextMinWidth = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_text_width) + (2 * mInnerMargin);
+ int taskIconHeight = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_drawable_touch_size);
+ int arrowWidth = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_arrow_size);
+ mIconArrowSize = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_arrow_drawable_size);
+ mIconMenuMarginStart = getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_margin);
+ mArrowMaxTranslationX =
+ mMaxIconBackgroundWidth - taskIconHeight - mIconTextMaxWidth + arrowWidth;
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mIconView = findViewById(R.id.icon_view);
+ mIconTextView = findViewById(R.id.icon_text);
+ mIconArrowView = findViewById(R.id.icon_arrow);
+ mIconViewBackground = findViewById(R.id.icon_view_background);
+ }
+
+ protected IconView getIconView() {
+ return mIconView;
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ if (mIconTextView != null) {
+ mIconTextView.setText(text);
+ }
+ }
+
+ @Override
+ public Drawable getDrawable() {
+ return mIconView == null ? null : mIconView.getDrawable();
+ }
+
+ @Override
+ public void setDrawable(Drawable icon) {
+ if (mIconView != null) {
+ mIconView.setDrawable(icon);
+ }
+ }
+
+ @Override
+ public void setDrawableSize(int iconWidth, int iconHeight) {
+ if (mIconView != null) {
+ mIconView.setDrawableSize(iconWidth, iconHeight);
+ }
+ }
+
+ @Override
+ public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) {
+
+ PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
+ boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+ DeviceProfile deviceProfile =
+ ActivityContext.lookupContext(getContext()).getDeviceProfile();
+
+ int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ int taskIconSize = deviceProfile.overviewTaskIconSizePx;
+ int taskMargin = deviceProfile.overviewTaskMarginPx;
+
+ LayoutParams iconMenuParams = (LayoutParams) getLayoutParams();
+ orientationHandler.setTaskIconMenuParams(iconMenuParams, mIconMenuMarginStart,
+ thumbnailTopMargin);
+ iconMenuParams.width = mMinIconBackgroundWidth;
+ iconMenuParams.height = taskIconSize;
+ if (orientationHandler instanceof SeascapePagedViewHandler) {
+ // Use half menu height to place the pivot within the X/Y center of icon in the menu.
+ setPivotX(getHeight() / 2f);
+ setPivotY(getHeight() / 2f - mIconMenuMarginStart);
+ } else if (orientationHandler instanceof LandscapePagedViewHandler) {
+ setPivotX(getWidth());
+ setPivotY(0);
+ }
+ // Pivot not updated for PortraitPagedViewHandler case, as it has 0 rotation.
+
+ setTranslationY(0);
+ setRotation(orientationHandler.getDegreesRotated());
+
+ LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
+ orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconSize,
+ thumbnailTopMargin, isRtl);
+ iconParams.width = iconParams.height = taskIconSize;
+ iconParams.gravity = Gravity.START | Gravity.CENTER_VERTICAL;
+ mIconView.setLayoutParams(iconParams);
+
+ int iconDrawableSize = enableOverviewIconMenu()
+ ? deviceProfile.overviewTaskIconAppChipMenuDrawableSizePx
+ : isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
+ : deviceProfile.overviewTaskIconDrawableSizePx;
+ mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
+
+ LayoutParams iconTextParams = (LayoutParams) mIconTextView.getLayoutParams();
+ orientationHandler.setTaskIconParams(iconTextParams, 0, taskIconSize,
+ thumbnailTopMargin, isRtl);
+ iconTextParams.width = mIconTextMaxWidth;
+ iconTextParams.height = taskIconSize;
+ iconTextParams.setMarginStart(taskIconSize);
+ iconTextParams.topMargin = (getHeight() - mIconTextView.getHeight()) / 2;
+ iconTextParams.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
+ mIconTextView.setLayoutParams(iconTextParams);
+ mIconTextView.setRevealClip(true, 0, taskIconSize / 2f, mIconTextMinWidth);
+
+ LayoutParams iconArrowParams = (LayoutParams) mIconArrowView.getLayoutParams();
+ iconArrowParams.gravity = Gravity.CENTER_VERTICAL | Gravity.END;
+ iconArrowParams.setMarginStart(taskIconSize + mIconTextMinWidth);
+ iconArrowParams.setMarginEnd(mInnerMargin);
+ mIconArrowView.setLayoutParams(iconArrowParams);
+ mIconArrowView.getDrawable().setBounds(0, 0, mIconArrowSize, mIconArrowSize);
+
+ LayoutParams backgroundParams = (LayoutParams) mIconViewBackground.getLayoutParams();
+ backgroundParams.width = mMinIconBackgroundWidth;
+ backgroundParams.height = taskIconSize;
+ mIconViewBackground.setPivotX(
+ isRtl ? mMinIconBackgroundWidth - (taskIconSize / 2f - mInnerMargin)
+ : taskIconSize / 2f - mInnerMargin);
+ mIconViewBackground.setPivotY(taskIconSize / 2f);
+
+ requestLayout();
+ }
+
+ @Override
+ public void setIconColorTint(int color, float amount) {
+ if (mIconView != null) {
+ mIconView.setIconColorTint(color, amount);
+ }
+ }
+
+ @Override
+ public int getDrawableWidth() {
+ return mIconView == null ? 0 : mIconView.getDrawableWidth();
+ }
+
+ @Override
+ public int getDrawableHeight() {
+ return mIconView == null ? 0 : mIconView.getDrawableHeight();
+ }
+
+ protected void revealAnim(boolean isRevealing) {
+ if (isRevealing) {
+ ((AnimatedVectorDrawable) mIconArrowView.getDrawable()).start();
+ AnimatorSet anim = new AnimatorSet();
+ anim.playTogether(
+ ViewAnimationUtils.createCircularReveal(mIconTextView, 0,
+ mIconTextView.getHeight() / 2, mIconTextMinWidth, mIconTextMaxWidth),
+ ObjectAnimator.ofFloat(mIconViewBackground, SCALE_X,
+ mMaxIconBackgroundWidth / (float) mMinIconBackgroundWidth),
+ ObjectAnimator.ofFloat(mIconViewBackground, SCALE_Y,
+ mMaxIconBackgroundHeight / (float) mMinIconBackgroundHeight),
+ ObjectAnimator.ofFloat(mIconArrowView, TRANSLATION_X,
+ isLayoutRtl() ? -mArrowMaxTranslationX : mArrowMaxTranslationX));
+ anim.setDuration(MENU_BACKGROUND_REVEAL_DURATION);
+ anim.setInterpolator(EMPHASIZED);
+ anim.start();
+ } else {
+ ((AnimatedVectorDrawable) mIconArrowView.getDrawable()).reverse();
+ AnimatorSet anim = new AnimatorSet();
+ Animator textRevealAnim = ViewAnimationUtils.createCircularReveal(mIconTextView, 0,
+ mIconTextView.getHeight() / 2, mIconTextMaxWidth, mIconTextMinWidth);
+ textRevealAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // createCircularReveal removes clip on finish, restore it here to clip text.
+ mIconTextView.setRevealClip(true, 0, mIconTextView.getHeight() / 2f,
+ mIconTextMinWidth);
+ }
+ });
+ anim.playTogether(
+ textRevealAnim,
+ ObjectAnimator.ofFloat(mIconViewBackground, SCALE_X, 1),
+ ObjectAnimator.ofFloat(mIconViewBackground, SCALE_Y, 1),
+ ObjectAnimator.ofFloat(mIconArrowView, TRANSLATION_X, 0));
+ anim.setDuration(MENU_BACKGROUND_HIDE_DURATION);
+ anim.setInterpolator(EMPHASIZED);
+ anim.start();
+ }
+ }
+
+ @Override
+ public View asView() {
+ return this;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
index 5895c05..64caba7 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.java
+++ b/quickstep/src/com/android/quickstep/views/IconView.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.views;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
+
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -22,16 +24,21 @@
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
+import android.widget.FrameLayout;
import androidx.annotation.Nullable;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.views.ActivityContext;
+import com.android.quickstep.util.RecentsOrientedState;
/**
* A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
* when the drawable changes.
*/
-public class IconView extends View {
+public class IconView extends View implements TaskViewIcon {
@Nullable
private Drawable mDrawable;
@@ -52,6 +59,7 @@
/**
* Sets a {@link Drawable} to be displayed.
*/
+ @Override
public void setDrawable(@Nullable Drawable d) {
if (mDrawable != null) {
mDrawable.setCallback(null);
@@ -67,6 +75,7 @@
/**
* Sets the size of the icon drawable.
*/
+ @Override
public void setDrawableSize(int iconWidth, int iconHeight) {
mDrawableWidth = iconWidth;
mDrawableHeight = iconHeight;
@@ -82,15 +91,18 @@
mDrawable.setBounds(drawableRect);
}
+ @Override
@Nullable
public Drawable getDrawable() {
return mDrawable;
}
+ @Override
public int getDrawableWidth() {
return mDrawableWidth;
}
+ @Override
public int getDrawableHeight() {
return mDrawableHeight;
}
@@ -147,9 +159,41 @@
* @param color to blend in.
* @param amount [0,1] 0 no tint, 1 full tint
*/
+ @Override
public void setIconColorTint(int color, float amount) {
if (mDrawable != null) {
mDrawable.setColorFilter(Utilities.makeColorTintingColorFilter(color, amount));
}
}
+
+ @Override
+ public void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask) {
+ PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
+ boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+ DeviceProfile deviceProfile =
+ ActivityContext.lookupContext(getContext()).getDeviceProfile();
+
+ FrameLayout.LayoutParams iconParams = (FrameLayout.LayoutParams) getLayoutParams();
+
+ int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
+ int taskMargin = deviceProfile.overviewTaskMarginPx;
+
+ orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconHeight,
+ thumbnailTopMargin, isRtl);
+ iconParams.width = iconParams.height = taskIconHeight;
+ setLayoutParams(iconParams);
+
+ setRotation(orientationHandler.getDegreesRotated());
+ int iconDrawableSize = enableOverviewIconMenu()
+ ? deviceProfile.overviewTaskIconAppChipMenuDrawableSizePx
+ : isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
+ : deviceProfile.overviewTaskIconDrawableSizePx;
+ setDrawableSize(iconDrawableSize, iconDrawableSize);
+ }
+
+ @Override
+ public View asView() {
+ return this;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index ebe4c66..a265146 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -25,12 +25,12 @@
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
@@ -38,12 +38,12 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.LauncherState;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.SplitConfigurationOptions;
@@ -77,8 +77,9 @@
@Override
public void init(OverviewActionsView actionsView,
- SplitSelectStateController splitPlaceholderView) {
- super.init(actionsView, splitPlaceholderView);
+ SplitSelectStateController splitPlaceholderView,
+ @Nullable DesktopRecentsTransitionController desktopRecentsTransitionController) {
+ super.init(actionsView, splitPlaceholderView, desktopRecentsTransitionController);
setContentAlpha(0);
}
@@ -87,7 +88,7 @@
StateManager stateManager = mActivity.getStateManager();
animated &= stateManager.shouldAnimateStateChange();
stateManager.goToState(NORMAL, animated);
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.getSplitAnimationController()
.playPlaceholderDismissAnim(mActivity);
}
@@ -137,12 +138,16 @@
@Override
public void onStateTransitionStart(LauncherState toState) {
setOverviewStateEnabled(toState.overviewUi);
+
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
if (toState == OVERVIEW_MODAL_TASK) {
setOverviewSelectEnabled(true);
}
setFreezeViewVisibility(true);
+ if (mActivity.getDesktopVisibilityController() != null) {
+ mActivity.getDesktopVisibilityController().onLauncherStateChanged(toState);
+ }
}
@Override
@@ -168,17 +173,12 @@
@Override
public void setOverviewStateEnabled(boolean enabled) {
super.setOverviewStateEnabled(enabled);
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "overview state enabled state has changed: "
- + enabled);
if (enabled) {
LauncherState state = mActivity.getStateManager().getState();
boolean hasClearAllButton = (state.getVisibleElements(mActivity)
& CLEAR_ALL_BUTTON) != 0;
setDisallowScrollToClearAll(!hasClearAllButton);
}
- if (mActivity.getDesktopVisibilityController() != null) {
- mActivity.getDesktopVisibilityController().setOverviewStateEnabled(enabled);
- }
}
@Override
@@ -233,7 +233,7 @@
@Override
protected boolean canLaunchFullscreenTask() {
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
return !mSplitSelectStateController.isSplitSelectActive();
} else {
return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
@@ -256,7 +256,7 @@
DesktopVisibilityController desktopVisibilityController = null;
boolean showDesktopApps = false;
GestureState.GestureEndTarget endTarget = null;
- if (DesktopTaskView.DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
desktopVisibilityController = mActivity.getDesktopVisibilityController();
endTarget = mCurrentGestureEndTarget;
if (endTarget == GestureState.GestureEndTarget.LAST_TASK
@@ -271,7 +271,8 @@
desktopVisibilityController.setRecentsGestureEnd(endTarget);
}
if (showDesktopApps) {
- SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId());
+ SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId(),
+ null /* transition */);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index b31791a..7f1d619 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -29,9 +29,9 @@
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
import com.android.launcher3.util.MultiValueAlpha;
@@ -289,7 +289,7 @@
return 0;
}
- if (mDp.isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (mDp.isTablet && Flags.enableGridOnlyOverview()) {
return mDp.stashedTaskbarHeight;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 76f9c2c..7972999 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -42,11 +42,12 @@
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
+import static com.android.launcher3.testing.shared.TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE;
import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -55,7 +56,7 @@
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import static com.android.quickstep.util.LogUtils.splitFailureMessage;
import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
-import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET;
import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_ACTIONS_IN_MENU;
@@ -142,6 +143,7 @@
import com.android.launcher3.anim.SpringProperty;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.desktop.DesktopRecentsTransitionController;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.statehandlers.DepthController;
@@ -215,6 +217,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -721,6 +724,9 @@
private ObjectAnimator mActionsViewAlphaAnimator;
private float mActionsViewAlphaAnimatorFinalValue;
+ @Nullable
+ private DesktopRecentsTransitionController mDesktopRecentsTransitionController;
+
/**
* Keeps track of the desktop task. Optional and only present when the feature flag is enabled.
*/
@@ -1041,10 +1047,12 @@
updateTaskStackListenerState();
}
- public void init(OverviewActionsView actionsView, SplitSelectStateController splitController) {
+ public void init(OverviewActionsView actionsView, SplitSelectStateController splitController,
+ @Nullable DesktopRecentsTransitionController desktopRecentsTransitionController) {
mActionsView = actionsView;
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
mSplitSelectStateController = splitController;
+ mDesktopRecentsTransitionController = desktopRecentsTransitionController;
}
public SplitSelectStateController getSplitSelectController() {
@@ -1079,7 +1087,7 @@
mIPipAnimationListener);
mOrientationState.initListeners();
mTaskOverlayFactory.initListeners();
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.registerSplitListener(mSplitSelectionListener);
}
}
@@ -1100,7 +1108,7 @@
mIPipAnimationListener.setActivityAndRecentsView(null, null);
mOrientationState.destroyListeners();
mTaskOverlayFactory.removeListeners();
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.unregisterSplitListener(mSplitSelectionListener);
}
}
@@ -1615,7 +1623,7 @@
mMovingTaskView = null;
runningTaskView.resetPersistentViewTransforms();
int frontTaskIndex = 0;
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED && mDesktopTaskView != null
+ if (isDesktopModeSupported() && mDesktopTaskView != null
&& !runningTaskView.isDesktopTask()) {
// If desktop mode is enabled, desktop task view is pinned at first position if present.
// Move running task to position 1.
@@ -1755,7 +1763,7 @@
if (!taskGroups.isEmpty()) {
addView(mClearAllButton);
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
// Check if we have apps on the desktop
if (desktopTask != null && !desktopTask.tasks.isEmpty()) {
// If we are actively choosing apps for split, skip the desktop tile
@@ -1782,7 +1790,7 @@
newFocusedTaskView = getTaskViewAt(1);
}
}
- mFocusedTaskViewId = newFocusedTaskView != null && !ENABLE_GRID_ONLY_OVERVIEW.get()
+ mFocusedTaskViewId = newFocusedTaskView != null && !enableGridOnlyOverview()
? newFocusedTaskView.getTaskViewId() : INVALID_TASK_ID;
updateTaskSize();
if (newFocusedTaskView != null) {
@@ -1900,7 +1908,7 @@
* Returns the number of tasks in the bottom row of the overview grid.
*/
public int getBottomRowTaskCountForTablet() {
- return getTaskViewCount() - mTopRowIdSet.size() - (ENABLE_GRID_ONLY_OVERVIEW.get() ? 0 : 1);
+ return getTaskViewCount() - mTopRowIdSet.size() - (enableGridOnlyOverview() ? 0 : 1);
}
protected void onTaskStackUpdated() {
@@ -1978,7 +1986,7 @@
DeviceProfile dp = mActivity.getDeviceProfile();
setOverviewGridEnabled(
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
- if (ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (enableGridOnlyOverview()) {
mActionsView.updateHiddenFlags(HIDDEN_ACTIONS_IN_MENU, dp.isTablet);
}
setPageSpacing(dp.overviewPageSpacing);
@@ -2056,11 +2064,11 @@
dp.widthPx - mInsets.right - mTempRect.right,
dp.heightPx - mInsets.bottom - mTempRect.bottom);
- mSizeStrategy.calculateGridSize(mActivity.getDeviceProfile(),
+ mSizeStrategy.calculateGridSize(mActivity.getDeviceProfile(), mActivity,
mLastComputedGridSize);
mSizeStrategy.calculateGridTaskSize(mActivity, mActivity.getDeviceProfile(),
mLastComputedGridTaskSize, mOrientationHandler);
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
mSizeStrategy.calculateDesktopTaskSize(mActivity, mActivity.getDeviceProfile(),
mLastComputedDesktopTaskSize);
}
@@ -2093,11 +2101,15 @@
}
float accumulatedTranslationX = 0;
+ float translateXToMiddle = enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+ ? mActivity.getDeviceProfile().widthPx / 2 - mLastComputedGridTaskSize.centerX()
+ : 0;
for (int i = 0; i < taskCount; i++) {
TaskView taskView = requireTaskViewAt(i);
taskView.updateTaskSize();
taskView.getPrimaryNonGridTranslationProperty().set(taskView, accumulatedTranslationX);
taskView.getSecondaryNonGridTranslationProperty().set(taskView, 0f);
+ taskView.setNonGridPivotTranslationX(translateXToMiddle);
// Compensate space caused by TaskView scaling.
float widthDiff =
taskView.getLayoutParams().width * (1 - taskView.getNonGridScale());
@@ -2140,7 +2152,7 @@
Rect outRect = new Rect(mLastComputedTaskSize);
outRect.offset(
-(primaryScroll - (selectedPageScroll + getOffsetFromScrollPosition(selectedPage))),
- (int) (showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get() && !isTopRow
+ (int) (showAsGrid() && enableGridOnlyOverview() && !isTopRow
? mTopBottomRowHeightDiff : 0));
return outRect;
}
@@ -2270,10 +2282,12 @@
if (showAsGrid()) {
int screenStart = mOrientationHandler.getPrimaryScroll(this);
int pageOrientedSize = mOrientationHandler.getMeasuredSize(this);
- int halfScreenSize = pageOrientedSize / 2;
- // Use +/- 50% screen width as visible area.
- visibleStart = screenStart - halfScreenSize;
- visibleEnd = screenStart + pageOrientedSize + halfScreenSize;
+ // For GRID_ONLY_OVERVIEW, use +/- 1 task column as visible area for preloading
+ // adjacent thumbnails, otherwise use +/-50% screen width
+ int extraWidth = enableGridOnlyOverview() ? getLastComputedTaskSize().width()
+ + getPageSpacing() : pageOrientedSize / 2;
+ visibleStart = screenStart - extraWidth;
+ visibleEnd = screenStart + pageOrientedSize + extraWidth;
} else {
int centerPageIndex = getPageNearestToCenterOfScreen();
int numChildren = getChildCount();
@@ -2354,6 +2368,12 @@
@Override
public void onHighResLoadingStateChanged(boolean enabled) {
+ // Preload cache when no overview task is visible (e.g. not in overview page), so when
+ // user goes to overview next time, the task thumbnails would show up without delay
+ if (mHasVisibleTaskData.size() == 0) {
+ mModel.preloadCacheIfNeeded();
+ }
+
// Whenever the high res loading state changes, poke each of the visible tasks to see if
// they want to updated their thumbnail state
for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
@@ -2402,7 +2422,7 @@
remoteTargetHandle.getTransformParams().setTargetSet(null);
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false);
});
- if (!FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (!FeatureFlags.enableSplitContextually()) {
resetFromSplitSelectionState();
}
@@ -2726,7 +2746,7 @@
boolean runningTaskTileHidden = mRunningTaskTileHidden;
setCurrentTask(runningTaskViewId);
- mFocusedTaskViewId = ENABLE_GRID_ONLY_OVERVIEW.get() ? INVALID_TASK_ID : runningTaskViewId;
+ mFocusedTaskViewId = enableGridOnlyOverview() ? INVALID_TASK_ID : runningTaskViewId;
runOnPageScrollsInitialized(() -> setCurrentPage(getRunningTaskIndex()));
setRunningTaskViewShowScreenshot(false);
setRunningTaskHidden(runningTaskTileHidden);
@@ -2739,7 +2759,7 @@
}
private boolean hasDesktopTask(Task[] runningTasks) {
- if (!DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (!isDesktopModeSupported()) {
return false;
}
for (Task task : runningTasks) {
@@ -2919,7 +2939,7 @@
// Desktop task view is hidden, skip it from grid calculations
continue;
}
- if (!ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (!enableGridOnlyOverview()) {
// Only apply x-translation when using legacy overview grid
gridTranslations[i] += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
}
@@ -3248,7 +3268,10 @@
mSplitSelectStateController.setFirstFloatingTaskView(firstFloatingTaskView);
// Allow user to click staged app to launch into fullscreen
- firstFloatingTaskView.setOnClickListener(this::animateToFullscreen);
+ firstFloatingTaskView.setOnClickListener(view ->
+ mSplitSelectStateController.getSplitAnimationController().
+ playAnimPlaceholderToFullscreen(mActivity, view,
+ Optional.of(() -> resetFromSplitSelectionState())));
// SplitInstructionsView: animate in
safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
@@ -3288,7 +3311,7 @@
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
} else {
// If transition to split select was interrupted, clean up to prevent glitches
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.resetState();
} else {
resetFromSplitSelectionState();
@@ -3301,41 +3324,6 @@
});
}
- private void animateToFullscreen(View view) {
- FloatingTaskView stagedTaskView = (FloatingTaskView) view;
-
- boolean isTablet = mActivity.getDeviceProfile().isTablet;
- int duration = isTablet
- ? SplitAnimationTimings.TABLET_CONFIRM_DURATION
- : SplitAnimationTimings.PHONE_CONFIRM_DURATION;
-
- PendingAnimation pendingAnimation = new PendingAnimation(duration);
-
- Rect firstTaskStartingBounds = new Rect();
- Rect firstTaskEndingBounds = new Rect();
-
- stagedTaskView.getBoundsOnScreen(firstTaskStartingBounds);
- mActivity.getDragLayer().getBoundsOnScreen(firstTaskEndingBounds);
-
- stagedTaskView.addConfirmAnimation(
- pendingAnimation,
- new RectF(firstTaskStartingBounds),
- firstTaskEndingBounds,
- false /* fadeWithThumbnail */,
- true /* isStagedTask */);
-
- pendingAnimation.addEndListener(animationSuccess ->
- mSplitSelectStateController.launchInitialAppFullscreen(launchSuccess -> {
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
- mSplitSelectStateController.resetState();
- } else {
- resetFromSplitSelectionState();
- }
- }));
-
- pendingAnimation.buildAnim().start();
- }
-
/**
* Creates a {@link PendingAnimation} for dismissing the specified {@link TaskView}.
* @param dismissedTaskView the {@link TaskView} to be dismissed
@@ -3432,7 +3420,7 @@
int topGridRowSize = mTopRowIdSet.size();
int bottomGridRowSize = taskCount - mTopRowIdSet.size()
- - (ENABLE_GRID_ONLY_OVERVIEW.get() ? 0 : 1);
+ - (enableGridOnlyOverview() ? 0 : 1);
boolean topRowLonger = topGridRowSize > bottomGridRowSize;
boolean bottomRowLonger = bottomGridRowSize > topGridRowSize;
boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId);
@@ -3445,7 +3433,7 @@
}
int longRowWidth = Math.max(topGridRowSize, bottomGridRowSize)
* (mLastComputedGridTaskSize.width() + mPageSpacing);
- if (!ENABLE_GRID_ONLY_OVERVIEW.get() && !isStagingFocusedTask) {
+ if (!enableGridOnlyOverview() && !isStagingFocusedTask) {
longRowWidth += mLastComputedTaskSize.width() + mPageSpacing;
}
@@ -3812,33 +3800,19 @@
taskViewIdArray.removeValue(
finalNextFocusedTaskView.getTaskViewId());
}
- try {
- if (snappedIndex < taskViewIdArray.size()) {
- taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
- } else if (snappedIndex == taskViewIdArray.size()) {
- // If the snapped task is the last item from the
- // dismissed row,
- // snap to the same column in the other grid row
- IntArray inverseRowTaskViewIdArray =
- isSnappedTaskInTopRow ? getBottomRowIdArray()
- : getTopRowIdArray();
- if (snappedIndex < inverseRowTaskViewIdArray.size()) {
- taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
- snappedIndex);
- }
+ if (snappedIndex < taskViewIdArray.size()) {
+ taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
+ } else if (snappedIndex == taskViewIdArray.size()) {
+ // If the snapped task is the last item from the
+ // dismissed row,
+ // snap to the same column in the other grid row
+ IntArray inverseRowTaskViewIdArray =
+ isSnappedTaskInTopRow ? getBottomRowIdArray()
+ : getTopRowIdArray();
+ if (snappedIndex < inverseRowTaskViewIdArray.size()) {
+ taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
+ snappedIndex);
}
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new IllegalStateException(
- "b/269956477 invalid snappedIndex"
- + "\nsnappedTaskViewId: "
- + snappedTaskViewId
- + "\nfocusedTaskViewId: "
- + mFocusedTaskViewId
- + "\ntopRowIdArray: "
- + getTopRowIdArray().toConcatString()
- + "\nbottomRowIdArray: "
- + getBottomRowIdArray().toConcatString(),
- e);
}
}
}
@@ -3867,7 +3841,7 @@
} else {
// Update focus task and its size.
if (finalIsFocusedTaskDismissed && finalNextFocusedTaskView != null) {
- mFocusedTaskViewId = ENABLE_GRID_ONLY_OVERVIEW.get()
+ mFocusedTaskViewId = enableGridOnlyOverview()
? INVALID_TASK_ID
: finalNextFocusedTaskView.getTaskViewId();
mTopRowIdSet.remove(mFocusedTaskViewId);
@@ -3965,7 +3939,7 @@
mActionsView.updateSplitButtonHiddenFlags(FLAG_IS_NOT_TABLET,
!mActivity.getDeviceProfile().isTablet);
mActionsView.updateSplitButtonDisabledFlags(FLAG_SINGLE_TASK, /*enable=*/ false);
- if (DESKTOP_MODE_SUPPORTED) {
+ if (isDesktopModeSupported()) {
boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView;
mActionsView.updateHiddenFlags(HIDDEN_DESKTOP, isCurrentDesktop);
}
@@ -4049,7 +4023,8 @@
}
protected void onDismissAnimationEnds() {
- AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ DISMISS_ANIMATION_ENDS_MESSAGE);
}
public PendingAnimation createAllTasksDismissAnimation(long duration) {
@@ -4351,14 +4326,19 @@
Utilities.getPivotsForScalingRectToRect(mTempRect, selectedTaskPosition,
mTempPointF);
- setPivotX(mTempPointF.x);
- setPivotY(mTempPointF.y);
} else {
+ mTempRect.set(mLastComputedTaskSize);
+ // Only update pivot when it is tablet and not in grid yet, so the pivot is correct
+ // for non-current tasks when swiping up to overview
+ if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+ && !mOverviewGridEnabled) {
+ mTempRect.offset(mActivity.getDeviceProfile().widthPx / 2 - mTempRect.centerX(), 0);
+ }
getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
mActivity.getDeviceProfile(), mTempPointF);
- setPivotX(mTempPointF.x);
- setPivotY(mTempPointF.y);
}
+ setPivotX(mTempPointF.x);
+ setPivotY(mTempPointF.y);
}
private void updatePageOffsets() {
@@ -4372,7 +4352,7 @@
int midpoint = runningTask == null ? -1 : indexOfChild(runningTask);
int modalMidpoint = getCurrentPage();
boolean isModalGridWithoutFocusedTask =
- showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && mTaskModalness > 0;
+ showAsGrid && enableGridOnlyOverview() && mTaskModalness > 0;
if (isModalGridWithoutFocusedTask) {
modalMidpoint = indexOfChild(mSelectedTask);
}
@@ -4434,7 +4414,7 @@
redrawLiveTile();
}
- if (showAsGrid && ENABLE_GRID_ONLY_OVERVIEW.get() && child instanceof TaskView) {
+ if (showAsGrid && enableGridOnlyOverview() && child instanceof TaskView) {
float totalTranslationY = getVerticalOffsetSize(i, modalOffset);
FloatProperty translationPropertyY =
((TaskView) child).getSecondaryTaskOffsetTranslationProperty();
@@ -4543,7 +4523,7 @@
* @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
*/
private float getVerticalOffsetSize(int childIndex, float offsetProgress) {
- if (offsetProgress == 0 || !(showAsGrid() && ENABLE_GRID_ONLY_OVERVIEW.get())
+ if (offsetProgress == 0 || !(showAsGrid() && enableGridOnlyOverview())
|| mSelectedTask == null) {
// Don't bother calculating everything below if we won't offset vertically.
return 0;
@@ -4633,7 +4613,7 @@
mSplitSelectStateController.setAnimateCurrentTaskDismissal(
true /*animateCurrentTaskDismissal*/);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
updateDesktopTaskVisibility(false /* visible */);
}
}
@@ -4657,7 +4637,7 @@
mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
splitSelectSource.position.stagePosition, splitSelectSource.itemInfo,
splitSelectSource.splitEvent, splitSelectSource.alreadyRunningTaskId);
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
updateDesktopTaskVisibility(false /* visible */);
}
}
@@ -4789,7 +4769,7 @@
pendingAnimation.addEndListener(aBoolean -> {
mSplitSelectStateController.launchSplitTasks(
aBoolean1 -> {
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
mSplitSelectStateController.resetState();
} else {
resetFromSplitSelectionState();
@@ -4818,7 +4798,7 @@
@SuppressLint("WrongCall")
protected void resetFromSplitSelectionState() {
if (mSplitSelectSource != null || mSplitHiddenTaskViewIndex != -1 ||
- FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ FeatureFlags.enableSplitContextually()) {
safeRemoveDragLayerView(mSplitSelectStateController.getFirstFloatingTaskView());
safeRemoveDragLayerView(mSecondFloatingTaskView);
safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
@@ -4838,7 +4818,7 @@
setTaskViewsPrimarySplitTranslation(0);
setTaskViewsSecondarySplitTranslation(0);
- if (!FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (!FeatureFlags.enableSplitContextually()) {
// When flag is on, this method gets called from resetState() call below, let's avoid
// infinite recursion today
mSplitSelectStateController.resetState();
@@ -4863,7 +4843,7 @@
mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE, INVALID_TASK_ID);
mSplitHiddenTaskView = null;
}
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED) {
+ if (isDesktopModeSupported()) {
updateDesktopTaskVisibility(true /* visible */);
}
}
@@ -4978,12 +4958,13 @@
protected void maybeDrawEmptyMessage(Canvas canvas) {
if (mShowEmptyMessage && mEmptyTextLayout != null) {
- // Offset to center in the visible (non-padded) part of RecentsView
- mTempRect.set(mInsets.left + getPaddingLeft(), mInsets.top + getPaddingTop(),
- mInsets.right + getPaddingRight(), mInsets.bottom + getPaddingBottom());
+ // Offsets icon and text up so that the vertical center of screen (accounting for
+ // insets) is between icon and text.
+ int offset = (mEmptyIcon.getIntrinsicHeight() + mEmptyMessagePadding) / 2;
+
canvas.save();
- canvas.translate(getScrollX() + (mTempRect.left - mTempRect.right) / 2,
- (mTempRect.top - mTempRect.bottom) / 2);
+ canvas.translate(getScrollX() + (mInsets.left - mInsets.right) / 2f,
+ (mInsets.top - mInsets.bottom) / 2f - offset);
mEmptyIcon.draw(canvas);
canvas.translate(mEmptyMessagePadding,
mEmptyIcon.getBounds().bottom + mEmptyMessagePadding);
@@ -5237,7 +5218,7 @@
}
RemoteTargetGluer gluer;
- if (DESKTOP_MODE_SUPPORTED && recentsAnimationTargets.hasDesktopTasks()) {
+ if (isDesktopModeSupported() && recentsAnimationTargets.hasDesktopTasks()) {
gluer = new RemoteTargetGluer(getContext(), getSizeStrategy(), recentsAnimationTargets,
true /* forDesktop */);
mRemoteTargetHandles = gluer.assignTargetsForDesktop(recentsAnimationTargets);
@@ -5298,8 +5279,6 @@
cleanupRemoteTargets();
if (mRecentsAnimationController == null) {
- Log.d(TestProtocol.INCORRECT_HOME_STATE, "finish recents animation but recents "
- + "animation controller was null. returning.");
if (onFinishComplete != null) {
onFinishComplete.run();
}
@@ -5412,7 +5391,7 @@
}
private int getFirstViewIndex() {
- if (DesktopTaskView.DESKTOP_IS_PROTO2_ENABLED && mDesktopTaskView != null) {
+ if (isDesktopModeSupported() && mDesktopTaskView != null) {
// Desktop task is at position 0, that is the first view
return 0;
}
@@ -5799,6 +5778,11 @@
return null;
}
+ @Nullable
+ protected DesktopRecentsTransitionController getDesktopRecentsController() {
+ return mDesktopRecentsTransitionController;
+ }
+
/** Enables or disables modal state for RecentsView */
public abstract void setModalStateEnabled(int taskId, boolean animate);
@@ -5968,6 +5952,13 @@
dispatchScrollChanged();
}
+ @Override
+ protected boolean shouldHandleRequestChildFocus() {
+ // If we are already scrolling to a task view, then the focus request has already been
+ // handled
+ return mScroller.isFinished();
+ }
+
private void dispatchScrollChanged() {
runActionOnRemoteHandles(remoteTargetHandle ->
remoteTargetHandle.getTaskViewSimulator().setScroll(getScrollOffset()));
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 4ca02e0..e8f06ee 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -99,7 +99,7 @@
private void init() {
mTextView = findViewById(R.id.split_instructions_text);
- if (!FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (!FeatureFlags.enableSplitContextually()) {
mTextView.setCompoundDrawables(null, null, null, null);
return;
}
@@ -138,7 +138,7 @@
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
- if (!FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (!FeatureFlags.enableSplitContextually()) {
return;
}
@@ -150,7 +150,7 @@
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
- if (!FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (!FeatureFlags.enableSplitContextually()) {
return super.performAccessibilityAction(action, arguments);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index b4d24e5..8f12909 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -16,6 +16,8 @@
package com.android.quickstep.views;
+import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
import android.animation.Animator;
@@ -24,6 +26,7 @@
import android.content.Context;
import android.graphics.Outline;
import android.graphics.Rect;
+import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.util.AttributeSet;
@@ -58,16 +61,19 @@
private static final Rect sTempRect = new Rect();
- private static final int REVEAL_OPEN_DURATION = 150;
- private static final int REVEAL_CLOSE_DURATION = 100;
+ private static final int REVEAL_OPEN_DURATION = enableOverviewIconMenu() ? 417 : 150;
+ private static final int REVEAL_CLOSE_DURATION = enableOverviewIconMenu() ? 333 : 100;
private BaseDraggingActivity mActivity;
private TextView mTaskName;
@Nullable
private AnimatorSet mOpenCloseAnimator;
+ @Nullable private Runnable mOnClosingStartCallback;
private TaskView mTaskView;
private TaskIdAttributeContainer mTaskContainer;
private LinearLayout mOptionLayout;
+ private float mMenuTranslationYBeforeOpen;
+ private float mIconViewTranslationYBeforeOpen;
public TaskMenuView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -137,14 +143,20 @@
}
}
- public static boolean showForTask(TaskIdAttributeContainer taskContainer) {
+ public static boolean showForTask(TaskIdAttributeContainer taskContainer,
+ @Nullable Runnable onClosingStartCallback) {
BaseDraggingActivity activity = BaseDraggingActivity.fromContext(
taskContainer.getTaskView().getContext());
final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
R.layout.task_menu, activity.getDragLayer(), false);
+ taskMenuView.setOnClosingStartCallback(onClosingStartCallback);
return taskMenuView.populateAndShowForTask(taskContainer);
}
+ public static boolean showForTask(TaskIdAttributeContainer taskContainer) {
+ return showForTask(taskContainer, null);
+ }
+
private boolean populateAndShowForTask(TaskIdAttributeContainer taskContainer) {
if (isAttachedToWindow()) {
return false;
@@ -171,8 +183,12 @@
}
private void addMenuOptions(TaskIdAttributeContainer taskContainer) {
- mTaskName.setText(TaskUtils.getTitle(getContext(), taskContainer.getTask()));
- mTaskName.setOnClickListener(v -> close(true));
+ if (enableOverviewIconMenu()) {
+ removeView(mTaskName);
+ } else {
+ mTaskName.setText(TaskUtils.getTitle(getContext(), taskContainer.getTask()));
+ mTaskName.setOnClickListener(v -> close(true));
+ }
TaskOverlayFactory.getEnabledShortcuts(mTaskView, taskContainer)
.forEach(this::addMenuOption);
}
@@ -180,6 +196,9 @@
private void addMenuOption(SystemShortcut menuOption) {
LinearLayout menuOptionView = (LinearLayout) mActivity.getLayoutInflater().inflate(
R.layout.task_view_menu_option, this, false);
+ if (enableOverviewIconMenu()) {
+ ((GradientDrawable) menuOptionView.getBackground()).setCornerRadius(0);
+ }
menuOption.setIconAndLabelFor(
menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
@@ -198,8 +217,9 @@
// Get Position
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskContainer.getThumbnailView(),
- sTempRect);
+ mActivity.getDragLayer().getDescendantRectRelativeToSelf(
+ enableOverviewIconMenu() ? taskContainer.getIconView().asView()
+ : taskContainer.getThumbnailView(), sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
int padding = getResources()
@@ -217,12 +237,17 @@
ShapeDrawable divider = new ShapeDrawable(new RectShape());
divider.getPaint().setColor(getResources().getColor(android.R.color.transparent));
int dividerSpacing = (int) getResources().getDimension(R.dimen.task_menu_spacing);
- mOptionLayout.setShowDividers(SHOW_DIVIDER_MIDDLE);
+ mOptionLayout.setShowDividers(
+ enableOverviewIconMenu() ? SHOW_DIVIDER_NONE : SHOW_DIVIDER_MIDDLE);
orientationHandler.setTaskOptionsMenuLayoutOrientation(
deviceProfile, mOptionLayout, dividerSpacing, divider);
- float thumbnailAlignedX = sTempRect.left - insets.left;
- float thumbnailAlignedY = sTempRect.top - insets.top;
+ float thumbnailAlignedX = sTempRect.left - insets.left + (enableOverviewIconMenu()
+ ? -getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_touch_max_margin) : 0);
+ float thumbnailAlignedY = sTempRect.top - insets.top + (enableOverviewIconMenu()
+ ? getResources().getDimensionPixelSize(R.dimen.task_thumbnail_icon_menu_max_height)
+ - 2 * dividerSpacing : 0);
// Changing pivot to make computations easier
// NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set,
// which would render the X and Y position set here incorrect
@@ -231,15 +256,22 @@
setRotation(orientationHandler.getDegreesRotated());
// Margin that insets the menuView inside the taskView
- float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
+ float taskInsetMargin =
+ enableOverviewIconMenu() ? getResources().getDimension(
+ R.dimen.task_thumbnail_icon_menu_margin) : getResources().getDimension(
+ R.dimen.task_card_margin);
setTranslationX(orientationHandler.getTaskMenuX(thumbnailAlignedX,
- mTaskContainer.getThumbnailView(), deviceProfile, taskInsetMargin));
+ mTaskContainer.getThumbnailView(), deviceProfile, taskInsetMargin,
+ mTaskContainer.getIconView().asView()));
setTranslationY(orientationHandler.getTaskMenuY(
thumbnailAlignedY, mTaskContainer.getThumbnailView(),
- mTaskContainer.getStagePosition(), this, taskInsetMargin));
+ mTaskContainer.getStagePosition(), this, taskInsetMargin,
+ mTaskContainer.getIconView().asView()));
}
private void animateOpen() {
+ mMenuTranslationYBeforeOpen = getTranslationY();
+ mIconViewTranslationYBeforeOpen = mTaskContainer.getIconView().asView().getTranslationY();
animateOpenOrClosed(false);
mIsOpen = true;
}
@@ -256,7 +288,29 @@
final Animator revealAnimator = createOpenCloseOutlineProvider()
.createRevealAnimator(this, closing);
- revealAnimator.setInterpolator(Interpolators.DECELERATE);
+ revealAnimator.setInterpolator(enableOverviewIconMenu() ? Interpolators.EMPHASIZED
+ : Interpolators.DECELERATE);
+
+ if (enableOverviewIconMenu()
+ && ((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
+ float taskBottom = mTaskView.getHeight() + mTaskView.getPersistentTranslationY();
+ float menuBottom = getHeight() + mMenuTranslationYBeforeOpen;
+ float additionalTranslationY = Math.max(menuBottom - taskBottom, 0);
+
+ ObjectAnimator translationYAnim = ObjectAnimator.ofFloat(this, TRANSLATION_Y,
+ closing ? mMenuTranslationYBeforeOpen
+ : mMenuTranslationYBeforeOpen - additionalTranslationY);
+ translationYAnim.setInterpolator(EMPHASIZED);
+
+ ObjectAnimator menuTranslationYAnim = ObjectAnimator.ofFloat(
+ mTaskContainer.getIconView().asView(), TRANSLATION_Y,
+ closing ? mIconViewTranslationYBeforeOpen
+ : mIconViewTranslationYBeforeOpen - additionalTranslationY);
+ menuTranslationYAnim.setInterpolator(EMPHASIZED);
+
+ mOpenCloseAnimator.playTogether(translationYAnim, menuTranslationYAnim);
+ }
+
mOpenCloseAnimator.playTogether(revealAnimator,
ObjectAnimator.ofFloat(
mTaskContainer.getThumbnailView(), DIM_ALPHA,
@@ -266,6 +320,9 @@
@Override
public void onAnimationStart(Animator animation) {
setVisibility(VISIBLE);
+ if (closing && mOnClosingStartCallback != null) {
+ mOnClosingStartCallback.run();
+ }
}
@Override
@@ -286,9 +343,16 @@
private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() {
float radius = TaskCornerRadius.get(mContext);
- Rect fromRect = new Rect(0, 0, getWidth(), 0);
+ Rect fromRect = new Rect(
+ enableOverviewIconMenu() && isLayoutRtl() ? getWidth() : 0,
+ 0,
+ enableOverviewIconMenu() && !isLayoutRtl() ? 0 : getWidth(),
+ 0);
Rect toRect = new Rect(0, 0, getWidth(), getHeight());
return new RoundedRectRevealOutlineProvider(radius, radius, fromRect, toRect);
}
+ private void setOnClosingStartCallback(Runnable onClosingStartCallback) {
+ mOnClosingStartCallback = onClosingStartCallback;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
index b373911..12b8b6f 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
@@ -106,7 +106,7 @@
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
override fun getTargetObjectLocation(outPos: Rect?) {
- popupContainer.getDescendantRectRelativeToSelf(taskContainer.iconView, outPos)
+ popupContainer.getDescendantRectRelativeToSelf(taskContainer.iconView.asView(), outPos)
}
override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index f746203..dff0580 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -558,13 +558,12 @@
.getRecentsActivityRotation();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData,
- getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx,
- dp.taskbarHeight, dp.isTablet, currentRotation, isRtl);
+ getMeasuredWidth(), getMeasuredHeight(), dp.isTablet, currentRotation, isRtl);
mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix());
mPaint.setShader(mBitmapShader);
}
- getTaskView().updateCurrentFullscreenParams(mPreviewPositionHelper);
+ getTaskView().updateCurrentFullscreenParams();
invalidate();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 39b6c62..94183c4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -23,6 +23,8 @@
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
import static com.android.app.animation.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.app.animation.Interpolators.LINEAR;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
@@ -34,6 +36,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
import static com.android.quickstep.TaskOverlayFactory.getEnabledShortcuts;
import static com.android.quickstep.util.BorderAnimator.DEFAULT_BORDER_COLOR;
+import static com.android.quickstep.views.DesktopTaskView.isDesktopModeSupported;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -63,6 +66,7 @@
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -75,6 +79,7 @@
import com.android.app.animation.Interpolators;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -107,10 +112,8 @@
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.TaskCornerRadius;
import com.android.quickstep.util.TaskRemovedDuringLaunchListener;
-import com.android.quickstep.util.TransformParams;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -122,6 +125,8 @@
import java.util.function.Consumer;
import java.util.stream.Stream;
+import kotlin.Unit;
+
/**
* A task in the Recents view.
*/
@@ -352,7 +357,7 @@
@Nullable
protected Task mTask;
protected TaskThumbnailView mSnapshotView;
- protected IconView mIconView;
+ protected TaskViewIcon mIconView;
protected final DigitalWellBeingToast mDigitalWellBeingToast;
protected float mFullscreenProgress;
private float mGridProgress;
@@ -380,6 +385,7 @@
// switch.
private float mNonGridTranslationX;
private float mNonGridTranslationY;
+ private float mNonGridPivotTranslationX;
// Used when in SplitScreenSelectState
private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX;
@@ -441,49 +447,45 @@
mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
- || DesktopTaskView.DESKTOP_MODE_SUPPORTED;
+ || isDesktopModeSupported();
+ boolean cursorHoverStatesEnabled = enableCursorHoverStates();
- boolean willDrawBorder =
- keyboardFocusHighlightEnabled || FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get();
- setWillNotDraw(!willDrawBorder);
+ setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled);
- if (willDrawBorder) {
- TypedArray styledAttrs = context.obtainStyledAttributes(
- attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);
+ TypedArray styledAttrs = context.obtainStyledAttributes(
+ attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);
- mFocusBorderAnimator = keyboardFocusHighlightEnabled ? new BorderAnimator(
- /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
- /* borderColor= */ styledAttrs.getColor(
- R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR),
- /* borderAnimationParams= */ new BorderAnimator.SimpleParams(
- /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
- R.dimen.keyboard_quick_switch_border_width),
- /* boundsBuilder= */ this::updateBorderBounds,
- /* targetView= */ this)) : null;
+ mFocusBorderAnimator = keyboardFocusHighlightEnabled
+ ? BorderAnimator.createSimpleBorderAnimator(
+ /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
+ /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_border_width),
+ /* boundsBuilder= */ this::updateBorderBounds,
+ /* targetView= */ this,
+ /* borderColor= */ styledAttrs.getColor(
+ R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR))
+ : null;
- mHoverBorderAnimator =
- FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get() ? new BorderAnimator(
- /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
- /* borderColor= */ styledAttrs.getColor(
- R.styleable.TaskView_hoverBorderColor, DEFAULT_BORDER_COLOR),
- /* borderAnimationParams= */ new BorderAnimator.SimpleParams(
- /* borderWidthPx= */ context.getResources()
- .getDimensionPixelSize(R.dimen.task_hover_border_width),
- /* boundsBuilder= */ this::updateBorderBounds,
- /* targetView= */ this)) : null;
+ mHoverBorderAnimator = cursorHoverStatesEnabled
+ ? BorderAnimator.createSimpleBorderAnimator(
+ /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
+ /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
+ R.dimen.task_hover_border_width),
+ /* boundsBuilder= */ this::updateBorderBounds,
+ /* targetView= */ this,
+ /* borderColor= */ styledAttrs.getColor(
+ R.styleable.TaskView_hoverBorderColor, DEFAULT_BORDER_COLOR))
+ : null;
- styledAttrs.recycle();
- } else {
- mFocusBorderAnimator = null;
- mHoverBorderAnimator = null;
- }
+ styledAttrs.recycle();
}
- protected void updateBorderBounds(Rect bounds) {
+ protected Unit updateBorderBounds(@NonNull Rect bounds) {
bounds.set(mSnapshotView.getLeft() + Math.round(mSnapshotView.getTranslationX()),
mSnapshotView.getTop() + Math.round(mSnapshotView.getTranslationY()),
mSnapshotView.getRight() + Math.round(mSnapshotView.getTranslationX()),
mSnapshotView.getBottom() + Math.round(mSnapshotView.getTranslationY()));
+ return Unit.INSTANCE;
}
public void setTaskViewId(int id) {
@@ -523,27 +525,35 @@
protected void onFinishInflate() {
super.onFinishInflate();
mSnapshotView = findViewById(R.id.snapshot);
- mIconView = findViewById(R.id.icon);
- mIconTouchDelegate = new TransformingTouchDelegate(mIconView);
+ ViewStub iconViewStub = findViewById(R.id.icon);
+ if (enableOverviewIconMenu()) {
+ iconViewStub.setLayoutResource(R.layout.icon_app_chip_view);
+ } else {
+ iconViewStub.setLayoutResource(R.layout.icon_view);
+ }
+ mIconView = (TaskViewIcon) iconViewStub.inflate();
+ mIconTouchDelegate = new TransformingTouchDelegate(mIconView.asView());
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
if (mFocusBorderAnimator != null) {
- mFocusBorderAnimator.buildAnimator(gainFocus).start();
+ mFocusBorderAnimator.setBorderVisibility(gainFocus, /* animated= */ true);
}
}
@Override
public boolean onHoverEvent(MotionEvent event) {
- if (FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get()) {
+ if (mHoverBorderAnimator != null) {
switch (event.getAction()) {
case MotionEvent.ACTION_HOVER_ENTER:
- mHoverBorderAnimator.buildAnimator(/* isAppearing= */ true).start();
+ mHoverBorderAnimator.setBorderVisibility(
+ /* visible= */ true, /* animated= */ true);
break;
case MotionEvent.ACTION_HOVER_EXIT:
- mHoverBorderAnimator.buildAnimator(/* isAppearing= */ false).start();
+ mHoverBorderAnimator.setBorderVisibility(
+ /* visible= */ false, /* animated= */ true);
break;
default:
break;
@@ -554,7 +564,7 @@
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
- if (FeatureFlags.ENABLE_CURSOR_HOVER_STATES.get()) {
+ if (enableCursorHoverStates()) {
// avoid triggering hover event on child elements which would cause HOVER_EXIT for this
// task view
return true;
@@ -565,14 +575,14 @@
@Override
public void draw(Canvas canvas) {
- super.draw(canvas);
+ // Draw border first so any child views outside of the thumbnail bounds are drawn above it.
if (mFocusBorderAnimator != null) {
mFocusBorderAnimator.drawBorder(canvas);
}
-
if (mHoverBorderAnimator != null) {
mHoverBorderAnimator.drawBorder(canvas);
}
+ super.draw(canvas);
}
/**
@@ -589,17 +599,22 @@
return false;
}
- protected void computeAndSetIconTouchDelegate(IconView iconView, float[] tempCenterCoords,
+ protected void computeAndSetIconTouchDelegate(TaskViewIcon view, float[] tempCenterCoords,
TransformingTouchDelegate transformingTouchDelegate) {
- float iconHalfSize = iconView.getWidth() / 2f;
- tempCenterCoords[0] = tempCenterCoords[1] = iconHalfSize;
- getDescendantCoordRelativeToAncestor(iconView, mActivity.getDragLayer(), tempCenterCoords,
- false);
+ if (view == null) {
+ return;
+ }
+ float viewHalfWidth = view.getWidth() / 2f;
+ float viewHalfHeight = view.getHeight() / 2f;
+ tempCenterCoords[0] = viewHalfWidth;
+ tempCenterCoords[1] = viewHalfHeight;
+ getDescendantCoordRelativeToAncestor(view.asView(), mActivity.getDragLayer(),
+ tempCenterCoords, false);
transformingTouchDelegate.setBounds(
- (int) (tempCenterCoords[0] - iconHalfSize),
- (int) (tempCenterCoords[1] - iconHalfSize),
- (int) (tempCenterCoords[0] + iconHalfSize),
- (int) (tempCenterCoords[1] + iconHalfSize));
+ (int) (tempCenterCoords[0] - viewHalfWidth),
+ (int) (tempCenterCoords[1] - viewHalfHeight),
+ (int) (tempCenterCoords[0] + viewHalfWidth),
+ (int) (tempCenterCoords[1] + viewHalfHeight));
}
/**
@@ -631,8 +646,8 @@
cancelPendingLoadTasks();
mTask = task;
mTaskIdContainer[0] = mTask.key.id;
- mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView,
- mIconView, STAGE_POSITION_UNDEFINED);
+ mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView, mIconView,
+ STAGE_POSITION_UNDEFINED);
mSnapshotView.bind(task);
setOrientationState(orientedState);
}
@@ -747,7 +762,7 @@
return new TaskThumbnailView[]{mSnapshotView};
}
- public IconView getIconView() {
+ public TaskViewIcon getIconView() {
return mIconView;
}
@@ -976,19 +991,17 @@
if (remoteTargetHandles.length == 1) {
targets = remoteTargetHandles[0].getTransformParams().getTargetSet();
} else {
- TransformParams topLeftParams = remoteTargetHandles[0].getTransformParams();
- TransformParams rightBottomParams = remoteTargetHandles[1].getTransformParams();
- RemoteAnimationTarget[] apps = Stream.concat(
- Arrays.stream(topLeftParams.getTargetSet().apps),
- Arrays.stream(rightBottomParams.getTargetSet().apps))
+ RemoteAnimationTarget[] apps = Arrays.stream(remoteTargetHandles)
+ .flatMap(handle -> Stream.of(
+ handle.getTransformParams().getTargetSet().apps))
.toArray(RemoteAnimationTarget[]::new);
- RemoteAnimationTarget[] wallpapers = Stream.concat(
- Arrays.stream(topLeftParams.getTargetSet().wallpapers),
- Arrays.stream(rightBottomParams.getTargetSet().wallpapers))
+ RemoteAnimationTarget[] wallpapers = Arrays.stream(remoteTargetHandles)
+ .flatMap(handle -> Stream.of(
+ handle.getTransformParams().getTargetSet().wallpapers))
.toArray(RemoteAnimationTarget[]::new);
targets = new RemoteAnimationTargets(apps, wallpapers,
- topLeftParams.getTargetSet().nonApps,
- topLeftParams.getTargetSet().targetMode);
+ remoteTargetHandles[0].getTransformParams().getTargetSet().nonApps,
+ remoteTargetHandles[0].getTransformParams().getTargetSet().targetMode);
}
if (targets == null) {
// If the recents animation is cancelled somehow between the parent if block and
@@ -1082,6 +1095,9 @@
mIconLoadRequest = iconCache.updateIconInBackground(mTask,
(task) -> {
setIcon(mIconView, task.icon);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView, task.title);
+ }
mDigitalWellBeingToast.initialize(task);
});
}
@@ -1097,6 +1113,9 @@
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
setIcon(mIconView, null);
+ if (enableOverviewIconMenu()) {
+ setText(mIconView, null);
+ }
}
}
}
@@ -1116,7 +1135,7 @@
}
}
- private boolean showTaskMenu(IconView iconView) {
+ private boolean showTaskMenu(TaskViewIcon iconView) {
if (!getRecentsView().canLaunchFullscreenTask()) {
// Don't show menu when selecting second split screen app
return true;
@@ -1133,14 +1152,19 @@
}
}
- protected boolean showTaskMenuWithContainer(IconView iconView) {
+ protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
TaskIdAttributeContainer menuContainer =
mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
DeviceProfile dp = mActivity.getDeviceProfile();
- if (dp.isTablet) {
+ if (enableOverviewIconMenu() && iconView instanceof IconAppChipView) {
+ ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ true);
+ return TaskMenuView.showForTask(menuContainer, () -> {
+ ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ false);
+ });
+ } else if (dp.isTablet) {
int alignedOptionIndex = 0;
if (getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && dp.isLandscape) {
- if (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()) {
+ if (Flags.enableGridOnlyOverview()) {
// With no focused task, there is less available space below the tasks, so align
// the arrow to the third option in the menu.
alignedOptionIndex = 2;
@@ -1149,13 +1173,14 @@
alignedOptionIndex = 1;
}
}
- return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignedOptionIndex);
+ return TaskMenuViewWithArrow.Companion.showForTask(menuContainer,
+ alignedOptionIndex);
} else {
return TaskMenuView.showForTask(menuContainer);
}
}
- protected void setIcon(IconView iconView, @Nullable Drawable icon) {
+ protected void setIcon(TaskViewIcon iconView, @Nullable Drawable icon) {
if (icon != null) {
iconView.setDrawable(icon);
iconView.setOnClickListener(v -> {
@@ -1175,32 +1200,13 @@
}
}
- public void setOrientationState(RecentsOrientedState orientationState) {
- setIconOrientation(orientationState);
- setThumbnailOrientation(orientationState);
+ protected void setText(TaskViewIcon iconView, CharSequence text) {
+ iconView.setText(text);
}
- protected void setIconOrientation(RecentsOrientedState orientationState) {
- PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
- boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-
- boolean isGridTask = isGridTask();
- LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
-
- int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
- int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
- int taskMargin = deviceProfile.overviewTaskMarginPx;
-
- orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconHeight,
- thumbnailTopMargin, isRtl);
- iconParams.width = iconParams.height = taskIconHeight;
- mIconView.setLayoutParams(iconParams);
-
- mIconView.setRotation(orientationHandler.getDegreesRotated());
- int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
- : deviceProfile.overviewTaskIconDrawableSizePx;
- mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
+ public void setOrientationState(RecentsOrientedState orientationState) {
+ mIconView.setIconOrientation(orientationState, isGridTask());
+ setThumbnailOrientation(orientationState);
}
protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
@@ -1280,8 +1286,8 @@
}
protected void resetPersistentViewTransforms() {
- mNonGridTranslationX = mNonGridTranslationY =
- mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
+ mNonGridTranslationX = mNonGridTranslationY = mGridTranslationX =
+ mGridTranslationY = mBoxTranslationY = mNonGridPivotTranslationX = 0f;
resetViewTransforms();
}
@@ -1483,6 +1489,14 @@
applyTranslationX();
}
+ /**
+ * Set translation X for non-grid pivot
+ */
+ public void setNonGridPivotTranslationX(float nonGridPivotTranslationX) {
+ mNonGridPivotTranslationX = nonGridPivotTranslationX;
+ applyTranslationX();
+ }
+
public float getScrollAdjustment(boolean gridEnabled) {
float scrollAdjustment = 0;
if (gridEnabled) {
@@ -1525,7 +1539,8 @@
* change according to a temporary state (e.g. task offset).
*/
public float getPersistentTranslationX() {
- return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX);
+ return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX)
+ + getNonGridTrans(mNonGridPivotTranslationX);
}
/**
@@ -1673,6 +1688,7 @@
return super.performAccessibilityAction(action, arguments);
}
+ @Nullable
public RecentsView getRecentsView() {
return (RecentsView) getParent();
}
@@ -1711,21 +1727,20 @@
}
protected void updateSnapshotRadius() {
- updateCurrentFullscreenParams(mSnapshotView.getPreviewPositionHelper());
+ updateCurrentFullscreenParams();
mSnapshotView.setFullscreenParams(mCurrentFullscreenParams);
}
- void updateCurrentFullscreenParams(PreviewPositionHelper previewPositionHelper) {
- updateFullscreenParams(mCurrentFullscreenParams, previewPositionHelper);
+ void updateCurrentFullscreenParams() {
+ updateFullscreenParams(mCurrentFullscreenParams);
}
- protected void updateFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams,
- PreviewPositionHelper previewPositionHelper) {
+ protected void updateFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
if (getRecentsView() == null) {
return;
}
fullscreenParams.setProgress(mFullscreenProgress, getRecentsView().getScaleX(),
- getScaleX(), getWidth(), mActivity.getDeviceProfile(), previewPositionHelper);
+ getScaleX());
}
/**
@@ -1896,8 +1911,7 @@
/**
* Sets the progress in range [0, 1]
*/
- public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
- int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
+ public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale) {
mCurrentDrawnCornerRadius =
Utilities.mapRange(fullscreenProgress, mCornerRadius, mWindowCornerRadius)
/ parentScale / taskViewScale;
@@ -1907,14 +1921,14 @@
public class TaskIdAttributeContainer {
private final TaskThumbnailView mThumbnailView;
private final Task mTask;
- private final IconView mIconView;
+ private final TaskViewIcon mIconView;
/** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */
private @SplitConfigurationOptions.StagePosition int mStagePosition;
@IdRes
private final int mA11yNodeId;
public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView,
- IconView iconView, int stagePosition) {
+ TaskViewIcon iconView, int stagePosition) {
this.mTask = task;
this.mThumbnailView = thumbnailView;
this.mIconView = iconView;
@@ -1939,7 +1953,7 @@
return TaskView.this;
}
- public IconView getIconView() {
+ public TaskViewIcon getIconView() {
return mIconView;
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskViewIcon.java b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
new file mode 100644
index 0000000..b4f21be
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/TaskViewIcon.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import android.annotation.Nullable;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.quickstep.util.RecentsOrientedState;
+
+/**
+ * Interface defining an object which can be used as a TaskView's icon.
+ */
+public interface TaskViewIcon {
+
+ /**
+ * Returns the width of this icon view.
+ */
+ int getWidth();
+
+ /**
+ * Returns the height of this icon view.
+ */
+ int getHeight();
+
+ /**
+ * Sets the opacity of the view.
+ */
+ void setAlpha(float alpha);
+
+ /**
+ * Returns this icon view's drawable.
+ */
+ @Nullable Drawable getDrawable();
+
+ /**
+ * Sets a {@link Drawable} to be displayed.
+ */
+ void setDrawable(@Nullable Drawable icon);
+
+ /**
+ * Register a callback to be invoked when this view is clicked.
+ */
+ void setOnClickListener(@Nullable View.OnClickListener l);
+
+ /**
+ * Register a callback to be invoked when this view is clicked and held.
+ */
+ void setOnLongClickListener(@Nullable View.OnLongClickListener l);
+
+ /**
+ * Returns the LayoutParams associated with this view.
+ */
+ ViewGroup.LayoutParams getLayoutParams();
+
+ /**
+ * Sets the layout parameters associated with this view.
+ */
+ void setLayoutParams(ViewGroup.LayoutParams params);
+
+ /**
+ * Sets the degrees that the view is rotated around the pivot point.
+ */
+ void setRotation(float rotation);
+
+ /**
+ * Sets the size of the icon drawable.
+ */
+ void setDrawableSize(int iconWidth, int iconHeight);
+
+ /**
+ * Sets the orientation of this icon view based on the provided orientationState.
+ */
+ void setIconOrientation(RecentsOrientedState orientationState, boolean isGridTask);
+
+ /**
+ * Sets the visibility state of this view.
+ */
+ void setVisibility(int visibility);
+
+ /**
+ * Sets the tint color of the icon, useful for scrimming or dimming.
+ *
+ * @param color to blend in.
+ * @param amount [0,1] 0 no tint, 1 full tint
+ */
+ void setIconColorTint(int color, float amount);
+
+ /**
+ * Gets the opacity of the view.
+ */
+ float getAlpha();
+
+ /**
+ * Returns the width of this icon view's drawable.
+ */
+ int getDrawableWidth();
+
+ /**
+ * Returns the height of this icon view's drawable.
+ */
+ int getDrawableHeight();
+
+ /**
+ * Directly calls any attached OnClickListener.
+ */
+ boolean callOnClick();
+
+ /**
+ * Calls this view's OnLongClickListener.
+ */
+ boolean performLongClick();
+
+ /**
+ * Sets the text for this icon view if any text view is associated.
+ */
+ default void setText(CharSequence text) {}
+
+ /**
+ * Returns this icon view cast as a View.
+ */
+ View asView();
+}
diff --git a/quickstep/tests/OWNERS b/quickstep/tests/OWNERS
index 02e8ebc..c271803 100644
--- a/quickstep/tests/OWNERS
+++ b/quickstep/tests/OWNERS
@@ -2,3 +2,4 @@
sunnygoyal@google.com
winsonc@google.com
hyunyoungs@google.com
+mateuszc@google.com
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
index 8c13fe3..f3115c6 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/FallbackTaskbarUIControllerTest.kt
@@ -24,11 +24,11 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.Mock
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class FallbackTaskbarUIControllerTest : TaskbarBaseTestCase() {
@@ -36,8 +36,8 @@
lateinit var fallbackTaskbarUIController: FallbackTaskbarUIController
lateinit var stateListener: StateManager.StateListener<RecentsState>
- @Mock lateinit var recentsActivity: RecentsActivity
- @Mock lateinit var stateManager: StateManager<RecentsState>
+ private val recentsActivity: RecentsActivity = mock()
+ private val stateManager: StateManager<RecentsState> = mock()
@Before
override fun setup() {
@@ -46,10 +46,10 @@
fallbackTaskbarUIController = FallbackTaskbarUIController(recentsActivity)
// Capture registered state listener to send events to in our tests
- val captor = ArgumentCaptor.forClass(StateManager.StateListener::class.java)
+ val captor = argumentCaptor<StateManager.StateListener<RecentsState>>()
fallbackTaskbarUIController.init(taskbarControllers)
verify(stateManager).addStateListener(captor.capture())
- stateListener = captor.value as StateManager.StateListener<RecentsState>
+ stateListener = captor.lastValue
}
@Test
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
index 2c16c15..15b1e53 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarBaseTestCase.kt
@@ -55,7 +55,7 @@
@Mock lateinit var taskbarOverlayController: TaskbarOverlayController
@Mock lateinit var taskbarEduTooltipController: TaskbarEduTooltipController
@Mock lateinit var keyboardQuickSwitchController: KeyboardQuickSwitchController
- @Mock lateinit var taskbarPinningController: TaskbarDividerPopupController
+ @Mock lateinit var taskbarPinningController: TaskbarPinningController
@Mock lateinit var optionalBubbleControllers: Optional<BubbleControllers>
lateinit var taskbarControllers: TaskbarControllers
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
index 6c0d44d..9ed3906 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarHoverToolTipControllerTest.java
@@ -18,7 +18,6 @@
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS;
-import static com.android.launcher3.taskbar.TaskbarHoverToolTipController.HOVER_TOOL_TIP_REVEAL_START_DELAY;
import static com.google.common.truth.Truth.assertThat;
@@ -27,7 +26,6 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -128,14 +126,11 @@
boolean hoverHandled =
mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent);
-
- // Verify fullscreen is not set until the delayed runnable to reveal the tooltip has run
- verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(true);
waitForIdleSync();
+
assertThat(hoverHandled).isTrue();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
- verify(taskbarActivityContext).setTaskbarWindowFullscreen(true);
}
@Test
@@ -159,14 +154,11 @@
boolean hoverHandled =
mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent);
-
- // Verify fullscreen is not set until the delayed runnable to reveal the tooltip has run
- verify(taskbarActivityContext, never()).setTaskbarWindowFullscreen(true);
waitForIdleSync();
+
assertThat(hoverHandled).isTrue();
verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS,
true);
- verify(taskbarActivityContext).setTaskbarWindowFullscreen(true);
}
@Test
@@ -222,7 +214,6 @@
}
private void waitForIdleSync() {
- mTestableLooper.moveTimeForward(HOVER_TOOL_TIP_REVEAL_START_DELAY + 1);
mTestableLooper.processAllMessages();
}
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
index 148e36c..ed88c29 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarKeyguardControllerTest.kt
@@ -23,17 +23,17 @@
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
import org.junit.Before
import org.junit.Test
-import org.mockito.Mock
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
class TaskbarKeyguardControllerTest : TaskbarBaseTestCase() {
- @Mock lateinit var baseDragLayer: TaskbarDragLayer
- @Mock lateinit var keyguardManager: KeyguardManager
+ private val baseDragLayer: TaskbarDragLayer = mock()
+ private val keyguardManager: KeyguardManager = mock()
@Before
override fun setup() {
@@ -50,7 +50,7 @@
@Test
fun uninterestingFlags_noActions() {
setFlags(0)
- verify(navbarButtonsViewController, never()).setKeyguardVisible(anyBoolean(), anyBoolean())
+ verify(navbarButtonsViewController, never()).setKeyguardVisible(any(), any())
}
@Test
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
index 3920b08..37fcf43 100644
--- a/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
+++ b/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
@@ -13,34 +13,35 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.R
import com.android.launcher3.taskbar.TaskbarManager
+import com.android.systemui.shared.rotation.RotationButton
import java.lang.IllegalStateException
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class NavButtonLayoutFactoryTest {
- @Mock lateinit var mockDeviceProfile: DeviceProfile
- @Mock lateinit var mockParentButtonContainer: FrameLayout
- @Mock lateinit var mockNavLayout: LinearLayout
- @Mock lateinit var mockStartContextualLayout: ViewGroup
- @Mock lateinit var mockEndContextualLayout: ViewGroup
- @Mock lateinit var mockResources: Resources
- @Mock lateinit var mockBackButton: ImageView
- @Mock lateinit var mockRecentsButton: ImageView
- @Mock lateinit var mockHomeButton: ImageView
+ private val mockDeviceProfile: DeviceProfile = mock()
+ private val mockParentButtonContainer: FrameLayout = mock()
+ private val mockNavLayout: LinearLayout = mock()
+ private val mockStartContextualLayout: ViewGroup = mock()
+ private val mockEndContextualLayout: ViewGroup = mock()
+ private val mockResources: Resources = mock()
+ private val mockBackButton: ImageView = mock()
+ private val mockRecentsButton: ImageView = mock()
+ private val mockHomeButton: ImageView = mock()
+ private val mockImeSwitcher: ImageView = mock()
+ private val mockRotationButton: RotationButton = mock()
+ private val mockA11yButton: ImageView = mock()
private var surfaceRotation = Surface.ROTATION_0
@Before
fun setup() {
- MockitoAnnotations.initMocks(this)
-
// Init end nav buttons
whenever(mockNavLayout.childCount).thenReturn(3)
whenever(mockNavLayout.findViewById<View>(R.id.back)).thenReturn(mockBackButton)
@@ -151,13 +152,13 @@
mockDeviceProfile.isTaskbarPresent = false
setDeviceProfileLandscape()
val layoutter: NavButtonLayoutFactory.NavButtonLayoutter =
- getLayoutter(
- isKidsMode = false,
- isInSetup = false,
- isThreeButtonNav = true,
- phoneMode = true,
- surfaceRotation = ROTATION_270
- )
+ getLayoutter(
+ isKidsMode = false,
+ isInSetup = false,
+ isThreeButtonNav = true,
+ phoneMode = true,
+ surfaceRotation = ROTATION_270
+ )
assert(layoutter is PhoneSeascapeNavLayoutter)
}
@@ -196,7 +197,10 @@
isInSetup = isInSetup,
isThreeButtonNav = isThreeButtonNav,
phoneMode = phoneMode,
- surfaceRotation = surfaceRotation
+ surfaceRotation = surfaceRotation,
+ imeSwitcher = mockImeSwitcher,
+ rotationButton = mockRotationButton,
+ a11yButton = mockA11yButton
)
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
index 9c6c93d..ba9ae67 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java
@@ -37,7 +37,6 @@
public class AbstractTaplTestsTaskbar extends AbstractQuickStepTest {
- protected static final String TEST_APP_NAME = "LauncherTestApp";
protected static final String TEST_APP_PACKAGE =
getInstrumentation().getContext().getPackageName();
protected static final String CALCULATOR_APP_PACKAGE =
@@ -95,6 +94,6 @@
launcher.enableTransientTaskbar(expectTransientTaskbar);
launcher.recreateTaskbar();
launcher.checkForAnomaly(true, true);
- AbstractLauncherUiTest.checkDetectedLeaks(launcher);
+ AbstractLauncherUiTest.checkDetectedLeaks(launcher, true);
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index a67d787..12568ea 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -32,8 +32,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification;
import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -57,10 +55,12 @@
import com.android.launcher3.tapl.OverviewTask;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
+import com.android.launcher3.util.rule.TestIsolationRule;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.launcher3.util.rule.ViewCaptureRule;
import com.android.quickstep.views.RecentsView;
@@ -94,9 +94,6 @@
public final TestRule mDisableHeadsUpNotification = disableHeadsUpNotification();
@Rule
- public final TestRule mSetLauncherCommand;
-
- @Rule
public final TestRule mOrderSensitiveRules;
@Rule
@@ -116,19 +113,7 @@
Utilities.enableRunningInTestHarnessForTests();
}
- final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
- RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
- mOrderSensitiveRules = RuleChain
- .outerRule(new SamplerRule())
- .around(new NavigationModeSwitchRule(mLauncher))
- .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
- .around(viewCaptureRule);
-
- mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
- getHomeIntentInPackage(context),
- MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
-
- mSetLauncherCommand = (base, desc) -> new Statement() {
+ final TestRule setLauncherCommand = (base, desc) -> new Statement() {
@Override
public void evaluate() throws Throwable {
TestCommandReceiver.callCommand(TestCommandReceiver.ENABLE_TEST_LAUNCHER);
@@ -151,6 +136,22 @@
}
}
};
+
+ final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
+ RecentsActivity.ACTIVITY_TRACKER::getCreatedActivity);
+ mOrderSensitiveRules = RuleChain
+ .outerRule(new SamplerRule())
+ .around(new TestStabilityRule())
+ .around(new NavigationModeSwitchRule(mLauncher))
+ .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
+ .around(viewCaptureRule)
+ .around(new TestIsolationRule(mLauncher, false))
+ .around(setLauncherCommand);
+
+ mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
+ getHomeIntentInPackage(context),
+ MATCH_DISABLED_COMPONENTS).get(0).activityInfo;
+
if (TestHelpers.isInLauncherProcess()) {
mLauncher.setSystemHealthSupplier(startTime -> TestCommandReceiver.callCommand(
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString()).
@@ -161,13 +162,15 @@
@Before
public void setUp() {
mLauncher.onTestStart();
+ AbstractLauncherUiTest.waitForSetupWizardDismissal();
+ AbstractLauncherUiTest.verifyKeyguardInvisible();
}
@After
public void tearDown() {
try {
// Limits UI tests affecting tests running after them.
- AbstractQuickStepTest.checkDetectedLeaks(mLauncher);
+ AbstractQuickStepTest.checkDetectedLeaks(mLauncher, true);
} finally {
mLauncher.onTestFinish();
}
@@ -175,7 +178,6 @@
// b/143488140
//@NavigationModeSwitch
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/266606727
@Test
public void goToOverviewFromHome() {
mDevice.pressHome();
@@ -223,7 +225,6 @@
// b/143488140
//@NavigationModeSwitch
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/266606727
@Test
public void testOverview() {
startAppFast(getAppPackageName());
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index bb1afdf..db06b6b 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -16,17 +16,13 @@
package com.android.quickstep
import android.content.Context
-import android.graphics.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.FakeInvariantDeviceProfileTest
import com.android.quickstep.util.TaskCornerRadius
import com.android.quickstep.views.TaskView.FullscreenDrawParams
-import com.android.systemui.shared.recents.model.ThumbnailData
-import com.android.systemui.shared.recents.utilities.PreviewPositionHelper
import com.android.systemui.shared.system.QuickStepContract
import com.google.common.truth.Truth.assertThat
-import kotlin.math.roundToInt
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -39,10 +35,6 @@
@RunWith(AndroidJUnit4::class)
class FullscreenDrawParamsTest : FakeInvariantDeviceProfileTest() {
- private val TASK_SCALE = 0.7f
- private var mThumbnailData: ThumbnailData = mock(ThumbnailData::class.java)
-
- private val mPreviewPositionHelper = PreviewPositionHelper()
private lateinit var params: FullscreenDrawParams
@Before
@@ -53,32 +45,11 @@
@Test
fun setStartProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = TaskCornerRadius.get(context)
@@ -88,32 +59,11 @@
@Test
fun setFullProgress_correctCornerRadiusForTablet() {
initializeVarsForTablet()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
@@ -123,32 +73,11 @@
@Test
fun setStartProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = TaskCornerRadius.get(context)
@@ -158,32 +87,11 @@
@Test
fun setFullProgress_correctCornerRadiusForPhone() {
initializeVarsForPhone()
- val dp = newDP()
- val previewRect = Rect(0, 0, 100, 100)
- val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt()
- val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt()
- val currentRotation = 0
- val isRtl = false
- mPreviewPositionHelper.updateThumbnailMatrix(
- previewRect,
- mThumbnailData,
- canvasWidth,
- canvasHeight,
- dp.widthPx,
- dp.heightPx,
- dp.taskbarHeight,
- dp.isTablet,
- currentRotation,
- isRtl
- )
params.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* previewWidth= */ 0,
- dp,
- mPreviewPositionHelper
+ /* taskViewScale= */ 1.0f
)
val expectedRadius = QuickStepContract.getWindowCornerRadius(context)
@@ -207,10 +115,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1TaskRadius)
@@ -218,10 +123,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2TaskRadius)
}
@@ -243,10 +145,7 @@
spyParams.setProgress(
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
- /* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
+ /* taskViewScale= */ 1.0f
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display1WindowRadius)
@@ -255,9 +154,6 @@
/* fullscreenProgress= */ 1.0f,
/* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f,
- /* unused previewWidth= */ -1,
- /* unusedDp= */ null,
- /* unused previewPositionHelper= */ null
)
assertThat(spyParams.mCurrentDrawnCornerRadius).isEqualTo(display2WindowRadius)
}
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index eded1c9..a5d7724 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -185,7 +185,7 @@
+ launcher.getNavigationModeMismatchError(false),
() -> launcher.getNavigationModeMismatchError(false) == null,
WAIT_TIME_MS, launcher);
- AbstractLauncherUiTest.checkDetectedLeaks(launcher);
+ AbstractLauncherUiTest.checkDetectedLeaks(launcher, true);
return true;
}
diff --git a/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java b/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
new file mode 100644
index 0000000..648fa93
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/RecentsModelTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.Flags;
+import com.android.launcher3.R;
+import com.android.launcher3.icons.IconProvider;
+import com.android.quickstep.util.GroupTask;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+@SmallTest
+public class RecentsModelTest {
+ @Mock
+ private Context mContext;
+
+ @Mock
+ private TaskThumbnailCache mThumbnailCache;
+
+ @Mock
+ private RecentTasksList mTasksList;
+
+ @Mock
+ private TaskThumbnailCache.HighResLoadingState mHighResLoadingState;
+
+ private RecentsModel mRecentsModel;
+
+ private RecentTasksList.TaskLoadResult mTaskResult;
+
+ private Resources mResource;
+
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ @Before
+ public void setup() throws NoSuchFieldException {
+ MockitoAnnotations.initMocks(this);
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_GRID_ONLY_OVERVIEW);
+ mTaskResult = getTaskResult();
+ doAnswer(invocation-> {
+ Consumer<ArrayList<GroupTask>> callback = invocation.getArgument(1);
+ callback.accept(mTaskResult);
+ return null;
+ }).when(mTasksList).getTaskKeys(anyInt(), any());
+
+ when(mHighResLoadingState.isEnabled()).thenReturn(true);
+ when(mThumbnailCache.getHighResLoadingState()).thenReturn(mHighResLoadingState);
+ when(mThumbnailCache.isPreloadingEnabled()).thenReturn(true);
+
+ mRecentsModel = new RecentsModel(mContext, mTasksList, mock(TaskIconCache.class),
+ mThumbnailCache, mock(IconProvider.class), mock(TaskStackChangeListeners.class));
+
+ mResource = mock(Resources.class);
+ when(mResource.getInteger((R.integer.recentsThumbnailCacheSize))).thenReturn(3);
+ when(mContext.getResources()).thenReturn(mResource);
+ }
+
+ @Test
+ @UiThreadTest
+ public void preloadOnHighResolutionEnabled() {
+ mRecentsModel.preloadCacheIfNeeded();
+
+ ArgumentCaptor<Task> taskArgs = ArgumentCaptor.forClass(Task.class);
+ verify(mRecentsModel.getThumbnailCache(), times(2))
+ .updateThumbnailInCache(taskArgs.capture(), /* lowResolution= */ eq(false));
+
+ GroupTask expectedGroupTask = mTaskResult.get(0);
+ assertThat(taskArgs.getAllValues().get(0)).isEqualTo(
+ expectedGroupTask.task1);
+ assertThat(taskArgs.getAllValues().get(1)).isEqualTo(
+ expectedGroupTask.task2);
+ }
+
+ @Test
+ public void notPreloadOnHighResolutionDisabled() {
+ when(mHighResLoadingState.isEnabled()).thenReturn(false);
+ when(mThumbnailCache.isPreloadingEnabled()).thenReturn(true);
+ mRecentsModel.preloadCacheIfNeeded();
+ verify(mRecentsModel.getThumbnailCache(), never())
+ .updateThumbnailInCache(any(), anyBoolean());
+ }
+
+ @Test
+ public void notPreloadOnPreloadDisabled() {
+ when(mThumbnailCache.isPreloadingEnabled()).thenReturn(false);
+ mRecentsModel.preloadCacheIfNeeded();
+ verify(mRecentsModel.getThumbnailCache(), never())
+ .updateThumbnailInCache(any(), anyBoolean());
+
+ }
+
+ @Test
+ public void increaseCacheSizeAndPreload() {
+ // Mock to return preload is needed
+ when(mThumbnailCache.updateCacheSizeAndRemoveExcess()).thenReturn(true);
+ // Update cache size
+ mRecentsModel.updateCacheSizeAndPreloadIfNeeded();
+ // Assert update cache is called
+ verify(mRecentsModel.getThumbnailCache(), times(2))
+ .updateThumbnailInCache(any(), /* lowResolution= */ eq(false));
+ }
+
+ @Test
+ public void decreaseCacheSizeAndNotPreload() {
+ // Mock to return preload is not needed
+ when(mThumbnailCache.updateCacheSizeAndRemoveExcess()).thenReturn(false);
+ // Update cache size
+ mRecentsModel.updateCacheSizeAndPreloadIfNeeded();
+ // Assert update cache is never called
+ verify(mRecentsModel.getThumbnailCache(), never())
+ .updateThumbnailInCache(any(), anyBoolean());
+ }
+
+ private RecentTasksList.TaskLoadResult getTaskResult() {
+ RecentTasksList.TaskLoadResult allTasks = new RecentTasksList.TaskLoadResult(0, false, 1);
+ ActivityManager.RecentTaskInfo taskInfo1 = new ActivityManager.RecentTaskInfo();
+ Task.TaskKey taskKey1 = new Task.TaskKey(taskInfo1);
+ Task task1 = Task.from(taskKey1, taskInfo1, false);
+
+ ActivityManager.RecentTaskInfo taskInfo2 = new ActivityManager.RecentTaskInfo();
+ Task.TaskKey taskKey2 = new Task.TaskKey(taskInfo2);
+ Task task2 = Task.from(taskKey2, taskInfo2, false);
+
+ allTasks.add(new GroupTask(task1, task2, null));
+ return allTasks;
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 20aa410..a89eab5 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -49,7 +49,6 @@
@Test
@NavigationModeSwitch
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/187761685
public void testStressPressHome() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
// Destroy Launcher activity.
diff --git a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconAppChipMenuTest.java b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconAppChipMenuTest.java
new file mode 100644
index 0000000..969da68
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconAppChipMenuTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import com.android.launcher3.Flags;
+import com.android.launcher3.InvariantDeviceProfile;
+
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * Tests the Icon App Chip Menu in overview.
+ *
+ * <p>Same tests as TaplOverviewIconTest with the Flag FLAG_ENABLE_OVERVIEW_ICON_MENU enabled.
+ * This class can be removed once FLAG_ENABLE_OVERVIEW_ICON_MENU is enabled by default.
+ */
+public class TaplOverviewIconAppChipMenuTest extends TaplOverviewIconTest {
+
+ @Before
+ public void setUp() throws Exception {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_OVERVIEW_ICON_MENU); // Call before super.setUp
+ super.setUp();
+ executeOnLauncher(launcher -> InvariantDeviceProfile.INSTANCE.get(launcher).onConfigChanged(
+ launcher));
+ }
+
+ @After
+ public void tearDown() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_OVERVIEW_ICON_MENU);
+ executeOnLauncher(launcher -> InvariantDeviceProfile.INSTANCE.get(launcher).onConfigChanged(
+ launcher));
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
new file mode 100644
index 0000000..f51f286
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.platform.test.annotations.PlatinumTest;
+
+import com.android.launcher3.tapl.OverviewTaskMenu;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Tests the app Icon in overview.
+ */
+public class TaplOverviewIconTest extends AbstractLauncherUiTest {
+
+ private static final String CALCULATOR_APP_PACKAGE =
+ resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testOverviewActionsMenu() {
+ startTestAppsWithCheck();
+
+ OverviewTaskMenu menu = mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
+
+ assertNotNull("Tapping App info menu item returned null", menu.tapAppInfoMenuItem());
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top",
+ isInLaunchedApp(launcher)));
+ }
+
+ private void startTestAppsWithCheck() {
+ startTestApps();
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top "
+ + "one",
+ isInLaunchedApp(launcher)));
+ }
+
+ private void startTestApps() {
+ startAppFast(getAppPackageName());
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ startTestActivity(2);
+ }
+
+ @Test
+ public void testSplitTaskTapBothIconMenus() {
+ createAndLaunchASplitPair();
+
+ OverviewTaskMenu taskMenu =
+ mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
+ assertTrue("App info item not appearing in expanded task menu.",
+ taskMenu.hasMenuItem("App info"));
+ taskMenu.touchOutsideTaskMenuToDismiss();
+
+ OverviewTaskMenu splitMenu =
+ mLauncher.goHome().switchToOverview().getCurrentTask().tapSplitTaskMenu();
+ assertTrue("App info item not appearing in expanded split task's menu.",
+ splitMenu.hasMenuItem("App info"));
+ splitMenu.touchOutsideTaskMenuToDismiss();
+ }
+
+ private void createAndLaunchASplitPair() {
+ startTestActivity(2);
+ startTestActivity(3);
+
+ if (mLauncher.isTablet() && !mLauncher.isGridOnlyOverviewEnabled()) {
+ mLauncher.goHome().switchToOverview().getOverviewActions()
+ .clickSplit()
+ .getTestActivityTask(2)
+ .open();
+ } else {
+ mLauncher.goHome().switchToOverview().getCurrentTask()
+ .tapMenu()
+ .tapSplitMenuItem()
+ .getCurrentTask()
+ .open();
+ }
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
new file mode 100644
index 0000000..74f37a4
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.content.Intent;
+
+import androidx.annotation.NonNull;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.tapl.KeyboardQuickSwitch;
+import com.android.launcher3.ui.TaplTestsLauncher3;
+
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TaplTestsKeyboardQuickSwitch extends AbstractQuickStepTest {
+
+ private enum TestSurface {
+ HOME, LAUNCHED_APP, HOME_ALL_APPS, WIDGETS,
+ }
+
+ private enum TestCase {
+ DISMISS(0),
+ LAUNCH_LAST_APP(0),
+ LAUNCH_SELECTED_APP(1),
+ LAUNCH_OVERVIEW(5);
+
+ private final int mNumAdditionalRunningTasks;
+
+ TestCase(int numAdditionalRunningTasks) {
+ mNumAdditionalRunningTasks = numAdditionalRunningTasks;
+ }
+ }
+
+ private static final String CALCULATOR_APP_PACKAGE =
+ resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
+
+ @Override
+ public void setUp() throws Exception {
+ Assume.assumeTrue(mLauncher.isTablet());
+ super.setUp();
+ TaplTestsLauncher3.initialize(this);
+ startAppFast(CALCULATOR_APP_PACKAGE);
+ startTestActivity(2);
+ }
+
+ @Test
+ public void testDismiss_fromHome() {
+ runTest(TestSurface.HOME, TestCase.DISMISS);
+ }
+
+ @Test
+ public void testDismiss_fromApp() {
+ runTest(TestSurface.LAUNCHED_APP, TestCase.DISMISS);
+ }
+
+ @Test
+ public void testDismiss_fromHomeAllApps() {
+ runTest(TestSurface.HOME_ALL_APPS, TestCase.DISMISS);
+ }
+
+ @Test
+ public void testDismiss_fromWidgets() {
+ runTest(TestSurface.WIDGETS, TestCase.DISMISS);
+ }
+
+ @Test
+ public void testLaunchLastTask_fromHome() {
+ runTest(TestSurface.HOME, TestCase.LAUNCH_LAST_APP);
+ }
+
+ @Test
+ public void testLaunchLastTask_fromApp() {
+ runTest(TestSurface.LAUNCHED_APP, TestCase.LAUNCH_LAST_APP);
+ }
+
+ @Test
+ public void testLaunchLastTask_fromHomeAllApps() {
+ runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_LAST_APP);
+ }
+
+ @Test
+ public void testLaunchLastTask_fromWidgets() {
+ runTest(TestSurface.WIDGETS, TestCase.LAUNCH_LAST_APP);
+ }
+
+ @Test
+ public void testLaunchSelectedTask_fromHome() {
+ runTest(TestSurface.HOME, TestCase.LAUNCH_SELECTED_APP);
+ }
+
+ @Test
+ public void testLaunchSelectedTask_fromApp() {
+ runTest(TestSurface.LAUNCHED_APP, TestCase.LAUNCH_SELECTED_APP);
+ }
+
+ @Test
+ public void testLaunchSelectedTask_fromHomeAllApps() {
+ runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_SELECTED_APP);
+ }
+
+ @Test
+ public void testLaunchSelectedTask_fromWidgets() {
+ runTest(TestSurface.WIDGETS, TestCase.LAUNCH_SELECTED_APP);
+ }
+
+ @Test
+ public void testLaunchOverviewTask_fromHome() {
+ runTest(TestSurface.HOME, TestCase.LAUNCH_OVERVIEW);
+ }
+
+ @Test
+ public void testLaunchOverviewTask_fromApp() {
+ runTest(TestSurface.LAUNCHED_APP, TestCase.LAUNCH_OVERVIEW);
+ }
+
+ @Test
+ public void testLaunchOverviewTask_fromHomeAllApps() {
+ runTest(TestSurface.HOME_ALL_APPS, TestCase.LAUNCH_OVERVIEW);
+ }
+
+ @Test
+ public void testLaunchOverviewTask_fromWidgets() {
+ runTest(TestSurface.WIDGETS, TestCase.LAUNCH_OVERVIEW);
+ }
+
+ private void runTest(@NonNull TestSurface testSurface, @NonNull TestCase testCase) {
+ for (int i = 0; i < testCase.mNumAdditionalRunningTasks; i++) {
+ startTestActivity(3 + i);
+ }
+
+ KeyboardQuickSwitch kqs;
+ switch (testSurface) {
+ case HOME:
+ kqs = mLauncher.goHome().showQuickSwitchView();
+ break;
+ case LAUNCHED_APP:
+ mLauncher.setIgnoreTaskbarVisibility(true);
+ kqs = mLauncher.getLaunchedAppState().showQuickSwitchView();
+ break;
+ case HOME_ALL_APPS:
+ kqs = mLauncher.goHome().switchToAllApps().showQuickSwitchView();
+ break;
+ case WIDGETS:
+ kqs = mLauncher.goHome().openAllWidgets().showQuickSwitchView();
+ break;
+ default:
+ throw new IllegalStateException(
+ "KeyboardQuickSwitch could not be initialized for test surface: "
+ + testSurface);
+ }
+
+ switch (testCase) {
+ case DISMISS:
+ kqs.dismiss();
+ break;
+ case LAUNCH_LAST_APP:
+ kqs.launchFocusedAppTask(CALCULATOR_APP_PACKAGE);
+ break;
+ case LAUNCH_SELECTED_APP:
+ kqs.moveFocusForward().launchFocusedAppTask(CALCULATOR_APP_PACKAGE);
+ break;
+ case LAUNCH_OVERVIEW:
+ kqs.moveFocusBackward().moveFocusBackward().launchFocusedOverviewTask();
+ break;
+ default:
+ throw new IllegalStateException("Cannot run test case: " + testCase);
+ }
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
index 1b5313b..9a2826d 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
@@ -22,6 +22,7 @@
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -38,6 +39,7 @@
@Test
@TaskbarModeSwitch(mode = PERSISTENT)
+ @Ignore // b/301575789
public void testHideTaskbarPersistsOnRecreate() {
getTaskbar().hide();
mLauncher.recreateTaskbar();
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 25f90ca..4075c55 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -16,11 +16,8 @@
package com.android.quickstep;
-import static com.android.launcher3.testing.shared.TestProtocol.FLAKY_QUICK_SWITCH_TO_PREVIOUS_APP;
-import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
+import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -30,7 +27,6 @@
import android.content.Intent;
import android.platform.test.annotations.PlatinumTest;
-import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -46,13 +42,10 @@
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewActions;
import com.android.launcher3.tapl.OverviewTask;
-import com.android.launcher3.tapl.OverviewTaskMenu;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
-import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import com.android.quickstep.views.RecentsView;
@@ -67,7 +60,6 @@
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
- private static final String APP_NAME = "LauncherTestApp";
private static final String CALCULATOR_APP_PACKAGE =
resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
private static final String READ_DEVICE_CONFIG_PERMISSION =
@@ -85,7 +77,7 @@
@After
public void tearDown() {
- executeOnLauncher(launcher -> {
+ executeOnLauncherInTearDown(launcher -> {
RecentsView recentsView = launcher.getOverviewPanel();
recentsView.getPagedViewOrientedState().forceAllowRotationForTesting(false);
});
@@ -187,6 +179,8 @@
@PortraitLandscape
@PlatinumTest(focusArea = "launcher")
public void testOverviewActions() throws Exception {
+ assumeFalse("Skipping Overview Actions tests for grid only overview",
+ mLauncher.isTablet() && mLauncher.isGridOnlyOverviewEnabled());
// Experimenting for b/165029151:
final Overview overview = mLauncher.goHome().switchToOverview();
if (overview.hasTasks()) overview.dismissAllTasks();
@@ -199,19 +193,6 @@
actionsView.clickAndDismissScreenshot();
}
-
- @Test
- public void testOverviewActionsMenu() throws Exception {
- startTestAppsWithCheck();
-
- OverviewTaskMenu menu = mLauncher.goHome().switchToOverview().getCurrentTask().tapMenu();
-
- assertNotNull("Tapping App info menu item returned null", menu.tapAppInfoMenuItem());
- executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the top",
- isInLaunchedApp(launcher)));
- }
-
private int getCurrentOverviewPage(Launcher launcher) {
return launcher.<RecentsView>getOverviewPanel().getCurrentPage();
}
@@ -242,6 +223,19 @@
isInState(() -> LauncherState.OVERVIEW));
}
+ @Test
+ @TaskbarModeSwitch(mode = TRANSIENT)
+ public void testSwitchToOverviewWithStashedTaskbar() throws Exception {
+ try {
+ startTestAppsWithCheck();
+ // Set ignoreTaskbarVisibility, as transient taskbar will be stashed after app launch.
+ mLauncher.setIgnoreTaskbarVisibility(true);
+ mLauncher.getLaunchedAppState().switchToOverview();
+ } finally {
+ mLauncher.setIgnoreTaskbarVisibility(false);
+ }
+ }
+
@Ignore
@Test
@NavigationModeSwitch
@@ -271,24 +265,6 @@
}
@Test
- @PortraitLandscape
- public void testAllAppsFromHome() throws Exception {
- // Test opening all apps
- assertNotNull("switchToAllApps() returned null",
- mLauncher.getWorkspace().switchToAllApps());
-
- TaplTestsLauncher3.runAllAppsTest(this, mLauncher.getAllApps());
-
- // Testing pressHome.
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- assertNotNull("pressHome returned null", mLauncher.goHome());
- assertTrue("Launcher internal state is not Home",
- isInState(() -> LauncherState.NORMAL));
- assertNotNull("getHome returned null", mLauncher.getWorkspace());
- }
-
- @Test
@NavigationModeSwitch
@PortraitLandscape
@PlatinumTest(focusArea = "launcher")
@@ -322,7 +298,7 @@
@Test
@ScreenRecord // b/242163205
@PlatinumTest(focusArea = "launcher")
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/286084688
+ @TaskbarModeSwitch(mode = PERSISTENT)
public void testQuickSwitchToPreviousAppForTablet() throws Exception {
assumeTrue(mLauncher.isTablet());
startTestActivity(2);
@@ -342,16 +318,7 @@
"The first app we should have quick switched to is not running");
// Expect task bar visible when the launched app was the test activity.
launchedAppState = getAndAssertLaunchedApp();
-
- Log.e(FLAKY_QUICK_SWITCH_TO_PREVIOUS_APP,
- "is Taskbar Transient : " + DisplayController.isTransientTaskbar(mTargetContext));
- // TODO(b/286084688): Remove this branching check after test corruption is resolved.
- // Branching this check because of test corruption.
- if (DisplayController.isTransientTaskbar(mTargetContext)) {
- launchedAppState.assertTaskbarHidden();
- } else {
- launchedAppState.assertTaskbarVisible();
- }
+ launchedAppState.assertTaskbarVisible();
}
@Test
@@ -369,7 +336,6 @@
@Test
@PortraitLandscape
@NavigationModeSwitch
- @PlatinumTest(focusArea = "launcher")
public void testPressBack() throws Exception {
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
READ_DEVICE_CONFIG_PERMISSION);
@@ -389,6 +355,7 @@
@PortraitLandscape
@TaskbarModeSwitch(mode = PERSISTENT)
@PlatinumTest(focusArea = "launcher")
+ @ScreenRecord
public void testOverviewForTablet() throws Exception {
assumeTrue(mLauncher.isTablet());
@@ -411,7 +378,9 @@
// Test opening the task.
overview.getCurrentTask().open();
assertTrue("Test activity didn't open from Overview",
- mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity10")),
+ mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text(
+ mLauncher.isGridOnlyOverviewEnabled() ? "TestActivity12"
+ : "TestActivity13")),
DEFAULT_UI_TIMEOUT));
// Scroll the task offscreen as it is now first
@@ -432,16 +401,17 @@
(Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet(
launcher)) <= 1)));
- // Test dismissing more tasks.
- assertTrue("Launcher internal state didn't remain in Overview",
- isInState(() -> LauncherState.OVERVIEW));
- overview.getCurrentTask().dismiss();
- assertTrue("Launcher internal state didn't remain in Overview",
- isInState(() -> LauncherState.OVERVIEW));
- overview.getCurrentTask().dismiss();
- executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after multiple dismissals",
- (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet(
- launcher)) <= 1)));
+ // TODO(b/308841019): Re-enable after fixing Overview jank when dismiss
+// // Test dismissing more tasks.
+// assertTrue("Launcher internal state didn't remain in Overview",
+// isInState(() -> LauncherState.OVERVIEW));
+// overview.getCurrentTask().dismiss();
+// assertTrue("Launcher internal state didn't remain in Overview",
+// isInState(() -> LauncherState.OVERVIEW));
+// overview.getCurrentTask().dismiss();
+// executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after multiple dismissals",
+// (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet(
+// launcher)) <= 1)));
// Test dismissing all tasks.
mLauncher.goHome().switchToOverview().dismissAllTasks();
@@ -502,7 +472,6 @@
}
@Test
- @ScreenRecord // b/242163205
public void testDisableRotationCheckForPhone() throws Exception {
assumeFalse(mLauncher.isTablet());
try {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index 92b598b..ee0fbb8 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -29,14 +29,15 @@
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
+import com.android.wm.shell.Flags;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -107,8 +108,10 @@
}
@Test
+ @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemExistsOnSplitPair() throws Exception {
- assumeTrue(FeatureFlags.ENABLE_APP_PAIRS.get());
+ assumeTrue("App pairs feature is currently not enabled, no test needed",
+ Flags.enableAppPairs());
createAndLaunchASplitPair();
@@ -121,8 +124,10 @@
}
@Test
+ @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemDoesNotExistOnSingleTask() throws Exception {
- assumeTrue(FeatureFlags.ENABLE_APP_PAIRS.get());
+ assumeTrue("App pairs feature is currently not enabled, no test needed",
+ Flags.enableAppPairs());
startAppFast(CALCULATOR_APP_PACKAGE);
@@ -138,7 +143,7 @@
startTestActivity(2);
startTestActivity(3);
- if (mLauncher.isTablet()) {
+ if (mLauncher.isTablet() && !mLauncher.isGridOnlyOverviewEnabled()) {
mLauncher.goHome().switchToOverview().getOverviewActions()
.clickSplit()
.getTestActivityTask(2)
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 4ff2f9c..0e382a4 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.quickstep.TaplTestsTaskbar.TaskbarMode.PERSISTENT;
import static com.android.quickstep.TaplTestsTaskbar.TaskbarMode.TRANSIENT;
@@ -151,6 +152,13 @@
.dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
}
+ @Test
+ @PortraitLandscape
+ public void testDismissAllAppsByTappingOutsideSheet() {
+ getTaskbar().openAllApps().dismissByTappingOutsideForTablet(/* tapRight= */ true);
+ getTaskbar().openAllApps().dismissByTappingOutsideForTablet(/* tapRight= */ false);
+ }
+
private boolean isTaskbarTestModeTransient() {
return TRANSIENT == mTaskbarMode;
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
index 3869bf7..db23cc0 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTransientTaskbar.java
@@ -15,13 +15,15 @@
*/
package com.android.quickstep;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
+import static org.junit.Assume.assumeTrue;
+
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.launcher3.util.TestUtil;
import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
import org.junit.Test;
@@ -34,44 +36,32 @@
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
public void testShowTaskbarUnstashHintOnHover() {
- try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
- getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- mLauncher.getLaunchedAppState().hoverToShowTaskbarUnstashHint();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ assumeTrue(enableCursorHoverStates());
+ getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ mLauncher.getLaunchedAppState().hoverToShowTaskbarUnstashHint();
}
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
public void testUnstashTaskbarOnScreenBottomEdgeHover() {
- try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
- getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- mLauncher.getLaunchedAppState().hoverScreenBottomEdgeToUnstashTaskbar();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ assumeTrue(enableCursorHoverStates());
+ getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ mLauncher.getLaunchedAppState().hoverScreenBottomEdgeToUnstashTaskbar();
}
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
public void testHoverBelowHintedTaskbarToUnstash() {
- try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
- getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- mLauncher.getLaunchedAppState().hoverBelowHintedTaskbarToUnstash();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ assumeTrue(enableCursorHoverStates());
+ getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ mLauncher.getLaunchedAppState().hoverBelowHintedTaskbarToUnstash();
}
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
- public void testClickHoveredTaskbarToGoHome() {
- try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
- getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- mLauncher.getLaunchedAppState().clickStashedTaskbarToGoHome();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ public void testClickHoveredTaskbarToGoHome() throws Exception {
+ assumeTrue(enableCursorHoverStates());
+ getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
+ mLauncher.getLaunchedAppState().clickStashedTaskbarToGoHome();
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java b/quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java
new file mode 100644
index 0000000..4e04261
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaskThumbnailCacheTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.R;
+import com.android.quickstep.util.TaskKeyCache;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+
+@SmallTest
+public class TaskThumbnailCacheTest {
+ @Mock
+ private Context mContext;
+
+ @Mock
+ private Resources mResource;
+
+ @Mock
+ private TaskKeyCache mTaskKeyCache;
+
+ @Before
+ public void setup() throws NoSuchFieldException {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getResources()).thenReturn(mResource);
+ }
+
+ @Test
+ public void increaseCacheSize() {
+ // Mock a cache size increase from 3 to 8
+ when(mTaskKeyCache.getMaxSize()).thenReturn(3);
+ when(mResource.getInteger((R.integer.recentsThumbnailCacheSize))).thenReturn(8);
+ TaskThumbnailCache thumbnailCache = new TaskThumbnailCache(mContext, mock(Executor.class),
+ mTaskKeyCache);
+
+ // Preload is needed when increasing size
+ assertTrue(thumbnailCache.updateCacheSizeAndRemoveExcess());
+ verify(mTaskKeyCache, times(1)).updateCacheSizeAndRemoveExcess(8);
+ }
+
+ @Test
+ public void decreaseCacheSize() {
+ // Mock a cache size decrease from 8 to 3
+ when(mTaskKeyCache.getMaxSize()).thenReturn(8);
+ when(mResource.getInteger((R.integer.recentsThumbnailCacheSize))).thenReturn(3);
+ TaskThumbnailCache thumbnailCache = new TaskThumbnailCache(mContext, mock(Executor.class),
+ mTaskKeyCache);
+ // Preload is not needed when decreasing size
+ assertFalse(thumbnailCache.updateCacheSizeAndRemoveExcess());
+ verify(mTaskKeyCache, times(1)).updateCacheSizeAndRemoveExcess(3);
+ }
+
+ @Test
+ public void keepSameCacheSize() {
+ when(mTaskKeyCache.getMaxSize()).thenReturn(3);
+ when(mResource.getInteger((R.integer.recentsThumbnailCacheSize))).thenReturn(3);
+ TaskThumbnailCache thumbnailCache = new TaskThumbnailCache(mContext, mock(Executor.class),
+ mTaskKeyCache);
+ // Preload is not needed when it has the same cache size
+ assertFalse(thumbnailCache.updateCacheSizeAndRemoveExcess());
+ verify(mTaskKeyCache, never()).updateCacheSizeAndRemoveExcess(anyInt());
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java
index 9e41f74..e5657fb 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java
@@ -123,7 +123,7 @@
assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar,
isTaskbarTransientMode(context) == expectTransientTaskbar, description);
- AbstractLauncherUiTest.checkDetectedLeaks(launcher);
+ AbstractLauncherUiTest.checkDetectedLeaks(launcher, true);
}
private static void assertTrue(LauncherInstrumentation launcher, String message,
diff --git a/quickstep/tests/src/com/android/quickstep/util/AppPairsControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/AppPairsControllerTest.kt
new file mode 100644
index 0000000..1723844
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/util/AppPairsControllerTest.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.util
+
+import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.launcher3.logging.StatsLogManager
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT
+import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT
+import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_30_70
+import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
+import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_70_30
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidJUnit4::class)
+class AppPairsControllerTest {
+ @Mock lateinit var context: Context
+ @Mock lateinit var splitSelectStateController: SplitSelectStateController
+ @Mock lateinit var statsLogManager: StatsLogManager
+
+ private lateinit var appPairsController: AppPairsController
+
+ private val left30: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_TOP_OR_LEFT, SNAP_TO_30_70)
+ }
+ private val left50: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_TOP_OR_LEFT, SNAP_TO_50_50)
+ }
+ private val left70: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_TOP_OR_LEFT, SNAP_TO_70_30)
+ }
+ private val right30: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_BOTTOM_OR_RIGHT, SNAP_TO_30_70)
+ }
+ private val right50: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_BOTTOM_OR_RIGHT, SNAP_TO_50_50)
+ }
+ private val right70: Int by lazy {
+ appPairsController.encodeRank(STAGE_POSITION_BOTTOM_OR_RIGHT, SNAP_TO_70_30)
+ }
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ appPairsController =
+ AppPairsController(context, splitSelectStateController, statsLogManager)
+ }
+
+ @Test
+ fun shouldEncodeRankCorrectly() {
+ assertEquals("left + 30-70 should encode as 0 (0b0)", 0, left30)
+ assertEquals("left + 50-50 should encode as 1 (0b1)", 1, left50)
+ assertEquals("left + 70-30 should encode as 2 (0b10)", 2, left70)
+ // See AppPairsController#BITMASK_SIZE and BITMASK_FOR_SNAP_POSITION for context
+ assertEquals("right + 30-70 should encode as 1 followed by 16 0s", 1 shl 16, right30)
+ assertEquals("right + 50-50 should encode as the above value + 1", (1 shl 16) + 1, right50)
+ assertEquals("right + 70-30 should encode as the above value + 2", (1 shl 16) + 2, right70)
+ }
+
+ @Test
+ fun shouldDecodeRankCorrectly() {
+ assertEquals(
+ "left + 30-70 should decode to left",
+ STAGE_POSITION_TOP_OR_LEFT,
+ AppPairsController.convertRankToStagePosition(left30),
+ )
+ assertEquals(
+ "left + 30-70 should decode to 30-70",
+ SNAP_TO_30_70,
+ AppPairsController.convertRankToSnapPosition(left30),
+ )
+
+ assertEquals(
+ "left + 50-50 should decode to left",
+ STAGE_POSITION_TOP_OR_LEFT,
+ AppPairsController.convertRankToStagePosition(left50),
+ )
+ assertEquals(
+ "left + 50-50 should decode to 50-50",
+ SNAP_TO_50_50,
+ AppPairsController.convertRankToSnapPosition(left50),
+ )
+
+ assertEquals(
+ "left + 70-30 should decode to left",
+ STAGE_POSITION_TOP_OR_LEFT,
+ AppPairsController.convertRankToStagePosition(left70),
+ )
+ assertEquals(
+ "left + 70-30 should decode to 70-30",
+ SNAP_TO_70_30,
+ AppPairsController.convertRankToSnapPosition(left70),
+ )
+
+ assertEquals(
+ "right + 30-70 should decode to right",
+ STAGE_POSITION_BOTTOM_OR_RIGHT,
+ AppPairsController.convertRankToStagePosition(right30),
+ )
+ assertEquals(
+ "right + 30-70 should decode to 30-70",
+ SNAP_TO_30_70,
+ AppPairsController.convertRankToSnapPosition(right30),
+ )
+
+ assertEquals(
+ "right + 50-50 should decode to right",
+ STAGE_POSITION_BOTTOM_OR_RIGHT,
+ AppPairsController.convertRankToStagePosition(right50),
+ )
+ assertEquals(
+ "right + 50-50 should decode to 50-50",
+ SNAP_TO_50_50,
+ AppPairsController.convertRankToSnapPosition(right50),
+ )
+
+ assertEquals(
+ "right + 70-30 should decode to right",
+ STAGE_POSITION_BOTTOM_OR_RIGHT,
+ AppPairsController.convertRankToStagePosition(right70),
+ )
+ assertEquals(
+ "right + 70-30 should decode to 70-30",
+ SNAP_TO_70_30,
+ AppPairsController.convertRankToSnapPosition(right70),
+ )
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
index 7e07b81..50803fe 100644
--- a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
@@ -32,39 +32,36 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class SplitAnimationControllerTest {
private val taskId = 9
- @Mock lateinit var mockSplitSelectStateController: SplitSelectStateController
+ private val mockSplitSelectStateController: SplitSelectStateController = mock()
// TaskView
- @Mock lateinit var mockTaskView: TaskView
- @Mock lateinit var mockThumbnailView: TaskThumbnailView
- @Mock lateinit var mockBitmap: Bitmap
- @Mock lateinit var mockIconView: IconView
- @Mock lateinit var mockTaskViewDrawable: Drawable
+ private val mockTaskView: TaskView = mock()
+ private val mockThumbnailView: TaskThumbnailView = mock()
+ private val mockBitmap: Bitmap = mock()
+ private val mockIconView: IconView = mock()
+ private val mockTaskViewDrawable: Drawable = mock()
// GroupedTaskView
- @Mock lateinit var mockGroupedTaskView: GroupedTaskView
- @Mock lateinit var mockTask: Task
- @Mock lateinit var mockTaskKey: Task.TaskKey
- @Mock lateinit var mockTaskIdAttributeContainer: TaskIdAttributeContainer
+ private val mockGroupedTaskView: GroupedTaskView = mock()
+ private val mockTask: Task = mock()
+ private val mockTaskKey: Task.TaskKey = mock()
+ private val mockTaskIdAttributeContainer: TaskIdAttributeContainer = mock()
// SplitSelectSource
- @Mock lateinit var splitSelectSource: SplitConfigurationOptions.SplitSelectSource
- @Mock lateinit var mockSplitSourceDrawable: Drawable
- @Mock lateinit var mockSplitSourceView: View
+ private val splitSelectSource: SplitConfigurationOptions.SplitSelectSource = mock()
+ private val mockSplitSourceDrawable: Drawable = mock()
+ private val mockSplitSourceView: View = mock()
lateinit var splitAnimationController: SplitAnimationController
@Before
fun setup() {
- MockitoAnnotations.initMocks(this)
-
whenever(mockTaskView.thumbnail).thenReturn(mockThumbnailView)
whenever(mockThumbnailView.thumbnail).thenReturn(mockBitmap)
whenever(mockTaskView.iconView).thenReturn(mockIconView)
@@ -85,12 +82,14 @@
// Missing taskView icon
whenever(mockIconView.drawable).thenReturn(null)
- val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
- splitAnimationController.getFirstAnimInitViews(
- { mockTaskView }, { splitSelectSource })
+ val splitAnimInitProps: SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews({ mockTaskView }, { splitSelectSource })
- assertEquals("Did not fallback to use splitSource icon drawable",
- mockSplitSourceDrawable, splitAnimInitProps.iconDrawable)
+ assertEquals(
+ "Did not fallback to use splitSource icon drawable",
+ mockSplitSourceDrawable,
+ splitAnimInitProps.iconDrawable
+ )
}
@Test
@@ -99,12 +98,14 @@
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
- val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
- splitAnimationController.getFirstAnimInitViews(
- { mockTaskView }, { splitSelectSource })
+ val splitAnimInitProps: SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews({ mockTaskView }, { splitSelectSource })
- assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
- splitAnimInitProps.iconDrawable)
+ assertEquals(
+ "Did not use taskView icon drawable",
+ mockTaskViewDrawable,
+ splitAnimInitProps.iconDrawable
+ )
}
@Test
@@ -116,12 +117,14 @@
// Set split source to null
whenever(splitSelectSource.drawable).thenReturn(null)
- val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
- splitAnimationController.getFirstAnimInitViews(
- { mockTaskView }, { splitSelectSource })
+ val splitAnimInitProps: SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews({ mockTaskView }, { splitSelectSource })
- assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
- splitAnimInitProps.iconDrawable)
+ assertEquals(
+ "Did not use taskView icon drawable",
+ mockTaskViewDrawable,
+ splitAnimInitProps.iconDrawable
+ )
}
@Test
@@ -130,12 +133,14 @@
whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(false)
whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
- val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
- splitAnimationController.getFirstAnimInitViews(
- { mockTaskView }, { splitSelectSource })
+ val splitAnimInitProps: SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews({ mockTaskView }, { splitSelectSource })
- assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
- splitAnimInitProps.iconDrawable)
+ assertEquals(
+ "Did not use splitSource icon drawable",
+ mockSplitSourceDrawable,
+ splitAnimInitProps.iconDrawable
+ )
}
@Test
@@ -154,12 +159,17 @@
whenever(mockTaskKey.getId()).thenReturn(taskId)
whenever(mockSplitSelectStateController.initialTaskId).thenReturn(taskId)
whenever(mockGroupedTaskView.taskIdAttributeContainers)
- .thenReturn(Array(1) { mockTaskIdAttributeContainer })
- val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
- splitAnimationController.getFirstAnimInitViews(
- { mockGroupedTaskView }, { splitSelectSource })
+ .thenReturn(Array(1) { mockTaskIdAttributeContainer })
+ val splitAnimInitProps: SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews(
+ { mockGroupedTaskView },
+ { splitSelectSource }
+ )
- assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
- splitAnimInitProps.iconDrawable)
+ assertEquals(
+ "Did not use splitSource icon drawable",
+ mockSplitSourceDrawable,
+ splitAnimInitProps.iconDrawable
+ )
}
-}
\ No newline at end of file
+}
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
index fc767fa..c6c5be4 100644
--- a/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/util/SplitSelectDataHolderTest.kt
@@ -381,7 +381,7 @@
}
@Test
- fun clearState() {
+ fun clearState_task() {
splitSelectDataHolder.setInitialTaskSelect(
sampleTaskInfo,
STAGE_POSITION_TOP_OR_LEFT,
@@ -392,4 +392,18 @@
splitSelectDataHolder.resetState()
assertFalse(splitSelectDataHolder.isSplitSelectActive())
}
+
+ @Test
+ fun clearState_intent() {
+ splitSelectDataHolder.setInitialTaskSelect(
+ sampleIntent,
+ STAGE_POSITION_TOP_OR_LEFT,
+ sampleItemInfo,
+ null,
+ INVALID_TASK_ID
+ )
+ splitSelectDataHolder.setSecondTask(sampleIntent, sampleUser)
+ splitSelectDataHolder.resetState()
+ assertFalse(splitSelectDataHolder.isSplitSelectActive())
+ }
}
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
index 69109c2..f292f9a 100644
--- a/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
@@ -20,7 +20,6 @@
import android.app.ActivityManager
import android.app.PendingIntent
import android.content.ComponentName
-import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Handler
@@ -31,12 +30,13 @@
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.statehandlers.DepthController
import com.android.launcher3.statemanager.StateManager
+import com.android.launcher3.statemanager.StatefulActivity
import com.android.launcher3.util.ComponentKey
import com.android.launcher3.util.SplitConfigurationOptions
-import com.android.launcher3.util.withArgCaptor
import com.android.quickstep.RecentsModel
import com.android.quickstep.SystemUiProxy
import com.android.systemui.shared.recents.model.Task
+import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
import java.util.function.Consumer
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -45,22 +45,22 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class SplitSelectStateControllerTest {
- @Mock lateinit var systemUiProxy: SystemUiProxy
- @Mock lateinit var depthController: DepthController
- @Mock lateinit var statsLogManager: StatsLogManager
- @Mock lateinit var stateManager: StateManager<LauncherState>
- @Mock lateinit var handler: Handler
- @Mock lateinit var context: Context
- @Mock lateinit var recentsModel: RecentsModel
- @Mock lateinit var pendingIntent: PendingIntent
+ private val systemUiProxy: SystemUiProxy = mock()
+ private val depthController: DepthController = mock()
+ private val statsLogManager: StatsLogManager = mock()
+ private val stateManager: StateManager<LauncherState> = mock()
+ private val handler: Handler = mock()
+ private val context: StatefulActivity<*> = mock()
+ private val recentsModel: RecentsModel = mock()
+ private val pendingIntent: PendingIntent = mock()
lateinit var splitSelectStateController: SplitSelectStateController
@@ -68,11 +68,12 @@
private val nonPrimaryUserHandle = UserHandle(ActivityManager.RunningTaskInfo().userId + 10)
private var taskIdCounter = 0
- private fun getUniqueId(): Int { return ++taskIdCounter }
+ private fun getUniqueId(): Int {
+ return ++taskIdCounter
+ }
@Before
fun setup() {
- MockitoAnnotations.initMocks(this)
splitSelectStateController =
SplitSelectStateController(
context,
@@ -81,7 +82,8 @@
depthController,
statsLogManager,
systemUiProxy,
- recentsModel
+ recentsModel,
+ null /*activityBackCallback*/
)
}
@@ -109,13 +111,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(nonMatchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(nonMatchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -160,13 +163,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(matchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(matchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -199,13 +203,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(nonPrimaryUserComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(nonPrimaryUserComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -253,13 +258,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(nonPrimaryUserComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(nonPrimaryUserComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -304,13 +310,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(matchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(matchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -325,10 +332,7 @@
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
- ComponentName("hotdog", "pie"),
- ComponentName("pumpkin", "pie")
- )
+ generateGroupTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
val groupTask2 =
generateGroupTask(
ComponentName("pomegranate", "juice"),
@@ -359,13 +363,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(nonMatchingComponent, matchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(nonMatchingComponent, matchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -379,10 +384,7 @@
ComponentKey(ComponentName(matchingPackage, matchingClass), primaryUserHandle)
val groupTask1 =
- generateGroupTask(
- ComponentName("hotdog", "pie"),
- ComponentName("pumpkin", "pie")
- )
+ generateGroupTask(ComponentName("hotdog", "pie"), ComponentName("pumpkin", "pie"))
val groupTask2 =
generateGroupTask(
ComponentName("pomegranate", "juice"),
@@ -413,13 +415,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(matchingComponent, matchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(matchingComponent, matchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -477,13 +480,14 @@
// Capture callback from recentsModel#getTasks()
val consumer =
- withArgCaptor<Consumer<ArrayList<GroupTask>>> {
- splitSelectStateController.findLastActiveTasksAndRunCallback(
- listOf(matchingComponent, matchingComponent),
- taskConsumer
- )
- verify(recentsModel).getTasks(capture())
- }
+ argumentCaptor<Consumer<ArrayList<GroupTask>>> {
+ splitSelectStateController.findLastActiveTasksAndRunCallback(
+ listOf(matchingComponent, matchingComponent),
+ taskConsumer
+ )
+ verify(recentsModel).getTasks(capture())
+ }
+ .lastValue
// Send our mocked tasks
consumer.accept(tasks)
@@ -529,7 +533,7 @@
@Test
fun secondPendingIntentSet() {
val itemInfo = ItemInfo()
- `when`(pendingIntent.creatorUserHandle).thenReturn(primaryUserHandle)
+ whenever(pendingIntent.creatorUserHandle).thenReturn(primaryUserHandle)
splitSelectStateController.setInitialTaskSelect(null, 0, itemInfo, null, 1)
splitSelectStateController.setSecondTask(pendingIntent)
assertTrue(splitSelectStateController.isBothSplitAppsConfirmed)
@@ -558,7 +562,7 @@
return GroupTask(
task1,
task2,
- SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1)
+ SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1, SNAP_TO_50_50)
)
}
@@ -590,7 +594,7 @@
return GroupTask(
task1,
task2,
- SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1)
+ SplitConfigurationOptions.SplitBounds(Rect(), Rect(), -1, -1, SNAP_TO_50_50)
)
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCacheTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCacheTest.java
new file mode 100644
index 0000000..ea2688a
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/util/TaskKeyByLastActiveTimeCacheTest.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+import android.content.ComponentName;
+import android.content.Intent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+import org.junit.Test;
+
+@SmallTest
+public class TaskKeyByLastActiveTimeCacheTest {
+ @Test
+ public void add() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 1);
+ ThumbnailData data1 = new ThumbnailData();
+ cache.put(key1, data1);
+
+ Task.TaskKey key2 = new Task.TaskKey(2, 0, new Intent(),
+ new ComponentName("", ""), 0, 2);
+ ThumbnailData data2 = new ThumbnailData();
+ cache.put(key2, data2);
+
+ assertEquals(2, cache.getSize());
+ assertEquals(data1, cache.getAndInvalidateIfModified(key1));
+ assertEquals(data2, cache.getAndInvalidateIfModified(key2));
+
+ assertEquals(2, cache.getQueue().size());
+ assertEquals(key1, cache.getQueue().poll());
+ assertEquals(key2, cache.getQueue().poll());
+ }
+
+ @Test
+ public void addSameTasksWithSameLastActiveTimeTwice() {
+ // Add 2 tasks with same id and last active time, it should only have 1 entry in cache
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 1000);
+ ThumbnailData data1 = new ThumbnailData();
+ cache.put(key1, data1);
+
+ Task.TaskKey key2 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 1000);
+ ThumbnailData data2 = new ThumbnailData();
+ cache.put(key2, data2);
+
+ assertEquals(1, cache.getSize());
+ assertEquals(data2, cache.getAndInvalidateIfModified(key2));
+
+ assertEquals(1, cache.getQueue().size());
+ assertEquals(key2, cache.getQueue().poll());
+ }
+
+ @Test
+ public void addSameTasksWithDifferentLastActiveTime() {
+ // Add 2 tasks with same id and different last active time, it should only have the
+ // higher last active time entry
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 1000);
+ ThumbnailData data1 = new ThumbnailData();
+ cache.put(key1, data1);
+
+ Task.TaskKey key2 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 2000);
+ ThumbnailData data2 = new ThumbnailData();
+ cache.put(key2, data2);
+
+ assertEquals(1, cache.getSize());
+ assertEquals(data2, cache.getAndInvalidateIfModified(key2));
+
+ assertEquals(1, cache.getQueue().size());
+ Task.TaskKey queueKey = cache.getQueue().poll();
+ assertEquals(key2, queueKey);
+ // TaskKey's equal method does not check last active time, so we check here
+ assertEquals(2000, queueKey.lastActiveTime);
+ }
+
+ @Test
+ public void remove() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 0);
+ cache.put(key1, new ThumbnailData());
+
+ cache.remove(key1);
+
+ assertEquals(0, cache.getSize());
+ assertEquals(0, cache.getQueue().size());
+ }
+
+ @Test
+ public void removeByStubKey() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 1, new Intent(),
+ new ComponentName("", ""), 1, 100);
+ cache.put(key1, new ThumbnailData());
+
+ Task.TaskKey stubKey = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 0);
+ cache.remove(stubKey);
+
+ assertEquals(0, cache.getSize());
+ assertEquals(0, cache.getQueue().size());
+ }
+
+ @Test
+ public void evictAll() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 0);
+ cache.put(key1, new ThumbnailData());
+ Task.TaskKey key2 = new Task.TaskKey(2, 0, new Intent(),
+ new ComponentName("", ""), 0, 0);
+ cache.put(key2, new ThumbnailData());
+
+ cache.evictAll();
+
+ assertEquals(0, cache.getSize());
+ assertEquals(0, cache.getQueue().size());
+ }
+
+ @Test
+ public void removeAllByPredicate() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ // Add user 1's tasks
+ Task.TaskKey user1Key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 1, 0);
+ cache.put(user1Key1, new ThumbnailData());
+ Task.TaskKey user1Key2 = new Task.TaskKey(2, 0, new Intent(),
+ new ComponentName("", ""), 1, 0);
+ cache.put(user1Key2, new ThumbnailData());
+ // Add user 2's task
+ Task.TaskKey user2Key = new Task.TaskKey(3, 0, new Intent(),
+ new ComponentName("", ""), 2, 0);
+ ThumbnailData user2Data = new ThumbnailData();
+ cache.put(user2Key, user2Data);
+
+ cache.removeAll(key -> key.userId == 1);
+
+ // Only user 2's task remains
+ assertEquals(1, cache.getSize());
+ assertEquals(user2Data, cache.getAndInvalidateIfModified(user2Key));
+
+ assertEquals(1, cache.getQueue().size());
+ assertEquals(user2Key, cache.getQueue().poll());
+ }
+
+ @Test
+ public void getAndInvalidateIfModified() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(3);
+ // Add user 1's tasks
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 1, 0);
+ ThumbnailData data1 = new ThumbnailData();
+ cache.put(key1, data1);
+
+ // Get result with task key of same last active time
+ Task.TaskKey keyWithSameActiveTime = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 1, 0);
+ ThumbnailData result1 = cache.getAndInvalidateIfModified(keyWithSameActiveTime);
+ assertEquals(data1, result1);
+ assertEquals(1, cache.getQueue().size());
+
+ // Invalidate result with task key of new last active time
+ Task.TaskKey keyWithNewActiveTime = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 1, 1);
+ ThumbnailData result2 = cache.getAndInvalidateIfModified(keyWithNewActiveTime);
+ // No entry is retrieved because the key has higher last active time
+ assertNull(result2);
+ assertEquals(0, cache.getSize());
+ assertEquals(0, cache.getQueue().size());
+ }
+
+ @Test
+ public void removeByLastActiveTimeWhenOverMaxSize() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(2);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 200);
+ ThumbnailData task1 = new ThumbnailData();
+ cache.put(key1, task1);
+ Task.TaskKey key2 = new Task.TaskKey(2, 0, new Intent(),
+ new ComponentName("", ""), 0, 100);
+ ThumbnailData task2 = new ThumbnailData();
+ cache.put(key2, task2);
+
+ // Add the 3rd entry which will exceed the max cache size
+ Task.TaskKey key3 = new Task.TaskKey(3, 0, new Intent(),
+ new ComponentName("", ""), 0, 300);
+ ThumbnailData task3 = new ThumbnailData();
+ cache.put(key3, task3);
+
+ // Assert map size and check the remaining entries have higher active time
+ assertEquals(2, cache.getSize());
+ assertEquals(task1, cache.getAndInvalidateIfModified(key1));
+ assertEquals(task3, cache.getAndInvalidateIfModified(key3));
+ assertNull(cache.getAndInvalidateIfModified(key2));
+
+ // Assert queue size and check the remaining entries have higher active time
+ assertEquals(2, cache.getQueue().size());
+ Task.TaskKey queueKey1 = cache.getQueue().poll();
+ assertEquals(key1, queueKey1);
+ assertEquals(200, queueKey1.lastActiveTime);
+ Task.TaskKey queueKey2 = cache.getQueue().poll();
+ assertEquals(key3, queueKey2);
+ assertEquals(300, queueKey2.lastActiveTime);
+ }
+
+ @Test
+ public void updateIfAlreadyInCache() {
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(2);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 200);
+ cache.put(key1, new ThumbnailData());
+
+ // Update original data to new data
+ ThumbnailData newData = new ThumbnailData();
+ cache.updateIfAlreadyInCache(key1.id, newData);
+
+ // Data is updated to newData successfully
+ ThumbnailData result = cache.getAndInvalidateIfModified(key1);
+ assertEquals(newData, result);
+ }
+
+ @Test
+ public void updateCacheSizeAndInvalidateExcess() {
+ // Last active time are not in-sync with insertion order to simulate the real async case
+ TaskKeyByLastActiveTimeCache<ThumbnailData> cache = new TaskKeyByLastActiveTimeCache<>(4);
+ Task.TaskKey key1 = new Task.TaskKey(1, 0, new Intent(),
+ new ComponentName("", ""), 0, 200);
+ cache.put(key1, new ThumbnailData());
+
+ Task.TaskKey key2 = new Task.TaskKey(2, 0, new Intent(),
+ new ComponentName("", ""), 0, 100);
+ cache.put(key2, new ThumbnailData());
+
+ Task.TaskKey key3 = new Task.TaskKey(3, 0, new Intent(),
+ new ComponentName("", ""), 0, 400);
+ cache.put(key3, new ThumbnailData());
+
+ Task.TaskKey key4 = new Task.TaskKey(4, 0, new Intent(),
+ new ComponentName("", ""), 0, 300);
+ cache.put(key4, new ThumbnailData());
+
+ // Check that it has 4 entries before cache size changes
+ assertEquals(4, cache.getSize());
+ assertEquals(4, cache.getQueue().size());
+
+ // Update size to 2
+ cache.updateCacheSizeAndRemoveExcess(2);
+
+ // Number of entries becomes 2, only key3 and key4 remain
+ assertEquals(2, cache.getSize());
+ assertEquals(2, cache.getQueue().size());
+ assertNotNull(cache.getAndInvalidateIfModified(key3));
+ assertNotNull(cache.getAndInvalidateIfModified(key4));
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index a54dc2d..b365173 100644
--- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -18,11 +18,15 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.ArrayMap;
+import android.util.DisplayMetrics;
import android.view.RemoteAnimationTarget;
import android.view.Surface;
@@ -35,7 +39,6 @@
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.NavigationMode;
-import com.android.launcher3.util.ReflectionHelpers;
import com.android.launcher3.util.RotationUtils;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.CachedDisplayInfo;
@@ -61,6 +64,7 @@
public void taskProperlyScaled_portrait_noRotation_sameInsets1() {
new TaskMatrixVerifier()
.withLauncherSize(1200, 2450)
+ .withDensityDpi(420)
.withInsets(new Rect(0, 80, 0, 120))
.verifyNoTransforms();
}
@@ -69,6 +73,7 @@
public void taskProperlyScaled_portrait_noRotation_sameInsets2() {
new TaskMatrixVerifier()
.withLauncherSize(1200, 2450)
+ .withDensityDpi(420)
.withInsets(new Rect(55, 80, 55, 120))
.verifyNoTransforms();
}
@@ -77,6 +82,7 @@
public void taskProperlyScaled_landscape_noRotation_sameInsets1() {
new TaskMatrixVerifier()
.withLauncherSize(2450, 1250)
+ .withDensityDpi(420)
.withInsets(new Rect(0, 80, 0, 40))
.verifyNoTransforms();
}
@@ -85,6 +91,7 @@
public void taskProperlyScaled_landscape_noRotation_sameInsets2() {
new TaskMatrixVerifier()
.withLauncherSize(2450, 1250)
+ .withDensityDpi(420)
.withInsets(new Rect(0, 80, 120, 0))
.verifyNoTransforms();
}
@@ -93,6 +100,7 @@
public void taskProperlyScaled_landscape_noRotation_sameInsets3() {
new TaskMatrixVerifier()
.withLauncherSize(2450, 1250)
+ .withDensityDpi(420)
.withInsets(new Rect(55, 80, 55, 120))
.verifyNoTransforms();
}
@@ -101,6 +109,7 @@
public void taskProperlyScaled_landscape_rotated() {
new TaskMatrixVerifier()
.withLauncherSize(1200, 2450)
+ .withDensityDpi(420)
.withInsets(new Rect(0, 80, 0, 120))
.withAppBounds(
new Rect(0, 0, 2450, 1200),
@@ -112,6 +121,7 @@
private static class TaskMatrixVerifier extends TransformParams {
private Point mDisplaySize = new Point();
+ private int mDensityDpi = DisplayMetrics.DENSITY_DEFAULT;
private Rect mDisplayInsets = new Rect();
private Rect mAppBounds = new Rect();
private Rect mLauncherInsets = new Rect();
@@ -129,6 +139,11 @@
return this;
}
+ TaskMatrixVerifier withDensityDpi(int densityDpi) {
+ mDensityDpi = densityDpi;
+ return this;
+ }
+
TaskMatrixVerifier withInsets(Rect insets) {
mDisplayInsets.set(insets);
mLauncherInsets.set(insets);
@@ -173,13 +188,17 @@
new ArrayMap<>();
perDisplayBoundsCache.put(cdi.normalize(), allBounds);
- DisplayController.Info mockInfo = new Info(
- helper.sandboxContext, wmProxy, perDisplayBoundsCache);
+ Configuration configuration = new Configuration();
+ configuration.densityDpi = mDensityDpi;
+ Context configurationContext = helper.sandboxContext.createConfigurationContext(
+ configuration);
- DisplayController controller =
- DisplayController.INSTANCE.get(helper.sandboxContext);
- controller.close();
- ReflectionHelpers.setField(controller, "mInfo", mockInfo);
+ DisplayController.Info info = new Info(
+ configurationContext, wmProxy, perDisplayBoundsCache);
+
+ DisplayController mockController = mock(DisplayController.class);
+ when(mockController.getInfo()).thenReturn(info);
+ helper.sandboxContext.putObject(DisplayController.INSTANCE, mockController);
mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(helper.sandboxContext)
.getBestMatch(mAppBounds.width(), mAppBounds.height(), rotation);
@@ -189,7 +208,7 @@
FallbackActivityInterface.INSTANCE);
tvs.setDp(mDeviceProfile);
- int launcherRotation = mockInfo.rotation;
+ int launcherRotation = info.rotation;
if (mAppRotation < 0) {
mAppRotation = launcherRotation;
}
diff --git a/quickstep/tests/src/com/android/quickstep/util/unfold/PreemptiveUnfoldTransitionProgressProviderTest.kt b/quickstep/tests/src/com/android/quickstep/util/unfold/PreemptiveUnfoldTransitionProgressProviderTest.kt
index f73be72..6a418a4 100644
--- a/quickstep/tests/src/com/android/quickstep/util/unfold/PreemptiveUnfoldTransitionProgressProviderTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/util/unfold/PreemptiveUnfoldTransitionProgressProviderTest.kt
@@ -21,19 +21,17 @@
import android.testing.TestableLooper.RunWithLooper
import android.util.Log
import androidx.test.filters.SmallTest
-import com.android.launcher3.util.any
-import com.android.launcher3.util.mock
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
+import org.mockito.kotlin.any
+import org.mockito.kotlin.inOrder
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -74,7 +72,7 @@
provider.preemptivelyStartTransition(initialProgress = null)
verify(listener).onTransitionStarted()
- verify(listener, never()).onTransitionProgress(anyFloat())
+ verify(listener, never()).onTransitionProgress(any())
}
@Test
@@ -90,7 +88,7 @@
provider.preemptivelyStartTransition()
provider.cancelPreemptiveStart()
- with(inOrder(listener)) {
+ inOrder(listener) {
verify(listener).onTransitionStarted()
verify(listener).onTransitionFinished()
}
@@ -111,7 +109,7 @@
source.onTransitionStarted()
source.onTransitionFinished()
- with(inOrder(listener)) {
+ inOrder(listener) {
verify(listener).onTransitionStarted()
verify(listener).onTransitionFinished()
}
@@ -152,7 +150,7 @@
provider.preemptivelyStartTransition()
source.onTransitionFinished()
- with(inOrder(listener)) {
+ inOrder(listener) {
verify(listener).onTransitionStarted()
verify(listener).onTransitionFinished()
}
@@ -165,7 +163,7 @@
testableLooper.moveTimeForward(PREEMPTIVE_UNFOLD_TIMEOUT_MS + 1)
testableLooper.processAllMessages()
- with(inOrder(listener)) {
+ inOrder(listener) {
verify(listener).onTransitionStarted()
verify(listener).onTransitionFinished()
}
@@ -178,7 +176,7 @@
testableLooper.moveTimeForward(PREEMPTIVE_UNFOLD_TIMEOUT_MS + 1)
testableLooper.processAllMessages()
- verify(testWtfHandler).onTerribleFailure(any(), any(), anyBoolean())
+ verify(testWtfHandler).onTerribleFailure(any(), any(), any())
}
@Test
@@ -225,7 +223,7 @@
source.onTransitionFinished()
- with(inOrder(listener)) {
+ inOrder(listener) {
verify(listener).onTransitionStarted()
verify(listener).onTransitionFinished()
}
diff --git a/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..654f0b3
--- /dev/null
+++ b/res/drawable-sw720dp/ic_transient_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="52dp"
+ android:height="52dp"
+ android:viewportWidth="52"
+ android:viewportHeight="52">
+ <path
+ android:pathData="M39.4,17.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C36.9,12 39.4,14.5 39.4,17.5z"
+ android:fillColor="#FF000000"/>
+ <path
+ android:pathData="M23.1,17.5c0,3.1 -2.5,5.5 -5.5,5.5S12,20.6 12,17.5s2.5,-5.5 5.5,-5.5S23.1,14.5 23.1,17.5z"
+ android:fillColor="#FF000000"/>
+ <path
+ android:pathData="M17.5,33.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"
+ android:fillColor="#FF000000"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M33.9,30c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9S30,36.1 30,33.9S31.8,30 33.9,30M33.9,28.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C39.5,30.8 37,28.3 33.9,28.3L33.9,28.3z"/>
+ <path
+ android:pathData="M36.9,37L43.2,43.3"
+ android:strokeWidth="1.7"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/res/drawable/encrypted_24px.xml b/res/drawable/encrypted_24px.xml
new file mode 100644
index 0000000..cf4d2df
--- /dev/null
+++ b/res/drawable/encrypted_24px.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M420,600L540,600L517,471Q537,461 548.5,442Q560,423 560,400Q560,367 536.5,343.5Q513,320 480,320Q447,320 423.5,343.5Q400,367 400,400Q400,423 411.5,442Q423,461 443,471L420,600ZM480,880Q341,845 250.5,720.5Q160,596 160,444L160,200L480,80L800,200L800,444Q800,596 709.5,720.5Q619,845 480,880ZM480,796Q584,763 652,664Q720,565 720,444L720,255L480,165L240,255L240,444Q240,565 308,664Q376,763 480,796ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Z"/>
+</vector>
diff --git a/res/drawable/ic_taskbar_all_apps_search_button.xml b/res/drawable/ic_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..8fbe539
--- /dev/null
+++ b/res/drawable/ic_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="44dp"
+ android:height="44dp"
+ android:viewportWidth="44"
+ android:viewportHeight="44">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M34.1,14.9c0,2.7 -2.2,4.9 -4.9,4.9s-4.9,-2.2 -4.9,-4.9s2.2,-4.9 4.9,-4.9S34.1,12.2 34.1,14.9z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.7,14.9c0,2.7 -2.2,4.9 -4.9,4.9S10,17.6 10,14.9s2.2,-4.9 4.9,-4.9S19.7,12.2 19.7,14.9z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M14.9,29.2m-4.9,0a4.9,4.9 0,1 1,9.8 0a4.9,4.9 0,1 1,-9.8 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M29.3,25.9c1.9,0 3.4,1.5 3.4,3.4c0,1.9 -1.5,3.4 -3.4,3.4s-3.4,-1.5 -3.4,-3.4C25.9,27.4 27.4,25.9 29.3,25.9M29.3,24.4c-2.7,0 -4.9,2.2 -4.9,4.9s2.2,4.9 4.9,4.9c2.7,0 4.9,-2.2 4.9,-4.9S32,24.4 29.3,24.4L29.3,24.4z"/>
+ <path
+ android:pathData="M31.9,32L37.4,37.5"
+ android:strokeWidth="1.5"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/res/drawable/ic_transient_taskbar_all_apps_search_button.xml b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
new file mode 100644
index 0000000..59a666b
--- /dev/null
+++ b/res/drawable/ic_transient_taskbar_all_apps_search_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M37.4,15.5c0,3.1 -2.5,5.5 -5.5,5.5c-3.1,0 -5.5,-2.5 -5.5,-5.5s2.5,-5.5 5.5,-5.5C34.9,10 37.4,12.5 37.4,15.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M21.1,15.5c0,3.1 -2.5,5.5 -5.5,5.5S10,18.6 10,15.5s2.5,-5.5 5.5,-5.5S21.1,12.5 21.1,15.5z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M15.5,31.9m-5.5,0a5.5,5.5 0,1 1,11 0a5.5,5.5 0,1 1,-11 0"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M31.9,28c2.1,0 3.9,1.7 3.9,3.9s-1.7,3.9 -3.9,3.9c-2.1,0 -3.9,-1.7 -3.9,-3.9S29.8,28 31.9,28M31.9,26.3c-3.1,0 -5.6,2.5 -5.6,5.6c0,3.1 2.5,5.6 5.6,5.6c3.1,0 5.6,-2.5 5.6,-5.6C37.5,28.8 35,26.3 31.9,26.3L31.9,26.3z"/>
+ <path
+ android:pathData="M34.9,35L41.2,41.3"
+ android:strokeWidth="1.7"
+ android:fillColor="#00000000"
+ android:strokeColor="#000000"/>
+</vector>
diff --git a/res/drawable/icon_menu_arrow_background.xml b/res/drawable/icon_menu_arrow_background.xml
new file mode 100644
index 0000000..f24022e
--- /dev/null
+++ b/res/drawable/icon_menu_arrow_background.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:autoMirrored="true">
+ <gradient
+ android:type="linear"
+ android:angle="0"
+ android:startColor="#00000000"
+ android:centerX="0.25"
+ android:centerColor="?androidprv:attr/materialColorSurfaceContainer"
+ android:endColor="?androidprv:attr/materialColorSurfaceContainer" />
+ <corners android:radius="@dimen/dialogCornerRadius" />
+</shape>
\ No newline at end of file
diff --git a/res/layout/popup_container_material_u.xml b/res/drawable/icon_menu_background.xml
similarity index 60%
rename from res/layout/popup_container_material_u.xml
rename to res/drawable/icon_menu_background.xml
index d34c500..ec5f011 100644
--- a/res/layout/popup_container_material_u.xml
+++ b/res/drawable/icon_menu_background.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
+<!--
+ Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,11 +14,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.popup.PopupContainerWithArrow
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/popup_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical"/>
\ No newline at end of file
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:shape="rectangle">
+ <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
+ <corners android:radius="@dimen/dialogCornerRadius" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/popup_background_material_u.xml b/res/drawable/popup_background.xml
similarity index 100%
rename from res/drawable/popup_background_material_u.xml
rename to res/drawable/popup_background.xml
diff --git a/res/layout/arrow_toast.xml b/res/layout/arrow_toast.xml
index 004e778..9e44917 100644
--- a/res/layout/arrow_toast.xml
+++ b/res/layout/arrow_toast.xml
@@ -29,11 +29,11 @@
android:background="@drawable/arrow_toast_rounded_background"
android:elevation="@dimen/arrow_toast_elevation"
android:textColor="?attr/arrowTipTextColor"
- android:textSize="14sp"/>
+ android:textSize="@dimen/arrow_toast_text_size"/>
<View
android:id="@+id/arrow"
android:elevation="@dimen/arrow_toast_elevation"
android:layout_width="@dimen/arrow_toast_arrow_width"
- android:layout_height="10dp"/>
+ android:layout_height="@dimen/arrow_toast_arrow_height"/>
</merge>
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml
index b175d17..6c1a2f7 100644
--- a/res/layout/deep_shortcut.xml
+++ b/res/layout/deep_shortcut.xml
@@ -13,10 +13,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<com.android.launcher3.shortcuts.DeepShortcutView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/deep_shortcut_material"
android:layout_width="@dimen/bg_popup_item_width"
android:layout_height="@dimen/bg_popup_item_height"
android:elevation="@dimen/deep_shortcuts_elevation"
@@ -31,12 +31,11 @@
android:textAlignment="viewStart"
android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
android:paddingEnd="@dimen/popup_padding_end"
- android:drawableEnd="@drawable/ic_drag_handle"
android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
android:singleLine="true"
android:ellipsize="end"
android:textSize="14sp"
- android:textColor="?android:attr/textColorPrimary"
+ android:textColor="?attr/popupTextColor"
launcher:layoutHorizontal="true"
launcher:iconDisplay="shortcut_popup"
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" />
@@ -48,5 +47,4 @@
android:layout_marginStart="@dimen/popup_padding_start"
android:layout_gravity="start|center_vertical"
android:background="@drawable/ic_deepshortcut_placeholder"/>
-
-</com.android.launcher3.shortcuts.DeepShortcutView>
+</com.android.launcher3.shortcuts.DeepShortcutView>
\ No newline at end of file
diff --git a/res/layout/deep_shortcut_container.xml b/res/layout/deep_shortcut_container.xml
index b6c3f56..bf9124a 100644
--- a/res/layout/deep_shortcut_container.xml
+++ b/res/layout/deep_shortcut_container.xml
@@ -16,7 +16,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/deep_shortcuts_container"
- android:background="@drawable/popup_background_material_u"
+ android:background="@drawable/popup_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="@string/popup_container_iterate_children"
diff --git a/res/layout/deep_shortcut_material_u.xml b/res/layout/deep_shortcut_material_u.xml
deleted file mode 100644
index 2e21ddb..0000000
--- a/res/layout/deep_shortcut_material_u.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.shortcuts.DeepShortcutView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:id="@+id/deep_shortcut_material"
- android:layout_width="@dimen/bg_popup_item_width"
- android:layout_height="@dimen/bg_popup_item_height"
- android:elevation="@dimen/deep_shortcuts_elevation"
- android:background="@drawable/middle_item_primary"
- android:theme="@style/PopupItem" >
-
- <com.android.launcher3.shortcuts.DeepShortcutTextView
- style="@style/BaseIcon"
- android:id="@+id/bubble_text"
- android:background="?android:attr/selectableItemBackground"
- android:gravity="start|center_vertical"
- android:textAlignment="viewStart"
- android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
- android:paddingEnd="@dimen/popup_padding_end"
- android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
- android:singleLine="true"
- android:ellipsize="end"
- android:textSize="14sp"
- android:textColor="?attr/popupTextColor"
- launcher:layoutHorizontal="true"
- launcher:iconDisplay="shortcut_popup"
- launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" />
-
- <View
- android:id="@+id/icon"
- android:layout_width="@dimen/deep_shortcut_icon_size"
- android:layout_height="@dimen/deep_shortcut_icon_size"
- android:layout_marginStart="@dimen/popup_padding_start"
- android:layout_gravity="start|center_vertical"
- android:background="@drawable/ic_deepshortcut_placeholder"/>
-</com.android.launcher3.shortcuts.DeepShortcutView>
\ No newline at end of file
diff --git a/res/layout/developer_options_top_bar.xml b/res/layout/developer_options_top_bar.xml
new file mode 100644
index 0000000..1b138ea
--- /dev/null
+++ b/res/layout/developer_options_top_bar.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:showDividers="middle">
+
+ <EditText
+ android:id="@+id/filter_box"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/developer_options_filter_margins"
+ android:hint="@string/developer_options_filter_hint"
+ android:inputType="text"
+ android:maxLines="1"
+ android:imeOptions="actionDone"
+ />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:text="Apply"
+ android:visibility="invisible"
+ android:id="@+id/flag_apply_btn" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/home_settings.xml b/res/layout/home_settings.xml
index c0f16e2..62900a8 100644
--- a/res/layout/home_settings.xml
+++ b/res/layout/home_settings.xml
@@ -3,22 +3,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <EditText
- android:id="@+id/filter_box"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/developer_options_filter_margins"
- android:hint="@string/developer_options_filter_hint"
- android:visibility="gone"
- android:inputType="text"
- android:maxLines="1"
- android:imeOptions="actionDone"
- />
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@android:id/list_container"/>
-</LinearLayout>
\ No newline at end of file
+ android:layout_height="match_parent"
+ android:id="@android:id/list_container"/>
diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml
index 9327287..bf7b126 100644
--- a/res/layout/popup_container.xml
+++ b/res/layout/popup_container.xml
@@ -13,27 +13,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<com.android.launcher3.popup.PopupContainerWithArrow
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/popup_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:clipToPadding="false"
android:clipChildren="false"
- android:orientation="vertical">
-
- <LinearLayout
- android:id="@+id/deep_shortcuts_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:tag="@string/popup_container_iterate_children"
- android:elevation="@dimen/deep_shortcuts_elevation"
- android:orientation="vertical"/>
-
- <com.android.launcher3.notification.NotificationContainer
- android:id="@+id/notification_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"/>
-</com.android.launcher3.popup.PopupContainerWithArrow>
\ No newline at end of file
+ android:clipToPadding="false"
+ android:orientation="vertical"/>
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icons_container.xml b/res/layout/system_shortcut_icons_container.xml
index fa92ba3..a5c0be3 100644
--- a/res/layout/system_shortcut_icons_container.xml
+++ b/res/layout/system_shortcut_icons_container.xml
@@ -17,9 +17,10 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/system_shortcuts_container"
+ android:tag="@string/popup_container_iterate_children"
android:layout_width="match_parent"
android:layout_height="@dimen/system_shortcut_header_height"
android:orientation="horizontal"
android:gravity="end|center_vertical"
- android:background="@drawable/single_item_primary"
+ android:background="@drawable/popup_background"
android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_icons_container_material_u.xml b/res/layout/system_shortcut_icons_container_material_u.xml
deleted file mode 100644
index fbf18af..0000000
--- a/res/layout/system_shortcut_icons_container_material_u.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/system_shortcuts_container"
- android:tag="@string/popup_container_iterate_children"
- android:layout_width="match_parent"
- android:layout_height="@dimen/system_shortcut_header_height"
- android:orientation="horizontal"
- android:gravity="end|center_vertical"
- android:background="@drawable/popup_background_material_u"
- android:elevation="@dimen/deep_shortcuts_elevation"/>
diff --git a/res/layout/system_shortcut_rows_container.xml b/res/layout/system_shortcut_rows_container.xml
index f992ef5..1940139 100644
--- a/res/layout/system_shortcut_rows_container.xml
+++ b/res/layout/system_shortcut_rows_container.xml
@@ -17,6 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/system_shortcuts_container"
+ android:background="@drawable/popup_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="@string/popup_container_iterate_children"
diff --git a/res/layout/system_shortcut_rows_container_material_u.xml b/res/layout/system_shortcut_rows_container_material_u.xml
deleted file mode 100644
index 006e280..0000000
--- a/res/layout/system_shortcut_rows_container_material_u.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/system_shortcuts_container"
- android:background="@drawable/popup_background_material_u"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:tag="@string/popup_container_iterate_children"
- android:elevation="@dimen/deep_shortcuts_elevation"
- android:orientation="vertical"/>
diff --git a/res/layout/widget_shortcut_container_material_u.xml b/res/layout/widget_shortcut_container_material_u.xml
index aab34e3..3a49c70 100644
--- a/res/layout/widget_shortcut_container_material_u.xml
+++ b/res/layout/widget_shortcut_container_material_u.xml
@@ -17,7 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_shortcut_container"
- android:background="@drawable/popup_background_material_u"
+ android:background="@drawable/popup_background"
android:layout_width="match_parent"
android:layout_height="@dimen/system_shortcut_header_height"
android:orientation="horizontal"
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 32e3b77..276d73e 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -37,11 +37,14 @@
android:id="@+id/pause_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:maxWidth="@dimen/work_fab_width"
android:textColor="@color/work_fab_icon_color"
android:textSize="14sp"
android:includeFontPadding="false"
android:textDirection="locale"
android:text="@string/work_apps_pause_btn_text"
android:layout_marginStart="@dimen/work_fab_text_start_margin"
+ android:ellipsize="end"
+ android:maxLines="1"
style="@style/TextHeadline"/>
</com.android.launcher3.allapps.WorkModeSwitch>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 377025a..dc57332 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Verdeelde skerm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Programinligting vir %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Stoor apppaar"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Raak en hou om \'n legstuk te skuif."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en hou om \'n legstuk te skuif of gebruik gepasmaakte handelinge."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persoonlik"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Werk"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Gesprekke"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Neem notas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Nuttige inligting binne jou bereik"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Jy kan legstukke by jou tuisskerm voeg om inligting te kry sonder om programme oop te maak"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om legstukinstellings te verander"</string>
@@ -59,7 +61,7 @@
<string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
<string name="label_application" msgid="8531721983832654978">"Program"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle programme"</string>
+ <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Raak en hou om \'n kortpad te skuif."</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dubbeltik en hou om \'n kortpad te skuif of gebruik gepasmaakte handelinge."</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Vouer hernoem na <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Apppaar: <xliff:g id="APP1">%1$s</xliff:g> en <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Muurpapier en styl"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Wysig tuisskerm"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tuis-instellings"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Deursoek jou foon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Deursoek jou tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misluk: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privaat ruimte"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 4638bc3..4bfea99 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -20,24 +20,25 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"ስራ"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ሥራ"</string>
<string name="activity_not_found" msgid="8071924732094499514">"መተግበሪያ አልተጫነም።"</string>
<string name="activity_not_available" msgid="7456344436509528827">"መተግበሪያ አይገኝም"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"የወረደው መተግበሪያ ደህንነቱ በተጠበቀ ሁኔታ ውስጥ ተሰናክሏል"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ምግብሮች በደህንነቱ የተጠበቀ ሁኔታ ተሰናክለዋል"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"አቋራጭ አይገኝም"</string>
<string name="home_screen" msgid="5629429142036709174">"መነሻ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"የተከፈለ ማያ ገጽ"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"የተከፈለ ማያ ገፅ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"የመተግበሪያ መረጃ ለ%1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"የመተግበሪያ ጥምረትን ያስቀምጡ"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ምግብርን ለማንቀሳቀስ ይንኩ እና ይያዙ።"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ምግብርን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"የ<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ምግብር"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"በመነሻ ማያ ገጽ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት"</string>
- <string name="add_to_home_screen" msgid="9168649446635919791">"ወደ መነሻ ማያ ገጽ አክል"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ምግብር ወደ መነሻ ማያ ገጽ ታክሏል"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"በመነሻ ማያ ገፅ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት"</string>
+ <string name="add_to_home_screen" msgid="9168649446635919791">"ወደ መነሻ ማያ ገፅ አክል"</string>
+ <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ምግብር ወደ መነሻ ማያ ገፅ ታክሏል"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"የአስተያየት ጥቆማዎች"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ምግብር}one{# ምግብሮች}other{# ምግብሮች}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# አቋራጭ}one{# አቋራጭ}other{# አቋራጮች}}"</string>
@@ -48,8 +49,9 @@
<string name="no_widgets_available" msgid="4337693382501046170">"መግብሮች እና አቋራጮች አይገኙም"</string>
<string name="no_search_results" msgid="3787956167293097509">"ምንም መግብሮች ወይም አቋራጮች አልተገኙም"</string>
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"የግል"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ስራ"</string>
+ <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ሥራ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ውይይቶች"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"የማስታወሻ አያያዝ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"በጣቶችዎ ጫፎች ላይ ጠቃሚ መረጃ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"መተግበሪያዎችን ሳይከፍቱ መረጃ ለማግኘት በመነሻ ማያ ገጽዎ ላይ ምግብሮችን ማከል ይችላሉ"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"የምግብር ቅንብሮችን ለመለወጥ መታ ያድርጉ"</string>
@@ -63,7 +65,7 @@
<string name="notifications_header" msgid="1404149926117359025">"ማሳወቂያዎች"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"አቋራጭን ለማንቀሳቀስ ይንኩ እና ይያዙ"</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"አቋራጭን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
- <string name="out_of_space" msgid="6455557115204099579">"በዚህ የመነሻ ማያ ገጽ ላይ ምንም ክፍል የለም"</string>
+ <string name="out_of_space" msgid="6455557115204099579">"በዚህ የመነሻ ማያ ገፅ ላይ ምንም ክፍል የለም"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"በተወዳጆች መሣቢያ ውስጥ ተጨማሪ ቦታ የለም"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"የመተግበሪያዎች ዝርዝር"</string>
<string name="all_apps_search_results" msgid="5889367432531296759">"የፍለጋ ውጤቶች"</string>
@@ -88,9 +90,9 @@
<string name="folder_hint_text" msgid="5174843001373488816">"ስም ያርትዑ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ተሰናክሏል"</string>
<string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{{app_name}፣ # ማሳወቂያ አለው}one{{app_name}፣ # ማሳወቂያዎች አሉት}other{{app_name}፣ # ማሳወቂያዎች አሉት}}"</string>
- <string name="default_scroll_format" msgid="7475544710230993317">"ገጽ %1$d ከ%2$d"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"መነሻ ማያ ገጽ %1$d ከ%2$d"</string>
- <string name="workspace_new_page" msgid="257366611030256142">"አዲስ የመነሻ ማያ ገጽ"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"ገፅ %1$d ከ%2$d"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"መነሻ ማያ ገፅ %1$d ከ%2$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"አዲስ የመነሻ ማያ ገፅ"</string>
<string name="folder_opened" msgid="94695026776264709">"አቃፊ ተከፍቷል፣ <xliff:g id="WIDTH">%1$d</xliff:g> በ<xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"አቃፊን ለመዝጋት መታ ያድርጉ"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ዳግም የተሰጠውን ስም ለማስቀመጥ መታ ያድርጉ"</string>
@@ -98,13 +100,12 @@
<string name="folder_renamed" msgid="1794088362165669656">"አቃፊ <xliff:g id="NAME">%1$s</xliff:g> ተብሎ ዳግም ተሰይሟል"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ንጥሎች"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ወይም ተጨማሪ ንጥሎች"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"የግድግዳ ወረቀቶች"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"የመተግበሪያ ጥምረት፦ <xliff:g id="APP1">%1$s</xliff:g> እና <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ልጣፍ እና ቅጥ"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"መነሻ ማያ ገጽን አርትዕ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"የመነሻ ቅንብሮች"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
- <string name="allow_rotation_title" msgid="7222049633713050106">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
+ <string name="allow_rotation_title" msgid="7222049633713050106">"የመነሻ ማያ ገፅ ማሽከርከርን ይፍቀዱ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ስልኩ ሲዞር"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"የማሳወቂያ ነጥቦች"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"አብራ"</string>
@@ -130,9 +131,9 @@
<string name="dialog_remove" msgid="6510806469849709407">"አስወግድ"</string>
<string name="widgets_list" msgid="796804551140113767">"የመግብሮች ዝርዝር"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"የመግብሮች ዝርዝር ተዘግቷል"</string>
- <string name="action_add_to_workspace" msgid="215894119683164916">"ወደ መነሻ ማያ ገጽ አክል"</string>
+ <string name="action_add_to_workspace" msgid="215894119683164916">"ወደ መነሻ ማያ ገፅ አክል"</string>
<string name="action_move_here" msgid="2170188780612570250">"ንጥልን ወደዚህ ውሰድ"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"ወደ መነሻ ማያ ገጽ ንጥል ታክሏል"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ወደ መነሻ ማያ ገፅ ንጥል ታክሏል"</string>
<string name="item_removed" msgid="851119963877842327">"ንጥል ነገር ተንቀሳቅሷል"</string>
<string name="undo" msgid="4151576204245173321">"ቀልብስ"</string>
<string name="action_move" msgid="4339390619886385032">"ንጥልን አንቀሳቅስ"</string>
@@ -145,7 +146,7 @@
<string name="added_to_folder" msgid="4793259502305558003">"ንጥል ወደ አቃፊ ታክሏል"</string>
<string name="create_folder_with" msgid="4050141361160214248">"አቃፊ ፍጠር ከዚህ ጋር፦ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"አቃፊ ተፈጥሮዋል"</string>
- <string name="action_move_to_workspace" msgid="39528912300293768">"ወደ መነሻ ማያ ገጽ አንቀሳቅስ"</string>
+ <string name="action_move_to_workspace" msgid="39528912300293768">"ወደ መነሻ ማያ ገፅ አንቀሳቅስ"</string>
<string name="action_resize" msgid="1802976324781771067">"መጠን ቀይር"</string>
<string name="action_increase_width" msgid="8773715375078513326">"ስፋት ጨምር"</string>
<string name="action_increase_height" msgid="459390020612501122">"ቁመት ጨምር"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ስልክዎን ይፈልጉ"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ጡባዊዎን ይፈልጉ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"አልተሳካም፦ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"የግል ቦታ"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 094fcac..9cbfbfa 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"تقسيم الشاشة"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"معلومات تطبيق %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"حفظ إعدادات ميزة \"استخدام تطبيقين في الوقت نفسه\""</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"انقر مع الاستمرار لنقل أداة."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -47,9 +48,10 @@
<string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"محو النص من مربّع البحث"</string>
<string name="no_widgets_available" msgid="4337693382501046170">"الأدوات والاختصارات غير متاحة."</string>
<string name="no_search_results" msgid="3787956167293097509">"لم يتم العثور على تطبيقات مصغّرة أو اختصارات."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"الأدوات الشخصية"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"أدوات العمل"</string>
+ <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"التطبيقات الشخصية"</string>
+ <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"تطبيقات العمل"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"المحادثات"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"تدوين الملاحظات"</string>
<string name="widget_education_header" msgid="4874760613775913787">"معلومات مفيدة في متناول يديك"</string>
<string name="widget_education_content" msgid="1731667670753497052">"للحصول على معلومات بدون فتح التطبيقات، يمكنك إضافة التطبيقات المصغّرة إلى الشاشة الرئيسية."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"انقر لتغيير إعدادات الأداة"</string>
@@ -82,7 +84,7 @@
<string name="permlab_write_settings" msgid="4820028712156303762">"تعديل الإعدادات والاختصارات على الشاشة الرئيسية"</string>
<string name="permdesc_write_settings" msgid="726859348127868466">"يسمح هذا الإذن للتطبيق بتغيير الإعدادات والاختصارات على الشاشة الرئيسية."</string>
<string name="gadget_error_text" msgid="740356548025791839">"يتعذّر تحميل الأداة."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"إعدادات الأداة"</string>
+ <string name="gadget_setup_text" msgid="8348374825537681407">"إعدادات التطبيق المصغّر"</string>
<string name="gadget_complete_setup_text" msgid="309040266978007925">"انقر لإكمال الإعداد."</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"هذا تطبيق نظام وتتعذر إزالته."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"تعديل الاسم"</string>
@@ -98,16 +100,15 @@
<string name="folder_renamed" msgid="1794088362165669656">"تمت إعادة تسمية المجلد إلى <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر أو أكثر"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"استخدام تطبيقين في الوقت نفسه: تطبيق \"<xliff:g id="APP1">%1$s</xliff:g>\" و\"<xliff:g id="APP2">%2$s</xliff:g>\""</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والأسلوب"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"تعديل الشاشة الرئيسية"</string>
<string name="settings_button_text" msgid="8873672322605444408">"إعدادات الشاشة الرئيسية"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"نقاط الإشعارات"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّلة"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"الإعداد مفعّل"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"غير مفعّل"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"يلزم تمكين الوصول إلى الإشعارات"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"لعرض نقاط الإشعارات، يجب تفعيل إشعارات التطبيق في <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"البحث في هاتفك"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"البحث في جهازك اللوحي"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"تعذَّر <xliff:g id="WHAT">%1$s</xliff:g>."</string>
+ <string name="private_space_label" msgid="2359721649407947001">"مساحة خاصة"</string>
</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 583a5c4..6368312 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"বিভাজিত স্ক্ৰীন"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sৰ বাবে এপৰ তথ্য"</string>
<string name="save_app_pair" msgid="5647523853662686243">"এপৰ পেয়াৰ ছেভ কৰক"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ৱিজেট স্থানান্তৰ কৰিবলৈ টিপি ধৰি ৰাখক।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"কোনো ৱিজেট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ব্যক্তিগত"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"কৰ্মস্থান"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"বাৰ্তালাপ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"টোকা গ্ৰহণ কৰা"</string>
<string name="widget_education_header" msgid="4874760613775913787">"আপোনাৰ আঙুলিৰে টিপতে উপযোগী তথ্য পাওক"</string>
<string name="widget_education_content" msgid="1731667670753497052">"এপ্ নোখোলাকৈ তথ্য পাবলৈ আপুনি নিজৰ গৃহ স্ক্ৰীনত ৱিজেট যোগ দিব পাৰে"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ৱিজেটৰ ছেটিং সলনি কৰিবলৈ টিপক"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"ফ\'ল্ডাৰৰ নাম সলনি কৰি <xliff:g id="NAME">%1$s</xliff:g> কৰা হৈছে"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা বস্তু"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা অথবা তাতকৈ অধিক বস্তু"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ৱালপেপাৰসমূহ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"এপ্ পেয়াৰ কৰা: <xliff:g id="APP1">%1$s</xliff:g> আৰু <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ৱালপেপাৰ আৰু শৈলী"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"গৃহ স্ক্ৰীন সম্পাদনা কৰক"</string>
<string name="settings_button_text" msgid="8873672322605444408">"গৃহ ছেটিং"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"আপোনাৰ ফ’নৰ বস্তু সন্ধান কৰক"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"আপোনাৰ টেবলেটৰ বস্তু সন্ধান কৰক"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"বিফল: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ব্যক্তিগত স্পে’চ"</string>
</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 2879158..2ec448d 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekran bölünməsi"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ilə bağlı tətbiq məlumatı"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Tətbiq cütünü saxlayın"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidceti daşımaq üçün toxunub saxlayın."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidceti daşımaq üçün iki dəfə toxunub saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Şəxsi"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"İş"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Söhbətlər"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Qeydgötürmə"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Faydalı məlumatlar barmaqlarınızın ucunda"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Tətbiqləri açmadan məlumat almaq üçün Əsas ekrana vidcet əlavə edə bilərsiniz"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidcet ayarlarını dəyişmək üçün toxunun"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Qovluq adı <xliff:g id="NAME">%1$s</xliff:g> ilə dəyişdirildi"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> element"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> və ya daha çox element"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Tətbiq cütü: <xliff:g id="APP1">%1$s</xliff:g> və <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Divar kağızı və üslub"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Əsas ekranı redaktə edin"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Əsas ekran çevrilsin"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Telefonunuzu axtarın"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Planşetinizi axtarın"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Alınmadı: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Şəxsi yer"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index be538fe..81da8a8 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podeljeni ekran"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji za: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Sačuvaj par aplikacija"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite radi pomeranja vidžeta."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da biste pomerali vidžet ili koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Lično"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Konverzacije"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pravljenje beležaka"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Da biste pronašli informacije bez otvaranja aplikacija, možete da dodate vidžete na početni ekran"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promenili podešavanja vidžeta"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder je preimenovan u <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par aplikacija: <xliff:g id="APP1">%1$s</xliff:g> i <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadina i stil"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Izmeni početni ekran"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Podešavanja početnog ekrana"</string>
@@ -156,8 +158,8 @@
<string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
<string name="accessibility_close" msgid="2277148124685870734">"Zatvori"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Obaveštenje je odbačeno"</string>
- <string name="all_apps_personal_tab" msgid="4190252696685155002">"Lične"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Poslovne"</string>
+ <string name="all_apps_personal_tab" msgid="4190252696685155002">"Lično"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Posao"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Poslovni profil"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Poslovne aplikacije su označene značkom i IT administrator može da ih vidi"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Važi"</string>
@@ -168,9 +170,10 @@
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Poslovne aplikacije su označene značkom i IT administrator može da ih vidi"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Važi"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pauziraj poslovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Opozovi pauzu"</string>
+ <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ponovo aktiviraj"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Pretražite telefon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Pretražite tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 7bdd1ec..5bbac0f 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Падзелены экран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Інфармацыя пра праграму для: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Захаваць спалучэнне праграм"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Націсніце і ўтрымлівайце віджэт для перамяшчэння."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Асабістыя"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Працоўныя"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Размовы"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Стварэнне нататак"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Карысная інфармацыя ў вас пад рукой"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Каб не адкрываць праграмы для прагляду патрэбнай інфармацыі, дадайце віджэты на галоўны экран"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Націсніце, каб змяніць налады віджэта"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Папка перайменавана ў <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g> ці больш"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Спалучэнне праграм: <xliff:g id="APP1">%1$s</xliff:g> і <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Шпалеры і стыль"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Змяніць Галоўны экран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Налады галоўнага экрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дазволіць паварот галоўнага экрана"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Пошук на тэлефоне"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Пошук на планшэце"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не ўдалося: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Прыватная вобласць"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 992abeb..bdae209 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделен екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Информация за приложението за %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Запазване на двойката приложения"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Докоснете и задръжте за преместване на приспособление"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лични"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Служебни"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Разговори"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Водене на бележки"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Лесен достъп до полезна информация"</string>
<string name="widget_education_content" msgid="1731667670753497052">"За да получавате информация, без да отваряте приложенията, можете да добавите приспособления към началния екран"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Докоснете, за да промените настройките на приспособлението"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Папката е преименувана на „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> елемента"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> или повече елементи"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Двойка приложения: <xliff:g id="APP1">%1$s</xliff:g> и <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тапет и стил"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Редактиране на началния екран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Настройки за началния екран"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Търсене в телефона ви"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Търсене в таблета ви"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Неуспешно: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Лично пространство"</string>
</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 995166f..3a57581 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"স্প্লিট স্ক্রিন"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-এর জন্য অ্যাপ সম্পর্কিত তথ্য"</string>
<string name="save_app_pair" msgid="5647523853662686243">"অ্যাপ পেয়ার সেভ করুন"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"কোনও উইজেট সরাতে সেটি টাচ করে ধরে রাখুন।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ব্যক্তিগত"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"অফিস"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"কথোপকথন"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"নোট নেওয়া"</string>
<string name="widget_education_header" msgid="4874760613775913787">"সহজেই দরকারি তথ্য পান"</string>
<string name="widget_education_content" msgid="1731667670753497052">"অ্যাপ না খুলেই তথ্য পাওয়ার জন্য, হোম স্ক্রিনে উইজেট যোগ করতে পারবেন"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"উইজেট সেটিংস পরিবর্তন করতে ট্যাপ করুন"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"ফোল্ডারের নাম পাল্টে <xliff:g id="NAME">%1$s</xliff:g> করা হয়েছে"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি আইটেম"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি বা তার বেশি আইটেম"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"অ্যাপ পেয়ার: <xliff:g id="APP1">%1$s</xliff:g> ও <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ওয়ালপেপার এবং স্টাইল"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"হোম স্ক্রিন এডিট করুন"</string>
<string name="settings_button_text" msgid="8873672322605444408">"হোম সেটিংস"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"হোম স্ক্রিন রোটেট করার অনুমতি দিন"</string>
@@ -160,7 +161,7 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ব্যক্তিগত"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"অফিস"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"অফিসের প্রোফাইল"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেগুলি দেখতে পাবেন"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"অফিস অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেগুলি দেখতে পাবেন"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"বুঝেছি"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"অফিস অ্যাপ বন্ধ করা আছে"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"আপনার অফিসের অ্যাপ থেকে আপনি কোনও বিজ্ঞপ্তি পাবেন না"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ফোনে সার্চ করে দেখুন"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"আপনার ট্যাবলেটে সার্চ করুন"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"কাজটি করা যায়নি: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ব্যক্তিগত স্পেস"</string>
</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 20fc18a..e453982 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podijeljeni ekran"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Sačuvaj par aplikacija"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da pomjerite vidžet."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da pomjerite vidžet ili da koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Lično"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Razgovori"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pisanje bilješki"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Da dobijete informacije bez otvaranja aplikacija, možete dodati vidžete na početni ekran"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da promijenite postavke vidžeta"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Ime foldera je promijenjeno u <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, br. stavki: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadinske slike"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par aplikacija: <xliff:g id="APP1">%1$s</xliff:g> i <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadinska slika i stil"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Uredi Početni ekran"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog ekrana"</string>
@@ -168,9 +170,10 @@
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Poslovne aplikacije su označene i vaš IT administrator ih može vidjeti"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Razumijem"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Pauziraj poslovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Prekini pauzu"</string>
+ <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Ponovo pokreni"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Pretražite telefon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Pretražite tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privatan prostor"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 7d45271..b03b4ec 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informació de l\'aplicació %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Desa la parella d\'aplicacions"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Fes doble toc i mantén premut per moure un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Fes doble toc i mantén premut per moure un widget o per utilitzar accions personalitzades."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Treball"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Converses"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Presa de notes"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informació útil a l\'abast de la mà"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Per obtenir informació sense obrir les aplicacions, pots afegir widgets a la pantalla d\'inici"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca per canviar la configuració del widget"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"S\'ha canviat el nom de la carpeta a <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elements"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o més elements"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Parella d\'aplicacions: <xliff:g id="APP1">%1$s</xliff:g> i <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Estil i fons de pantalla"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Edita la pantalla d\'inici"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Config. pantalla d\'inici"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permet la rotació de la pantalla d\'inici"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Cerca al telèfon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Cerca a la tauleta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espai privat"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index ac093e4..a39a1d5 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -27,9 +27,10 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"V nouzovém režimu jsou widgety zakázány."</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Zkratka není k dispozici"</string>
<string name="home_screen" msgid="5629429142036709174">"Domů"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdělená obrazovka"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdělit obrazovku"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informace o aplikaci %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Uložit pár aplikací"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget přesunete klepnutím a podržením."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobní"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Práce"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Konverzace"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Psaní poznámek"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Užitečné informace na dosah"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Pokud chcete mít informace k dispozici bez otevírání aplikací, můžete si na plochu přidat widgety"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím změníte nastavení widgetu"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Složka přejmenována na <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g> nebo více"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Dvojice aplikací: <xliff:g id="APP1">%1$s</xliff:g> a <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta a styl"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Upravit plochu"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Nastavení plochy"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Povolit otáčení plochy"</string>
@@ -172,6 +173,7 @@
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Zrušit pozastavení"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Prohledávání telefonu"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Vyhledávat na tabletu"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Vyhledávání na tabletu"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Selhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Soukromý prostor"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 66a191a..faebb41 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Opdel skærm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinfo for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Gem appsammenknytning"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Hold en widget nede for at flytte den."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryk to gange, og hold en widget nede for at flytte den eller bruge tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -47,9 +48,10 @@
<string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Ryd teksten i søgefeltet"</string>
<string name="no_widgets_available" msgid="4337693382501046170">"Der er ingen tilgængelige widgets eller genveje"</string>
<string name="no_search_results" msgid="3787956167293097509">"Der blev ikke fundet nogen widgets eller genveje"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personlige"</string>
+ <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personlig"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Arbejde"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Samtaler"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Notetagning"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Nyttige oplysninger lige ved hånden"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Hvis du vil have oplysninger uden at åbne apps, kan du føje widgets til din startskærm"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryk for at ændre widgetindstillinger"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mappen er omdøbt til <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Appsammenknytning: <xliff:g id="APP1">%1$s</xliff:g> og <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Baggrund og stil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Rediger startskærm"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Indst. for startskærm"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillad rotation af startskærmen"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Søg på din telefon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Søg på din tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislykket: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privat rum"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 959840d..61e4859 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -27,9 +27,10 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets im abgesicherten Modus deaktiviert"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Verknüpfung nicht verfügbar"</string>
<string name="home_screen" msgid="5629429142036709174">"Startbildschirm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Geteilter Bildschirm"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Splitscreen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App-Info für %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"App-Paar speichern"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Zum Verschieben des Widgets berühren und halten"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Doppeltippen und halten, um ein Widget zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Privat"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Geschäftlich"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Unterhaltungen"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Notizen"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Praktische Informationen – immer zur Hand"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Wenn du Informationen erhalten möchtest, ohne Apps zu öffnen, kannst du deinem Startbildschirm Widgets hinzufügen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tippen, um die Widget-Einstellungen zu ändern"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Ordner umbenannt in <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> Elemente"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> oder mehr Elemente"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund & Stil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App-Paar: <xliff:g id="APP1">%1$s</xliff:g> und <xliff:g id="APP2">%2$s</xliff:g>"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund und Stil"</string>
+ <string name="edit_home_screen" msgid="8947858375782098427">"Startbildschirm bearbeiten"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Einstellungen"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Drehen des Startbildschirms zulassen"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Auf dem Smartphone suchen"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Auf dem Tablet suchen"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Fehler: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privater Bereich"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index b517975..b98ae4f 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Διαχωρισμός οθόνης"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Πληροφορίες εφαρμογής για %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Αποθήκευση ζεύγους εφαρμογών"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Πατήστε παρατετ. για μετακίνηση γραφ. στοιχείου."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Προσωπικά"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Εργασίας"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Συζητήσεις"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Δημιουργία σημειώσεων"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Χρήσιμες πληροφορίες στη διάθεσή σας"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Για να λάβετε πληροφορίες χωρίς να ανοίξετε εφαρμογές, μπορείτε να προσθέσετε γραφικά στοιχεία στην αρχική οθόνη."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Πατήστε για αλλαγή των ρυθμίσεων του γραφικού στοιχείου"</string>
@@ -63,7 +65,7 @@
<string name="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Πατήστε παρατεταμένα για μετακίνηση συντόμευσης."</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση συντόμευσης ή χρήση προσαρμοσμένων ενεργειών."</string>
- <string name="out_of_space" msgid="6455557115204099579">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη"</string>
+ <string name="out_of_space" msgid="6455557115204099579">"Δεν υπάρχει χώρος σε αυτή την αρχική οθόνη"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Δεν υπάρχει επιπλέον χώρος στην περιοχή Αγαπημένα"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Λίστα εφαρμογών"</string>
<string name="all_apps_search_results" msgid="5889367432531296759">"Αποτελέσματα αναζήτησης"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Ο φάκελος μετονομάστηκε σε <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> στοιχεία"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ή περισσότερα στοιχεία"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Ζεύγος εφαρμογών: <xliff:g id="APP1">%1$s</xliff:g> και <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Ταπετσαρία και στιλ"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Επεξεργασία αρχικής οθόνης"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ρυθμίσεις Αρχ. Οθ."</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Αναζήτηση στο τηλέφωνό σας"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Αναζήτηση στο tablet σας"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Αποτυχία: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Ιδιωτικός χώρος"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index eea6581..8e55910 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Save app pair"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
<string name="widget_education_content" msgid="1731667670753497052">"To get info without opening apps, you can add widgets to your home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App pair: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper and style"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit home screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Search your phone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Search your tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index b00fee6..c5e5caf 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Save app pair"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch & hold to move a widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
+ <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
+ <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap and hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Touch & hold the widget to move it around the home screen"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Touch and hold the widget to move it around the home screen"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"Add to home screen"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget added to home screen"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Suggestions"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
<string name="widget_education_content" msgid="1731667670753497052">"To get info without opening apps, you can add widgets to your home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
@@ -61,8 +63,8 @@
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch & hold to move a shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap & hold to move a shortcut or use custom actions."</string>
+ <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch and hold to move a shortcut."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap and hold to move a shortcut or use custom actions."</string>
<string name="out_of_space" msgid="6455557115204099579">"No room on this home screen"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favorites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
@@ -98,8 +100,8 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App pair: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper and style"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit Home Screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Search your phone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Search your tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index eea6581..8e55910 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Save app pair"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
<string name="widget_education_content" msgid="1731667670753497052">"To get info without opening apps, you can add widgets to your home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App pair: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper and style"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit home screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Search your phone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Search your tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index eea6581..8e55910 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Save app pair"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
<string name="widget_education_content" msgid="1731667670753497052">"To get info without opening apps, you can add widgets to your home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App pair: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper and style"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit home screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Search your phone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Search your tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 31fea4b..1ad2059 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Save app pair"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch & hold to move a widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap & hold to move a widget or use custom actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Note-taking"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
<string name="widget_education_content" msgid="1731667670753497052">"To get info without opening apps, you can add widgets to your home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App pair: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit Home Screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Search your phone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Search your tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Private space"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 35b6124..b8d213b 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la app de %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Guardar vinculación de apps"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén presionado para mover un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Presiona dos veces y mantén presionado para mover un widget o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personales"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabajo"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversaciones"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Tomar notas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Información útil a tu alcance"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Para recibir información de apps sin abrirlas, puedes agregar widgets a la pantalla principal"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Presiona para cambiar la configuración del widget"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"El nombre de la carpeta se cambió a <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o más elementos"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Vinculación de apps: <xliff:g id="APP1">%1$s</xliff:g> y <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fondo de pantalla y estilo"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Editar pantalla principal"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configuración de pantalla principal"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir la rotación de la pantalla principal"</string>
@@ -172,6 +173,7 @@
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Reanudar"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Busca tu teléfono"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Busca tu tablet"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Busca en tu tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 323feb0..c13ce1a 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la aplicación %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Guardar aplicaciones emparejadas"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personales"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabajo"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversaciones"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Toma de notas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Información útil al alcance de la mano"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Para ver información sin abrir una aplicación, puedes añadir widgets a la pantalla de inicio"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar los ajustes del widget"</string>
@@ -98,14 +100,14 @@
<string name="folder_renamed" msgid="1794088362165669656">"Se ha cambiado el nombre de la carpeta a <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> elementos)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> o más elementos)"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Aplicaciones emparejadas: <xliff:g id="APP1">%1$s</xliff:g> y <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fondo de pantalla y estilo"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Editar pantalla de inicio"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ajustes de la pantalla de inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitado por el administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificación"</string>
+ <string name="notification_dots_title" msgid="9062440428204120317">"Burbujas de notificación"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activado"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivadas"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Se necesita acceso a las notificaciones"</string>
@@ -171,6 +173,7 @@
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Reanudar"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Busca en tu teléfono"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Busca en tu tablet"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Buscar en tu tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Se ha producido un error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index cf6e1c4..76bd494 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Jagatud ekraanikuva"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Rakenduse teave: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Salvesta rakendusepaar"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidina teisaldamiseks puudutage ja hoidke all."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Vidina teisaldamiseks avakuval puudutage vidinat ja hoidke seda all"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Vidina teisaldamiseks avakuval puudutage vidinat pikalt"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"Lisa avakuvale"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g> lisati avakuvale"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Soovitused"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Isiklikud"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Töö"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Vestlused"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Märkmete tegemine"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Kasulik teave on teie käeulatuses"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Teabe saamiseks rakendusi avamata võite oma avakuvale lisada vidinaid"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Puudutage vidina seadete muutmiseks"</string>
@@ -71,7 +73,7 @@
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Töörakenduste loend"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Eemalda"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalli"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduste teave"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduse teave"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installimine"</string>
<string name="dismiss_prediction_label" msgid="3357562989568808658">"Ära soovita rakendust"</string>
<string name="pin_prediction" msgid="4196423321649756498">"Kinnita ennustus"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> üksust"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> või rohkem üksust"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Rakendusepaar: <xliff:g id="APP1">%1$s</xliff:g> ja <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Taustapilt ja stiil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Muuda avaekraani"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Avakuva seaded"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Luba avakuva pööramine"</string>
@@ -169,9 +170,10 @@
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Töörakendustel on märk ja need on teie IT-administraatorile nähtavad"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Selge"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Peata töörakendused"</string>
- <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Jätka"</string>
+ <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Lõpeta peatamine"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Otsimine telefonist"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Otsimine tahvelarvutist"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nurjus: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privaatne ruum"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 88f3a95..d73c885 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -27,9 +27,10 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Lasterbideak ez daude erabilgarri"</string>
<string name="home_screen" msgid="5629429142036709174">"Hasierako pantaila"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Zatitu pantaila"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantaila zatitzea"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s aplikazioari buruzko informazioa"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Gorde aplikazio parea"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Eduki sakatuta widget bat mugitzeko."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Sakatu birritan eta eduki sakatuta widget bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pertsonalak"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Lanekoak"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Elkarrizketak"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Oharrak idazteko"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informazio erabilgarria beti eskura"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Aplikaziorik ireki beharrik gabe informazioa zuzenean jasotzeko, gehitu widgetak hasierako pantailan"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Sakatu hau widgeten ezarpenak aldatzeko"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Karpetari <xliff:g id="NAME">%1$s</xliff:g> izena eman zaio"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu edo gehiago)"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Aplikazio parea: <xliff:g id="APP1">%1$s</xliff:g> eta <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Horma-papera eta estiloa"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Editatu hasierako pantaila"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Hasierako pantailaren ezarpenak"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Eman hasierako pantaila biratzeko baimena"</string>
@@ -162,7 +163,7 @@
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Laneko profila"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Laneko aplikazioek bereizgarriak dituzte, eta IKT saileko administratzaileak ikus ditzake"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Ados"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Pausatu egin dira laneko aplikazioak"</string>
+ <string name="work_apps_paused_title" msgid="3040901117349444598">"Pausatuta daude laneko aplikazioak"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"Ez duzu jasoko laneko aplikazioen jakinarazpenik"</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"Laneko aplikazioek ezin dute jakinarazpenik bidali, bateria erabili edo kokapena atzitu"</string>
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"Ez duzu jasoko laneko aplikazioen telefono-deirik, testu-mezurik edo jakinarazpenik"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Bilatu telefonoan"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Bilatu tabletan"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Huts egin du: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Eremu pribatua"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 6708519..fc42f54 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"صفحهٔ دونیمه"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"اطلاعات برنامه %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ذخیره جفت برنامه"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"برای جابهجا کردن ابزارک، لمس کنید و نگه دارید."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"برای جابهجا کردن ابزارک یا استفاده از کنشهای سفارشی، دوضربه بزنید و نگه دارید."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ابزارکهای شخصی"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"کار"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"مکالمهها"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"یادداشتبرداری"</string>
<string name="widget_education_header" msgid="4874760613775913787">"دسترسی آسان به اطلاعات سودمند"</string>
<string name="widget_education_content" msgid="1731667670753497052">"با افزودن ابزارکها به صفحه اصلی میتوانید اطلاعات را بدون باز کردن برنامهها دریافت کنید"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"برای تغییر تنظیمات ابزارک، ضربه بزنید"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"نام پوشه به <xliff:g id="NAME">%1$s</xliff:g> تغییر کرد"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد یا بیشتر"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواریها"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"جفت برنامه: <xliff:g id="APP1">%1$s</xliff:g> و <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"کاغذدیواری و سبک"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ویرایش «صفحه اصلی»"</string>
<string name="settings_button_text" msgid="8873672322605444408">"تنظیمات صفحه اصلی"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"جستجوی تلفن"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"جستجوی رایانه لوحی"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناموفق بود: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"فضای خصوصی"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index df7b6ac..a567eba 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Jaettu näyttö"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Sovellustiedot: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Tallenna sovelluspari"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Kosketa pitkään, niin voit siirtää widgetiä."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Kaksoisnapauta ja paina pitkään, niin voit siirtää widgetiä tai käyttää muokattuja toimintoja."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Henkilökohtaiset"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Työ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Keskustelut"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Muistiinpanojen tekeminen"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Hyödyllisiä tietoja käden ulottuvilla"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Jos haluat nähdä tietoja avaamatta sovelluksia, voit lisätä aloitusnäytölle widgetejä"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Napauta, niin voit muuttaa widgetin asetuksia"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Kansion nimeksi vaihdettiin <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, ainakin <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Sovelluspari: <xliff:g id="APP1">%1$s</xliff:g> ja <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Taustakuva ja tyyli"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Muokkaa aloitusnäyttöä"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Aloitusnäyttö"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Salli aloitusnäytön kiertäminen"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Hae puhelimesta"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Hae tabletilta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Epäonnistui: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Yksityinen tila"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 6adcb61..a6f5053 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Écran partagé"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Renseignements sur l\'appli pour %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Enregistrer la paire d\'applications"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Maintenez le doigt sur un widget pour le déplacer."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Touchez 2x un widget et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personnels"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Professionnels"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Prise de note"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Renseignements utiles à portée de main"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Pour obtenir des informations sans ouvrir d\'applications, vous pouvez ajouter des widgets à votre écran d\'accueil"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Touchez pour modifier les paramètres du widget"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Nouveau nom du dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> élément(s)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Paire d\'applications : <xliff:g id="APP1">%1$s</xliff:g> et <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fond d\'écran et style"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Modifier l\'écran d\'accueil"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Paramètres d\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Autoriser la rotation de l\'écran d\'accueil"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Rechercher sur votre téléphone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Rechercher sur votre tablette"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 8b54628..9e09a5c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Écran partagé"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Infos sur l\'appli pour %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Enregistrer la paire d\'applis"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Appuyez de manière prolongée sur un widget pour le déplacer."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Appuyez deux fois et maintenez la pression pour déplacer widget ou utiliser actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personnels"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Professionnels"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Prise de notes"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Infos utiles à portée de main"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Pour obtenir des infos sans ouvrir d\'applis, vous pouvez ajouter des widgets à votre écran d\'accueil"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Appuyez pour modifier les paramètres du widget"</string>
@@ -98,17 +100,16 @@
<string name="folder_renamed" msgid="1794088362165669656">"Nouveau nom du dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Paire d\'applications : <xliff:g id="APP1">%1$s</xliff:g> et <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fond d\'écran et style"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Modifier l\'écran d\'accueil"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Paramètres de l\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Pastilles de notification"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Activé"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivées"</string>
+ <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivé"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Accès aux notifications requis"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les pastilles de notification, activez les notifications de l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
@@ -162,7 +163,7 @@
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil professionnel"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Les applis professionnelles sont identifiées par un badge et votre administrateur informatique peut les voir"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Applications professionnelles en veille"</string>
+ <string name="work_apps_paused_title" msgid="3040901117349444598">"Applis professionnelles en pause"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"Vous ne recevrez pas de notifications de vos applications professionnelles"</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"Vos applis professionnelles ne peuvent pas vous envoyer de notifications, utiliser votre batterie ni accéder à votre position"</string>
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"Vous ne recevrez pas d\'appels téléphoniques, de messages ni de notifications de vos applications professionnelles"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Rechercher sur votre téléphone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Rechercher sur votre tablette"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index c1f4f3c..41c30c2 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Información da aplicación para %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Gardar emparellamento de aplicacións"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén premido un widget para movelo."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dúas veces un widget e manteno premido para movelo ou utiliza accións personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Widgets persoais"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Widgets do traballo"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Toma de notas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Información útil ao teu alcance"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Se queres obter información sen abrir as aplicacións, podes engadir widgets á pantalla de inicio"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar a configuración do widget"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"O cartafol cambiou o nome a <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos ou máis"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Emparellamento de aplicacións: <xliff:g id="APP1">%1$s</xliff:g> e <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Estilo e fondo de pantalla"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Editar pantalla de inicio"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Axustes de Inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir xirar a pantalla de inicio"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Buscar no teléfono"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Facer buscas na tableta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Erro: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espazo privado"</string>
</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index a804870..71aebc4 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s માટે ઍપ માહિતી"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ઍપની જોડી સાચવો"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"વિજેટ ખસેડવા ટચ કરીને થોડી વાર દબાવી રાખો."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"વિજેટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,12 +51,13 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"વ્યક્તિગત"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ઑફિસ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"વાતચીતો"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"નોંધ લેવી"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ઉપયોગી માહિતી તમારી આંગળીના ટેરવે"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ઍપને ખોલ્યા વિના માહિતી મેળવવા માટે, તમે તમારી હોમ સ્ક્રીનમાં વિજેટ ઉમેરી શકો છો"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"વિજેટના સેટિંગ બદલવા માટે ટૅપ કરો"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"સમજાઈ ગયું"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"વિજેટના સેટિંગ બદલો"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ઍપ શોધો"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
<string name="label_application" msgid="8531721983832654978">"ઍપ"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"ફોલ્ડરનું નામ બદલીને <xliff:g id="NAME">%1$s</xliff:g> કર્યું"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> આઇટમ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> કે વધુ આઇટમ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ઍપની જોડી: <xliff:g id="APP1">%1$s</xliff:g> અને <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"વૉલપેપર અને સ્ટાઇલ"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"હોમ સ્ક્રીનમાં ફેરફાર કરો"</string>
<string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
@@ -157,7 +158,7 @@
<string name="action_dismiss_notification" msgid="5909461085055959187">"છોડી દો"</string>
<string name="accessibility_close" msgid="2277148124685870734">"બંધ કરો"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"સૂચના છોડી દીધી"</string>
- <string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
+ <string name="all_apps_personal_tab" msgid="4190252696685155002">"વ્યક્તિગત ઍપ"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ઑફિસની ઍપ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ઑફિસની પ્રોફાઇલ"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT ઍડમિન તેમને જોઈ શકે છે"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"તમારો ફોન શોધો"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"તમારું ટૅબ્લેટ શોધો"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"નિષ્ફળ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ખાનગી સ્પેસ"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ce83230..a9f9ecd 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s के लिए ऐप्लिकेशन की जानकारी"</string>
<string name="save_app_pair" msgid="5647523853662686243">"साथ में इस्तेमाल किए जा सकने वाले ऐप्लिकेशन की जानकारी सेव करें"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उसे दबाकर रखें."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"होम स्क्रीन पर इधर-उधर ले जाने के लिए, विजेट को दबाकर रखें"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"विजेट को होम स्क्रीन पर इधर-उधर ले जाने के लिए, उसे दबाकर रखें"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"होम स्क्रीन पर जोड़ें"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट को होम स्क्रीन पर जोड़ा गया"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सुझाव"</string>
@@ -48,14 +49,15 @@
<string name="no_widgets_available" msgid="4337693382501046170">"विजेट और शॉर्टकट उपलब्ध नहीं हैं"</string>
<string name="no_search_results" msgid="3787956167293097509">"कोई विजेट या शॉर्टकट नहीं मिला"</string>
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"निजी विजेट"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ऑफ़िस"</string>
+ <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"वर्क विजेट"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"बातचीत"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"नोट बनाने से जुड़े विजेट"</string>
<string name="widget_education_header" msgid="4874760613775913787">"काम की जानकारी आसानी से पाएं"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ऐप्लिकेशन को खोले बिना उनकी जानकारी पाने के लिए, होम स्क्रीन पर विजेट जोड़े जा सकते हैं"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट की सेटिंग में बदलाव करने के लिए टैप करें"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"ठीक है"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेट की सेटिंग में बदलाव करें"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप सर्च करें"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप्लिकेशन खोजें"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
<string name="label_application" msgid="8531721983832654978">"ऐप्लिकेशन"</string>
@@ -98,11 +100,10 @@
<string name="folder_renamed" msgid="1794088362165669656">"फ़ोल्डर का नाम बदलकर <xliff:g id="NAME">%1$s</xliff:g> किया गया"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आइटम"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> या इससे ज़्यादा आइटम"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"साथ में इस्तेमाल किए जा सकने वाले ऐप्लिकेशन: <xliff:g id="APP1">%1$s</xliff:g> और <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वॉलपेपर और स्टाइल"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
- <string name="settings_button_text" msgid="8873672322605444408">"होम पेज की सेटिंग"</string>
+ <string name="edit_home_screen" msgid="8947858375782098427">"होम स्क्रीन में बदलाव करें"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"होम स्क्रीन की सेटिंग"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके एडमिन ने बंद किया हुआ है"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"होम स्क्रीन घुमाने की अनुमति दें"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
@@ -160,7 +161,7 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"निजी ऐप्लिकेशन"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"वर्क ऐप्लिकेशन"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"वर्क प्रोफ़ाइल"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"वर्क ऐप्लिकेशन बैज किए गए हैं और आईटी एडमिन को दिख रहे हैं"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"वर्क ऐप्लिकेशन बैज किए गए हैं. आईटी एडमिन इन्हें देख सकता है"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"ठीक है"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"वर्क ऐप्लिकेशन रोके गए"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"आपको वर्क ऐप्लिकेशन से सूचनाएं नहीं मिलेंगी"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"अपने फ़ोन में खोजें"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"अपने टैबलेट में खोजें"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"पूरा नहीं हुआ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"प्राइवेट स्पेस"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 73e366f..757f335 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podijeljeni zaslon"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Spremi par aplikacija"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da biste premjestili widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite pritisak da biste premjestili widget ili upotrijebite prilagođene radnje"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobni"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Razgovori"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pisanje bilježaka"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Da biste dobili informacije bez otvaranja aplikacija, možete dodati widgete na početni zaslon"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promijenili postavke widgeta"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mapa je preimenovana u <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par aplikacija: <xliff:g id="APP1">%1$s</xliff:g> i <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadina i stil"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Uredi početni zaslon"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog zaslona"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Pretraživanje telefona"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Pretraživanje tableta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 3380476..6c43388 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Osztott képernyő"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Alkalmazásinformáció a következőhöz: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Alkalmazáspár mentése"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tartsa lenyomva a modult az áthelyezéshez."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Modul áthelyezéséhez koppintson duplán, tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Személyes"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Munka"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Beszélgetések"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Jegyzetelés"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Hasznos információk egy koppintásnyira"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Ha az alkalmazások megnyitása nélkül szeretne információhoz jutni, felvehet modulokat a kezdőképernyőre"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ide koppintva módosíthatja a modulbeállításokat"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"A mappa új neve: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elem"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vagy több elem"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Alkalmazáspár: <xliff:g id="APP1">%1$s</xliff:g> és <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Háttérkép és stílus"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Kezdőképernyő szerkesztése"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Kezdőképernyő beállításai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"A kezdőképernyő elforgatásának engedélyezése"</string>
@@ -160,13 +161,13 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Személyes"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Munkahelyi"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Munkaprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és ezeket láthatja a rendszergazda"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Értem"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"A munkahelyi alkalmazások szüneteltetve vannak"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"A munkahelyi alkalmazásoktól nem kap értesítést."</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"A munkahelyi alkalmazások nem küldhetnek Önnek értesítéseket, nem használhatják az akkumulátorát, és nem férhetnek hozzá a tartózkodási helyéhez."</string>
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"A munkahelyi alkalmazásoktól nem kap telefonhívásokat, szöveges üzeneteket vagy értesítéseket."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára"</string>
+ <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és ezeket láthatja a rendszergazda"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Értem"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Munkahelyi alkalmazások szüneteltetése"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Folytatás"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Keresés a telefonon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Keresés a táblagépen"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Sikertelen: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privát terület"</string>
</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 5fee7a8..6eae2b6 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Տրոհել էկրանը"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Տեղեկություններ %1$s հավելվածի մասին"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Պահել հավելվածների զույգը"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Հպեք և պահեք՝ վիջեթ տեղափոխելու համար։"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Անձնական"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Աշխատանքային"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Զրույցներ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Նշումների ստեղծում"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Բոլոր կարևոր տեղեկությունները՝ ձեռքի տակ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Ավելացրեք վիջեթներ ձեր հիմնական էկրանին, որպեսզի տեղեկություններ ստանաք՝ առանց հավելվածները բացելու։"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Հպեք՝ վիջեթի կարգավորումները փոփոխելու համար"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Պանակը վերանվանվեց <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> տարր"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> կամ ավելի տարրեր"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Հավելվածների զույգ՝ <xliff:g id="APP1">%1$s</xliff:g> և <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Պաստառ և ոճ"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Փոփոխել հիմնական էկրանը"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Գլխավոր էկրանի կարգավորումներ"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Որոնում հեռախոսում"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Որոնում պլանշետում"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Չհաջողվեց կատարել գործողությունը (<xliff:g id="WHAT">%1$s</xliff:g>)"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Անձնական տարածք"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 7b33e9d..a47ec3b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Layar terpisah"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Info aplikasi untuk %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Simpan pasangan aplikasi"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh lama untuk memindahkan widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketuk dua kali & tahan untuk memindahkan widget atau gunakan tindakan khusus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Sentuh lama widget untuk memindahkannya di sekitar layar utama"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Sentuh lama widget untuk memindah-mindahkannya di layar utama"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"Tambahkan ke layar utama"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ditambahkan ke layar utama"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Saran"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pribadi"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Kerja"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Percakapan"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pembuatan catatan"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Info bermanfaat mudah dilihat"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Untuk mendapatkan info tanpa membuka aplikasi, Anda dapat menambahkan widget ke layar utama"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketuk untuk mengubah setelan widget"</string>
@@ -84,7 +86,7 @@
<string name="gadget_error_text" msgid="740356548025791839">"Tidak dapat memuat widget"</string>
<string name="gadget_setup_text" msgid="8348374825537681407">"Setelan widget"</string>
<string name="gadget_complete_setup_text" msgid="309040266978007925">"Ketuk untuk menyelesaikan penyiapan"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat di-uninstal."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Sunting Nama"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dinonaktifkan"</string>
<string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{{app_name} memiliki # notifikasi}other{{app_name} memiliki # notifikasi}}"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder diganti namanya menjadi <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item atau lebih"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Pasangan aplikasi: <xliff:g id="APP1">%1$s</xliff:g> dan <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & gaya"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit Layar Utama"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Setelan layar utama"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Telusuri di ponsel"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Telusuri di tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Ruang pribadi"</string>
</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 5e7af5f..9e9be03 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Skipta skjá"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Upplýsingar um forrit fyrir %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Vista forritapar"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Haltu fingri á græju til að færa hana."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ýttu tvisvar og haltu fingri á græju til að færa hana eða notaðu sérsniðnar aðgerðir."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persónulegt"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Vinna"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Samtöl"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Glósugerð"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Gagnlegar upplýsingar innan seilingar"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Þú getur bætt við græjum á heimaskjáinn til að fá upplýsingar án þess að opna forrit"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ýttu til að breyta græjustillingum"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Heiti möppu breytt í <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atriði"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eða fleiri atriði"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Forritapar: <xliff:g id="APP1">%1$s</xliff:g> og <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Veggfóður og stíll"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Breyta heimaskjá"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Heimastillingar"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Leita í símanum"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Leita í spjaldtölvunni"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mistókst: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Einkarými"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 3251006..407a492 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Schermo diviso"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informazioni sull\'app %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Salva coppia di app"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tocca e tieni premuto per spostare un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tocca due volte e tieni premuto per spostare un widget o per usare le azioni personalizzate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personali"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Lavoro"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversazioni"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Aggiunta di note"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informazioni utili a portata di mano"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Per ricevere informazioni senza aprire le app, puoi aggiungere dei widget alla schermata Home"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tocca per modificare le impostazioni del widget"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Nome della cartella sostituito con <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementi"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o più elementi"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Coppia di app: <xliff:g id="APP1">%1$s</xliff:g> and <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Sfondo e stile"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Modifica la schermata Home"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Impostazioni schermata Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Consenti rotazione della schermata Home"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Ricerche sul telefono"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Ricerche sul tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Operazione non riuscita: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Spazio privato"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 103e4e0..e87cfaf 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"מסך מפוצל"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"פרטים על האפליקציה %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"שמירה של צמד אפליקציות"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"להעברת ווידג\'ט למקום אחר לוחצים עליו לחיצה ארוכה."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ווידג\'טים אישיים"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"עבודה"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"שיחות"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"כתיבת הערות"</string>
<string name="widget_education_header" msgid="4874760613775913787">"קבלת מידע שימושי בהקשה"</string>
<string name="widget_education_content" msgid="1731667670753497052">"רוצה לקבל מידע בלי לפתוח אפליקציות? אפשר להוסיף ווידג\'טים למסך הבית"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"אפשר לשנות את הגדרות הווידג\'ט בהקשה"</string>
@@ -98,14 +100,13 @@
<string name="folder_renamed" msgid="1794088362165669656">"שם התיקייה שונה ל-<xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, מספר הפריטים: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> פריטים או יותר"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"טפטים"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"צמד אפליקציות: <xliff:g id="APP1">%1$s</xliff:g> ו-<xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"טפט וסגנון"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"עריכה של מסך הבית"</string>
<string name="settings_button_text" msgid="8873672322605444408">"הגדרות של מסך הבית"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"אישור לסיבוב מסך הבית"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר הטלפון מסובב"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר מסובבים את הטלפון"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"סימני ההתראות"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"מופעל"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"כבוי"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"חיפוש בטלפון"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"חיפוש בטאבלט"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"מרחב פרטי"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 7552eaf..e8a72eb 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割画面"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s のアプリ情報"</string>
<string name="save_app_pair" msgid="5647523853662686243">"アプリのペア設定を保存"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"長押ししてウィジェットを移動させます。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人用"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"仕事用"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"会話"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"メモ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ウィジェットで情報を得る"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ホーム画面にウィジェットを追加すると、アプリを開かずに情報を入手できます"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"タップしてウィジェットの設定を変更する"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"フォルダの名前を「<xliff:g id="NAME">%1$s</xliff:g>」に変更しました"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件のアイテム"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件以上のアイテム"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"アプリのペア設定: <xliff:g id="APP1">%1$s</xliff:g> と <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"壁紙とスタイル"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ホーム画面を編集"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ホームの設定"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"スマートフォンを検索"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"タブレットを探す"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"プライベート スペース"</string>
</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index e56b580..ab6e962 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ეკრანის გაყოფა"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-ის აპის ინფო"</string>
<string name="save_app_pair" msgid="5647523853662686243">"აპთა წყვილის შენახვა"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"პირადი"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"სამსახური"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"მიმოწერები"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ჩანიშვნა"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ადვილად მისაწვდომი სასარგებლო ინფორმაცია"</string>
<string name="widget_education_content" msgid="1731667670753497052">"იმისთვის, რომ ინფორმაცია აპების გაუხსნელად მიიღოთ, შეგიძლიათ, მთავარ ეკრანზე ვიჯეტები დაამატოთ"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"შეეხეთ ვიჯეტის პარამეტრების შესაცვლელად"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"საქაღალდეს შეეცვალა სახელი „<xliff:g id="NAME">%1$s</xliff:g>“-ად"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ერთეული"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ან მეტი ერთეული"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"აპთა წყვილი: <xliff:g id="APP1">%1$s</xliff:g> და <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ფონი და სტილი"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"მთავარი ეკრანის რედაქტირება"</string>
<string name="settings_button_text" msgid="8873672322605444408">"მთავარი გვერდის პარამეტრები"</string>
@@ -159,7 +161,7 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"პირადი"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"სამსახური"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"სამსახურის პროფილი"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"სამსახურის აპები ბეჯით არის მონიშნული და ხილულია IT ადმინისტრატორისთვის"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"სამსახურის აპები ბეჯით არის მონიშნული და ხილულია თქვენი IT ადმინისტრატორისთვის"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"გასაგებია"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"სამსახურის აპები დაპაუზებულია"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"თქვენ არ მიიღებთ შეტყობინებებს თქვენი სამსახურის აპებიდან"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"მოიძიეთ თქვენს ტელეფონში"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ძიება თქვენს ტაბლეტში"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ვერ მოხერხდა: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"პირადი სივრცე"</string>
</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 4da44a8..c18a43f 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлу"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s қолданбасы туралы ақпарат"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Қолданбаларды жұптау әрекетін сақтау"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетті жылжыту үшін басып тұрыңыз."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Жеке виджеттер"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Жұмыс виджеттері"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Әңгімелер"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Ескертпе жазу"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Саусақпен түртсеңіз болғаны – пайдалы ақпарат көз алдыңызда"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Қолданбаларды ашпай-ақ ақпарат алу үшін негізгі экранға тиісті виджеттерді қосыңыз."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджет параметрлерін өзгерту үшін түртіңіз."</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Қалта атауы <xliff:g id="NAME">%1$s</xliff:g> болып өзгертілді"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> элемент бар"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> не одан көп элемент бар"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Қолданбаларды жұптау: <xliff:g id="APP1">%1$s</xliff:g> және <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тұсқағаз және стиль"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Негізгі экранды өзгерту"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Негізгі экран параметрлері"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Негізгі экранды бұруға рұқсат ету"</string>
@@ -152,7 +153,7 @@
<string name="action_decrease_width" msgid="1374549771083094654">"Енін азайту"</string>
<string name="action_decrease_height" msgid="282377193880900022">"Биіктігін азайту"</string>
<string name="widget_resized" msgid="9130327887929620">"Виджет өлшемінің ені <xliff:g id="NUMBER_0">%1$s</xliff:g>, биіктігі <xliff:g id="NUMBER_1">%2$s</xliff:g> болып өзгертілді"</string>
- <string name="action_deep_shortcut" msgid="2864038805849372848">"Таңбашалар"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"Жылдам пәрмендер"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Таңбашалар мен хабарландырулар"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Бас тарту"</string>
<string name="accessibility_close" msgid="2277148124685870734">"Жабу"</string>
@@ -168,10 +169,11 @@
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"Жұмыс қолданбаларынан телефон қоңырауларын, мәтіндік хабарлар немесе хабарландырулар алмайсыз."</string>
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Жұмыс қолданбаларының танымбелгілері бар және олар әкімшіңізге көрінеді."</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Түсінікті"</string>
- <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Жұмыс қолданбаларын тоқтата тұру"</string>
+ <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Жұмыс қолданбаларын кідірту"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Қайта қосу"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Сүзгі"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Телефоннан іздеу"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Планшеттен іздеу"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Қате шықты: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Жеке бөлме"</string>
</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 6aa399b..4aa1878 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"មុខងារបំបែកអេក្រង់"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ព័ត៌មានកម្មវិធីសម្រាប់ %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"រក្សាទុកគូកម្មវិធី"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ចុចឱ្យជាប់ដើម្បីផ្លាស់ទីធាតុក្រាហ្វិក។"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទីធាតុក្រាហ្វិក ឬប្រើសកម្មភាពតាមបំណង។"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ផ្ទាល់ខ្លួន"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ការងារ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ការសន្ទនា"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ការកត់ត្រា"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ទទួលបានព័ត៌មានដែលមានប្រយោជន៍យ៉ាងងាយស្រួល"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ដើម្បីទទួលបានព័ត៌មានដោយមិនចាំបាច់បើកកម្មវិធី អ្នកអាចបញ្ចូលធាតុក្រាហ្វិកទៅក្នុងអេក្រង់ដើមរបស់អ្នក"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ចុចដើម្បីប្ដូរការកំណត់ធាតុក្រាហ្វិក"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"បានប្ដូរឈ្មោះថតជា <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g> ឬច្រើនជាងនេះ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំងរូបភាព"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"គូកម្មវិធី៖ <xliff:g id="APP1">%1$s</xliff:g> និង <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ផ្ទាំងរូបភាព និងរចនាប័ទ្ម"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"កែអេក្រង់ដើម"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ការកំណត់ទំព័រដើម"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ស្វែងរកក្នុងទូរសព្ទរបស់អ្នក"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ស្វែងរកក្នុងថេប្លេតរបស់អ្នក"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"បានបរាជ័យ៖ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"បន្ទប់ឯកជន"</string>
</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index e27483e..138e1b3 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ಗಾಗಿ ಆ್ಯಪ್ ಮಾಹಿತಿ"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ಆ್ಯಪ್ ಜೋಡಿ ಉಳಿಸಿ"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ವಿಜೆಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,17 +51,18 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ವೈಯಕ್ತಿಕ"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ಕೆಲಸ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ಸಂಭಾಷಣೆಗಳು"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ಟಿಪ್ಪಣಿ ತೆಗೆದುಕೊಳ್ಳುವುದು"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ನಿಮ್ಮ ಬೆರಳ ತುದಿಯಲ್ಲಿ ಉಪಯುಕ್ತ ಮಾಹಿತಿ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ಆ್ಯಪ್ಗಳನ್ನು ತೆರೆಯದೆಯೇ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು, ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನೀವು ವಿಜೆಟ್ಗಳನ್ನು ಸೇರಿಸಬಹುದು"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"ಅರ್ಥವಾಯಿತು"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಆ್ಯಪ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
<string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು"</string>
- <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"ನೋಟಿಫಿಕೇಶನ್ಗಳು"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ಶಾರ್ಟ್ಕಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ಶಾರ್ಟ್ಕಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="out_of_space" msgid="6455557115204099579">"ಈ ಹೋಮ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
@@ -98,20 +100,20 @@
<string name="folder_renamed" msgid="1794088362165669656">"ಫೋಲ್ಡರ್ ಅನ್ನು <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಮರುಹೆಸರಿಸಲಾಗಿದೆ"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಐಟಂಗಳು"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಅಥವಾ ಹೆಚ್ಚಿನ ಐಟಂಗಳು"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್ಪೇಪರ್ಗಳು"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ಆ್ಯಪ್ ಜೋಡಿ: <xliff:g id="APP1">%1$s</xliff:g> ಮತ್ತು <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ವಾಲ್ಪೇಪರ್ ಮತ್ತು ಶೈಲಿ"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್ ತಿರುಗಿಸಿದಾಗ"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳು"</string>
+ <string name="notification_dots_title" msgid="9062440428204120317">"ನೋಟಿಫಿಕೇಶನ್ ಡಾಟ್ಗಳು"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ಆನ್ ಆಗಿದೆ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ಆಫ್ ಆಗಿದೆ"</string>
- <string name="title_missing_notification_access" msgid="7503287056163941064">"ಅಧಿಸೂಚನೆ ಪ್ರವೇಶ ಅಗತ್ಯವಿದೆ"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"ಅಧಿಸೂಚನೆ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಅಪ್ಲಿಕೇಶನ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್ ಮಾಡಿ"</string>
+ <string name="title_missing_notification_access" msgid="7503287056163941064">"ನೋಟಿಫಿಕೇಶನ್ ಆ್ಯಕ್ಸೆಸ್ ಅಗತ್ಯವಿದೆ"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"ನೋಟಿಫಿಕೇಶನ್ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಆ್ಯಪ್ ನೋಟಿಫಿಕೇಶನ್ಗಳನ್ನು ಆನ್ ಮಾಡಿ"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"ಅಧಿಸೂಚನೆ ಡಾಟ್ಗಳನ್ನು ತೋರಿಸಿ"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"ನೋಟಿಫಿಕೇಶನ್ ಡಾಟ್ಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="developer_options_title" msgid="700788437593726194">"ಡೆವಲಪರ್ ಆಯ್ಕೆಗಳು"</string>
<string name="auto_add_shortcuts_label" msgid="4926805029653694105">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಆ್ಯಪ್ ಐಕಾನ್ಗಳನ್ನು ಸೇರಿಸಿ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ"</string>
@@ -131,7 +133,7 @@
<string name="widgets_list_closed" msgid="6141506579418771922">"ವಿಜೆಟ್ ಪಟ್ಟಿಯನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="action_add_to_workspace" msgid="215894119683164916">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಸೇರಿಸಿ"</string>
<string name="action_move_here" msgid="2170188780612570250">"ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="item_removed" msgid="851119963877842327">"ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="undo" msgid="4151576204245173321">"ರದ್ದುಮಾಡಿ"</string>
<string name="action_move" msgid="4339390619886385032">"ಐಟಂ ಸರಿಸಿ"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಹುಡುಕಿ"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಹುಡುಕಿ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ವಿಫಲವಾಗಿದೆ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ಖಾಸಗಿ ಸ್ಪೇಸ್"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index b0bcff7..7803d09 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"화면 분할"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 앱 정보"</string>
<string name="save_app_pair" msgid="5647523853662686243">"앱 페어링 저장"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"길게 터치하여 위젯을 이동하세요."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"개인 위젯"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"직장 위젯"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"대화"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"메모"</string>
<string name="widget_education_header" msgid="4874760613775913787">"빠르게 유용한 정보 확인"</string>
<string name="widget_education_content" msgid="1731667670753497052">"앱을 열지 않고 정보를 확인하려면 홈 화면에 위젯을 추가하세요."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"탭하여 위젯 설정 변경"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"폴더 이름 변경: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개 이상"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"앱 페어링: <xliff:g id="APP1">%1$s</xliff:g> 및 <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"배경화면 및 스타일"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"홈 화면 수정"</string>
<string name="settings_button_text" msgid="8873672322605444408">"홈 설정"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"홈 화면 회전 허용"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"휴대전화 속 항목 검색"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"태블릿 속 항목 검색"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"실패: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"비공개 스페이스"</string>
</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 24fca36..a9da5b8 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлүү"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s колдонмосу жөнүндө маалымат"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Эки колдонмону бир маалда пайдаланууну сактоо"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетти кое бербей басып туруп жылдырыңыз."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетти жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Жеке виджеттер"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Жумуш"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Сүйлөшүүлөр"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Эскертме жазуу"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Керектүү маалымат манжаңыздын учунда"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Бир нерсе билүү үчүн колдонмолорду улам ачып убара болбостон, башкы экранга виджеттерди кошуп коюңуз."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджеттин параметрлерин өзгөртүү үчүн таптап коюңуз"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Фолдердин аты <xliff:g id="NAME">%1$s</xliff:g> деп өзгөртүлдү"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g> же андан көбүрөөк"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Эки колдонмону бир маалда пайдалануу: <xliff:g id="APP1">%1$s</xliff:g> жана <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тушкагаз жана стиль"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Башкы экранды түзөтүү"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Башкы бет параметрлери"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Башкы экранды бурууга уруксат берүү"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Телефондо издөө"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Планшетте издөө"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Аткарылган жок: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Жеке чөйрө"</string>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 2148178..1dc9a91 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ແບ່ງໜ້າຈໍ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ຂໍ້ມູນແອັບສຳລັບ %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ບັນທຶກຈັບຄູ່ແອັບ"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ແຕະຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ ຫຼື ໃຊ້ຄຳສັ່ງກຳນົດເອງ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ສ່ວນຕົວ"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ວຽກ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ການສົນທະນາ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ການຈົດບັນທຶກ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ຂໍ້ມູນທີ່ເປັນປະໂຫຍດຢູ່ປາຍນິ້ວຂອງທ່ານ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ເພື່ອຮັບຂໍ້ມູນໂດຍບໍ່ຕ້ອງເປີດແອັບ, ທ່ານສາມາດເພີ່ມວິດເຈັດໃສ່ໂຮມສະກຣີນຂອງທ່ານໄດ້"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ແຕະເພື່ອປ່ຽນການຕັ້ງຄ່າວິດເຈັດ"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"ປ່ຽນຊື່ໂຟນເດີເປັນ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ລາຍການ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ຫຼື ລາຍການເພີ່ມເຕີມ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ຈັບຄູ່ແອັບ: <xliff:g id="APP1">%1$s</xliff:g> ແລະ <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ຮູບພື້ນຫຼັງ ແລະ ຮູບແບບ"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ແກ້ໄຂໂຮມສະກຣີນ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າໜ້າຫຼັກ"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ຊອກຫາໂທລະສັບຂອງທ່ານ"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ຊອກຫາແທັບເລັດຂອງທ່ານ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ບໍ່ສຳເລັດ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ພື້ນທີ່ສ່ວນຕົວ"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 2ea7174..1666f47 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Išskaidyto ekrano režimas"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Programos „%1$s“ informacija"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Išsaugoti programų porą"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Dukart pal. ir palaik., kad perkeltumėte valdiklį."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dukart palieskite ir palaikykite, kad perkeltumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Asmeniniai"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Darbas"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Pokalbiai"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Užrašų kūrimas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Lengvai pasiekiama naudinga informacija"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Jei norite gauti informacijos neatidarę programų, galite pridėti valdiklių pagrindiniame ekrane"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Palieskite, kad pakeistumėte valdiklio nustatymus"</string>
@@ -69,7 +71,7 @@
<string name="all_apps_search_results" msgid="5889367432531296759">"Paieškos rezultatai"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Asmeninių programų sąrašas"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Darbo programų sąrašas"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Ištrinti"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Pašalinti"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Pašalinti"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Programos inform."</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Įdiegti"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Aplankas pervardytas kaip „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g> ar daugiau"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Ekrano fonai"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Programų pora: „<xliff:g id="APP1">%1$s</xliff:g>“ ir „<xliff:g id="APP2">%2$s</xliff:g>“"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Ekrano fonas ir stilius"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Redaguoti pagrindinį ekraną"</string>
<string name="settings_button_text" msgid="8873672322605444408">"„Home“ nustatymai"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Paieška telefone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Paieška planšetiniame kompiuteryje"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nepavyko: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privati erdvė"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 3a848dd..420d3d6 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Sadalīt ekrānu"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s: informācija par lietotni"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Saglabāt lietotņu pāri"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Lai pārvietotu logrīku, pieskarieties un turiet."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Lai pārvietotu logrīku, uz tā veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personīgs"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Darba"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Sarunas"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Piezīmju pierakstīšana"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Ērta piekļuve noderīgai informācijai"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Lai iegūtu informāciju, neatverot lietotnes, varat pievienot sākuma ekrānam logrīkus"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Pieskarieties, lai mainītu logrīka iestatījumus."</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mape pārdēvēta par: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mape <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vienumi"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mape <xliff:g id="NAME">%1$s</xliff:g>, vienumu skaits mapē: vismaz <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fona tapetes"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Lietotņu pāris: <xliff:g id="APP1">%1$s</xliff:g> un <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fona tapete un stils"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Rediģēt sākuma ekrānu"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Sākumlapas iestatījumi"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Atļaut sākuma ekrāna pagriešanu"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Meklēšana tālrunī"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Meklēšana planšetdatorā"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Neizdevās: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privātā telpa"</string>
</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 6de6141..841aba7 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Поделен екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Податоци за апликација за %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Зачувај го парот апликации"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Допрете и задржете за да преместите виџет."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лични"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Работни"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Разговори"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Фаќање белешки"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Корисни информации на дофат на прстите"</string>
<string name="widget_education_content" msgid="1731667670753497052">"За да добивате информации без да ги отворате апликациите, може да додадете виџети на почетниот екран"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Допрете за да ги промените поставките за виџетот"</string>
@@ -82,7 +84,7 @@
<string name="permlab_write_settings" msgid="4820028712156303762">"да пишува поставки и кратенки на почетна страница"</string>
<string name="permdesc_write_settings" msgid="726859348127868466">"Овозможува апликацијата да ги менува поставките и кратенките на почетната страница."</string>
<string name="gadget_error_text" msgid="740356548025791839">"Не може да се вчита виџетот"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Поставки за виџет"</string>
+ <string name="gadget_setup_text" msgid="8348374825537681407">"Поставки за виџетот"</string>
<string name="gadget_complete_setup_text" msgid="309040266978007925">"Допрете за да го завршите поставувањето"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ова е системска апликација и не може да се деинсталира."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Изменете го името"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Папката е преименувана во <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставки"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или повеќе ставки"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Пар апликации: <xliff:g id="APP1">%1$s</xliff:g> и <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тапет и стил"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Изменете го почетниот екран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Поставки за почетен екран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дозволи ротирање на почетниот екран"</string>
@@ -171,7 +172,8 @@
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Паузирај ги работните апликации"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Прекини ја паузата"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
- <string name="search_pref_screen_title" msgid="3258959643336315962">"Пребарувајте на телефонот"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Пребарувајте на таблетот"</string>
+ <string name="search_pref_screen_title" msgid="3258959643336315962">"Пребарување низ телефонот"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Пребарување низ таблетот"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Приватен простор"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 59827f2..df39e74 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"സ്ക്രീൻ വിഭജന മോഡ്"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s എന്നതിന്റെ ആപ്പ് വിവരങ്ങൾ"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ആപ്പ് ജോടി സംരക്ഷിക്കുക"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"വിജറ്റ് നീക്കാൻ സ്പർശിച്ച് പിടിക്കുക."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"വിജറ്റ് നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"വ്യക്തിപരം"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ജോലി"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"സംഭാഷണങ്ങൾ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"കുറിപ്പ് രേഖപ്പെടുത്തൽ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ഉപകാരപ്രദമായ വിവരങ്ങൾ നിങ്ങളുടെ വിരൽത്തുമ്പിൽ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ആപ്പുകൾ തുറക്കാതെ വിവരങ്ങൾ ലഭിക്കാൻ, നിങ്ങൾക്ക് ഹോം സ്ക്രീനിലേക്ക് വിജറ്റുകൾ ചേർക്കാം"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"വിജറ്റ് ക്രമീകരണം മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"ഫോൾഡറിന്റെ പേര് <xliff:g id="NAME">%1$s</xliff:g> എന്നായി മാറ്റി"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ഇനങ്ങൾ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> അല്ലെങ്കിൽ അതിലധികം ഇനങ്ങൾ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ആപ്പ് ജോടി: <xliff:g id="APP1">%1$s</xliff:g>, <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"വാൾപേപ്പറും സ്റ്റൈലും"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ഹോം സ്ക്രീൻ എഡിറ്റ് ചെയ്യുക"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string>
@@ -119,7 +121,7 @@
<string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string>
<string name="abandoned_search" msgid="891119232568284442">"തിരയുക"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക."</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വയമേവ ഇൻസ്റ്റാളുചെയ്യുക."</string>
<string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ഇൻസ്റ്റാൾ ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ഡൗൺലോഡ് ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"ഇൻസ്റ്റാൾ ചെയ്യാൻ <xliff:g id="NAME">%1$s</xliff:g> കാക്കുന്നു"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"നിങ്ങളുടെ ഫോണിലുള്ളവ തിരയുക"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"നിങ്ങളുടെ ടാബ്ലെറ്റിലുള്ളവ തിരയുക"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"പരാജയപ്പെട്ടു: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"സ്വകാര്യ സ്പേസ്"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index eea9195..ad89209 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Дэлгэцийг хуваах"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-н аппын мэдээлэл"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Апп хослуулалтыг хадгалах"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетийг зөөх бол хүрээд, удаан дарна уу."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Хувийн виджетүүд"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Ажил"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Харилцан яриа"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Тэмдэглэл хөтлөх"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Хэрэгтэй мэдээллээ хурууныхаа үзүүрээр аваарай"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Аппуудыг нээлгүйгээр мэдээлэл авахын тулд та үндсэн нүүрэндээ виджетүүд нэмэх боломжтой"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Жижиг хэрэгслийн тохиргоог өөрчлөхийн тулд товшино уу"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Фолдерын нэр <xliff:g id="NAME">%1$s</xliff:g> болов"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> зүйл"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> эсвэл үүнээс олон зүйл"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Дэлгэцийн зураг"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Апп хослуулалт: <xliff:g id="APP1">%1$s</xliff:g> болон <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Дэлгэцийн зураг, загвар"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Үндсэн нүүрийг засах"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Нүүр хуудасны тохиргоо"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Үндсэн нүүрийг эргүүлэхийг зөвшөөрөх"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Утаснаасаа хайх"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Таблетнаасаа хайх"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Амжилтгүй болсон: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Хувийн орон зай"</string>
</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index b74a8f5..a14459c 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s साठी ॲपशी संबंधित माहिती"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ॲपची जोडी सेव्ह करा"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"विजेट हलवण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"होम स्क्रीनवर ते हलवण्यासाठी विजेटला स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"होम स्क्रीनवर हलवण्यासाठी विजेटला स्पर्श करून धरून ठेवा"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"होम स्क्रीनवर जोडा"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> हे विजेट तुमच्या होम स्क्रीनवर जोडले आहे"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"सूचना"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"वैयक्तिक"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ऑफिस"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"संभाषणे"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"टिपा घेणे"</string>
<string name="widget_education_header" msgid="4874760613775913787">"तुमच्यासाठी सहज उपलब्ध असलेली माहिती"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ॲप्स न उघडता माहिती मिळवण्यासाठी, तुम्ही तुमच्या होम स्क्रीनवर विजेट जोडू शकता"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट सेटिंग्ज बदलण्यासाठी टॅप करा"</string>
@@ -88,9 +90,9 @@
<string name="folder_hint_text" msgid="5174843001373488816">"नाव संपादित करा"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम केला आहे"</string>
<string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{{app_name} संबंधित # सूचना आहे}other{{app_name} संबंधित # सूचना आहेत}}"</string>
- <string name="default_scroll_format" msgid="7475544710230993317">"%2$d पैकी %1$d पृष्ठ"</string>
+ <string name="default_scroll_format" msgid="7475544710230993317">"%2$d पैकी %1$d पेज"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d पैकी %1$d मुख्य स्क्रीन"</string>
- <string name="workspace_new_page" msgid="257366611030256142">"नवीन मुख्य स्क्रीन पृष्ठ"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"नवीन होम स्क्रीन पेज"</string>
<string name="folder_opened" msgid="94695026776264709">"फोल्डर उघडले, <xliff:g id="WIDTH">%1$d</xliff:g> बाय <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"फोल्डर बंद करण्यासाठी टॅप करा"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"पुनर्नामित करणे सेव्ह करण्यासाठी टॅप करा"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"फोल्डरचे नाव बदलून <xliff:g id="NAME">%1$s</xliff:g> असे ठेवले"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आयटम"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> किंवा त्याहून अधिक आयटम"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ॲपची जोडी: <xliff:g id="APP1">%1$s</xliff:g> आणि <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वॉलपेपर आणि शैली"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"होम स्क्रीन संपादित करा"</string>
<string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्ज"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"तुमच्या फोनमध्ये शोधा"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"तुमच्या टॅबलेटमध्ये शोधा"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"खाजगी स्पेस"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 7d1a4d1..75a50b0 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Skrin pisah"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Maklumat apl untuk %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Simpan gandingan apl"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh & tahan untuk menggerakkan widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketik dua kali & tahan untuk menggerakkan widget atau menggunakan tindakan tersuai."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Peribadi"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Tempat kerja"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Perbualan"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pengambilan nota"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Maklumat berguna di hujung jari anda"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Untuk mendapatkan maklumat tanpa membuka apl, anda boleh menambahkan widget pada skrin utama anda"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketik untuk menukar tetapan widget"</string>
@@ -98,8 +100,8 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atau lebih banyak item"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Hiasan latar"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Kertas dinding & gaya"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Gandingan apl: <xliff:g id="APP1">%1$s</xliff:g> dan <xliff:g id="APP2">%2$s</xliff:g>"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hiasan latar & gaya"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Edit Skrin Utama"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tetapan skrin utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
@@ -170,7 +172,8 @@
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Jeda apl kerja"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Nyahjeda"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Tapis"</string>
- <string name="search_pref_screen_title" msgid="3258959643336315962">"Cari telefon anda"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Cari tablet anda"</string>
+ <string name="search_pref_screen_title" msgid="3258959643336315962">"Cari pada telefon"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Cari pada tablet anda"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Ruang peribadi"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 1a6b0de..a4d2417 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s အတွက် အက်ပ်အချက်အလက်"</string>
<string name="save_app_pair" msgid="5647523853662686243">"အက်ပ်တွဲချိတ်ခြင်း သိမ်းရန်"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ဝိဂျက်ကို ရွှေ့ရန် တို့ပြီး ဖိထားပါ။"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ကိုယ်ပိုင်"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"အလုပ်"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"စကားဝိုင်းများ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"မှတ်စုလိုက်ခြင်း"</string>
<string name="widget_education_header" msgid="4874760613775913787">"အသုံးဝင်သော အချက်အလက်များကို အလွယ်တကူ ရယူလိုက်ပါ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"အက်ပ်မဖွင့်ဘဲ အချက်အလက်များရယူရန် ပင်မစာမျက်နှာတွင် ဝိဂျက်များ ထည့်နိုင်သည်"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ဝိဂျက် ဆက်တင်များကို ပြောင်းရန် တို့ပါ"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"ပြောင်းလဲလိုက်သော အကန့်အမည် <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> ဖိုင်များ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> သို့မဟုတ် နောက်ထပ်ဖိုင်များ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"အက်ပ်တွဲချိတ်ခြင်း- <xliff:g id="APP1">%1$s</xliff:g> နှင့် <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"နောက်ခံနှင့် ပုံစံ"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ပင်မစာမျက်နှာ တည်းဖြတ်ရန်"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ပင်မဆက်တင်များ"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"သင့်ဖုန်းတွင် ရှာခြင်း"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"သင့်တက်ဘလက်ကို ရှာခြင်း"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"မအောင်မြင်ပါ− <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"သီးသန့်ချတ်ခန်း"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 41fb8c0..aea53fa 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Delt skjerm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinformasjon for %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Lagre apptilkoblingen"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Trykk og hold for å flytte en modul."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dobbelttrykk og hold inne for å flytte en modul eller bruke tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personlige"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Jobb"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Samtaler"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Notatskriving"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Lett tilgjengelig nyttig informasjon"</string>
<string name="widget_education_content" msgid="1731667670753497052">"For å se informasjon uten å åpne apper kan du legge til moduler på startskjermen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trykk for å endre modulinnstillinger"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mappen heter nå <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunner"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Apptilkobling: <xliff:g id="APP1">%1$s</xliff:g> og <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Bakgrunn og stil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Endre startsiden"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Startsideinnstillinger"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillat at startskjermen roterer"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Søk på telefonen"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Søk på nettbrettet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislyktes: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privat område"</string>
</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 8ce5603..b5760d7 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रिन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s का हकमा एपसम्बन्धी जानकारी"</string>
<string name="save_app_pair" msgid="5647523853662686243">"एपको पेयर सेभ गर्नुहोस्"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"कुनै विजेट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"कुनै विजेट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,12 +51,13 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"व्यक्तिगत"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"कामसम्बन्धी"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"वार्तालापहरू"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"नोट लेख्ने कार्य"</string>
<string name="widget_education_header" msgid="4874760613775913787">"उपयोगी जानकारी सजिलै प्राप्त गर्नुहोस्"</string>
<string name="widget_education_content" msgid="1731667670753497052">"एपहरू नखोलिकनै जानकारी प्राप्त गर्न तपाईं आफ्नो होम स्क्रिनमा विजेटहरू हाल्न सक्नुहुन्छ"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेटका सेटिङ बदल्न ट्याप गर्नुहोस्"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"बुझेँ"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेटका सेटिङ बदल्नुहोस्"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी एपहरू"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"एपहरू खोज्नुहोस्"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"एपहरू लोड गर्दै…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै एप भेटिएन"</string>
<string name="label_application" msgid="8531721983832654978">"एप"</string>
@@ -98,13 +100,13 @@
<string name="folder_renamed" msgid="1794088362165669656">"फोल्डर <xliff:g id="NAME">%1$s</xliff:g> मा पुनःनामाकरण गरियो।"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वस्तुहरू"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वा सोभन्दा बढी वस्तुहरू"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"एप पेयर: <xliff:g id="APP1">%1$s</xliff:g> र <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वालपेपर तथा शैली"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"होम स्क्रिन बदल्नुहोस्"</string>
<string name="settings_button_text" msgid="8873672322605444408">"होम पेजका सेटिङहरू"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"होम स्क्रिन रोटेट हुन दिइयोस्"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"फोन घुमाउँदा"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"सूचनाको प्रतीक जनाउने थोप्लाहरू"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"सक्रिय"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"निष्क्रिय"</string>
@@ -171,6 +173,7 @@
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"सुचारु गर्नुहोस्"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"आफ्नो फोन खोज्नुहोस्"</string>
- <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"आफ्नो ट्याब्लेट खोज्नुहोस्"</string>
+ <string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"आफ्नो ट्याबलेटमा खोज्नुहोस्"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"निजी स्पेस"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 2241a58..7f362ec 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Gesplitst scherm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App-info voor %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"App-paar opslaan"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tik en houd vast om een widget te verplaatsen."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en houd vast om een widget te verplaatsen of aangepaste acties te gebruiken."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persoonlijk"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Werk"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Gesprekken"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Aantekeningen maken"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Nuttige informatie binnen handbereik"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Als je informatie wilt krijgen zonder apps te openen, kun je widgets toevoegen aan je startscherm"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om de widgetinstellingen te wijzigen"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"De naam van de map is gewijzigd in <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Achtergrond"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"App-paar: <xliff:g id="APP1">%1$s</xliff:g> en <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Achtergrond en stijl"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Startscherm bewerken"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Instellingen start"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Zoeken op je telefoon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Zoeken op je tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislukt: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privéruimte"</string>
</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 5a93d91..406b176 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -27,9 +27,10 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"ନିରାପଦ ମୋଡରେ ୱିଜେଟ୍ ଅକ୍ଷମ କରାଗଲା"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ଶର୍ଟକଟ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="home_screen" msgid="5629429142036709174">"ହୋମ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ସ୍କ୍ରିନକୁ ସ୍ପ୍ଲିଟ୍ କରନ୍ତୁ"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ସ୍କ୍ରିନକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ପାଇଁ ଆପ ସୂଚନା"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ଆପ ପେୟାର ସେଭ କରନ୍ତୁ"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -39,7 +40,7 @@
<string name="add_to_home_screen" msgid="9168649446635919791">"ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>ର ୱିଜେଟ ହୋମ ସ୍କ୍ରିନରେ ଯୋଡ଼ାଗଲା"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"ପରାମର୍ଶଗୁଡ଼ିକ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#ଟି ୱିଜେଟ୍}other{#ଟି ୱିଜେଟ୍}}"</string>
+ <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ୱିଜେଟ}other{# ୱିଜେଟ}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{#ଟି ସର୍ଟକଟ୍}other{#ଟି ସର୍ଟକଟ୍}}"</string>
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"ୱିଜେଟ୍"</string>
@@ -50,12 +51,13 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ବ୍ୟକ୍ତିଗତ"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ୱାର୍କ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ନୋଟ-ଟେକିଂ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ଉପଯୋଗୀ ସୂଚନା ଆପଣଙ୍କ ପାଖରେ ସହଜରେ ଉପଲବ୍ଧ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ଆପ୍ସକୁ ନଖୋଲି ସୂଚନା ପାଇବା ପାଇଁ, ଆପଣ ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନରେ ୱିଜେଟଗୁଡ଼ିକୁ ଯୋଗ କରିପାରିବେ"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ୱିଜେଟ ସେଟିଂସ ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"ବୁଝିଗଲି"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ୱିଜେଟ ସେଟିଂସ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ୍ ଖୋଜନ୍ତୁ"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ଆପ୍ ଲୋଡ୍ ହେଉଛି..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍ ମିଳିଲା ନାହିଁ"</string>
<string name="label_application" msgid="8531721983832654978">"ଆପ୍"</string>
@@ -69,7 +71,7 @@
<string name="all_apps_search_results" msgid="5889367432531296759">"ସନ୍ଧାନ ଫଳାଫଳ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ବ୍ୟକ୍ତିଗତ ଆପ୍ ତାଲିକା"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"କାର୍ଯ୍ୟକାରୀ ଆପ୍ ତାଲିକା"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"ବାହାର କରନ୍ତୁ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ଅନଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ଆପ୍ ସୂଚନା"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
@@ -98,14 +100,13 @@
<string name="folder_renamed" msgid="1794088362165669656">"ଫୋଲ୍ଡରର ନାମ <xliff:g id="NAME">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ଆଇଟମଗୁଡ଼ିକ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> କିମ୍ବା ଅଧିକ ଆଇଟମ୍"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ୱାଲପେପର୍"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ଆପ ପେୟାର: <xliff:g id="APP1">%1$s</xliff:g> ଏବଂ <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ୱାଲପେପର ଏବଂ ଷ୍ଟାଇଲ"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"ହୋମ ସ୍କ୍ରିନକୁ ଏଡିଟ କରନ୍ତୁ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ହୋମ ସେଟିଂସ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ହୋମ ସ୍କ୍ରିନ ରୋଟେସନକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ବୁଲାଯାଇଥାଏ"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ରୋଟେଟ କରାଯାଇଥାଏ"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"ବିଜ୍ଞପ୍ତି ଡଟ୍ସ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ଚାଲୁ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ବନ୍ଦ କରନ୍ତୁ"</string>
@@ -160,7 +161,7 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ବ୍ୟକ୍ତିଗତ"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ୱାର୍କ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ୱାର୍କ ଆପ୍ସ ବ୍ୟାଜ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହେଉଛି"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ୱାର୍କ ଆପ୍ସକୁ ବେଜ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯାଉଛି"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"ବୁଝିଗଲି"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"ୱାର୍କ ଆପ୍ସ ବିରତ କରାଯାଇଛି"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"ଆପଣ ଆପଣଙ୍କ ୱାର୍କ ଆପ୍ସରୁ ବିଜ୍ଞପ୍ତି ପାଇବେ ନାହିଁ"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ଆପଣଙ୍କ ଫୋନରେ ସନ୍ଧାନ କରନ୍ତୁ"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ଆପଣଙ୍କ ଟାବଲେଟରେ ସନ୍ଧାନ କରନ୍ତୁ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ବିଫଳ ହୋଇଛି: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index ae10c8f..837eba0 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ਲਈ ਐਪ ਜਾਣਕਾਰੀ"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ਐਪ ਜੋੜਾਬੱਧ ਰੱਖਿਅਤ ਕਰੋ"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ਕਿਸੇ ਵਿਜੇਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ਨਿੱਜੀ"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ਕਾਰਜ-ਸਥਾਨ"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"ਗੱਲਾਂਬਾਤਾਂ"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"ਨੋਟ ਬਣਾਉਣਾ"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ਮਹੱਤਵਪੂਰਨ ਜਾਣਕਾਰੀ ਤੁਰੰਤ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ਐਪਾਂ ਨੂੰ ਖੋਲ੍ਹੇ ਬਿਨਾਂ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ, ਤੁਸੀਂ ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"ਫੋਲਡਰ ਨੂੰ <xliff:g id="NAME">%1$s</xliff:g> ਮੁੜ ਨਾਮ ਦਿੱਤਾ ਗਿਆ"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਆਈਟਮਾਂ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਜਾਂ ਹੋਰ ਆਈਟਮਾਂ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ਐਪ ਜੋੜਾਬੱਧ: <xliff:g id="APP1">%1$s</xliff:g> ਅਤੇ <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ਵਾਲਪੇਪਰ ਅਤੇ ਸਟਾਈਲ"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"ਹੋਮ ਸਕ੍ਰੀਨ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ਆਪਣਾ ਫ਼ੋਨ ਖੋਜੋ"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ਆਪਣਾ ਟੈਬਲੈੱਟ ਖੋਜੋ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ਇਹ ਕਾਰਵਾਈ ਅਸਫਲ ਹੋਈ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ਨਿੱਜੀ ਸਪੇਸ"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 6f73d5f..24f09f9 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -30,12 +30,13 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podziel ekran"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacje o aplikacji: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Zapisz parę aplikacji"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Naciśnij i przytrzymaj, aby przenieść widżet."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść widżet lub użyć działań niestandardowych."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"Widżet <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Kliknij i przytrzymaj widżet, aby poruszać nim po ekranie głównym"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"Aby poruszać widżetem po ekranie głównym, kliknij go i przytrzymaj"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"Dodaj do ekranu głównego"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widżet <xliff:g id="WIDGET_NAME">%1$s</xliff:g> został dodany do ekranu głównego"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"Sugestie"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobiste"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Służbowe"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Rozmowy"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Notatki"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Użyteczne informacje w zasięgu ręki"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Możesz dodać widżety do ekranu głównego, aby uzyskiwać informacje bez otwierania aplikacji"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Kliknij, aby zmienić ustawienia widżetu"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Nazwa folderu zmieniona na <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementy"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, liczba elementów: <xliff:g id="SIZE">%2$d</xliff:g> lub więcej"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Para aplikacji: <xliff:g id="APP1">%1$s</xliff:g> oraz <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta i styl"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Edytuj ekran główny"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ustawienia ekranu głównego"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Zezwalaj na obrót ekranu głównego"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Przeszukuj telefon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Przeszukuj tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Niepowodzenie: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Obszar prywatny"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index dcbbe1d..0febbd1 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ecrã dividido"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informações da app para %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Guardar par de apps"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque sem soltar para mover um widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes sem soltar para mover um widget ou utilizar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pessoais"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabalho"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Tomar notas"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informações úteis à sua disposição"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Para obter informações sem abrir apps, pode adicionar widgets ao seu ecrã principal"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para alterar as definições do widget"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Nome de pasta alterado para <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Imagens de fundo"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par de apps: <xliff:g id="APP1">%1$s</xliff:g> e <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imagem fundo/estilo"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Editar ecrã principal"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Definições de início"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Pesquise no telemóvel"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Pesquise no tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falhou: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espaço privado"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 421f2dd..ad8e0c0 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Tela dividida"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informações do app %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Salvar par de apps"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque e pressione para mover um widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes e mantenha a tela pressionada para mover um widget ou usar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,8 +51,9 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pessoais"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabalho"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Anotações"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informações úteis ao seu alcance"</string>
- <string name="widget_education_content" msgid="1731667670753497052">"Para ver informações sem precisar abrir os apps, adicione widgets à sua tela inicial"</string>
+ <string name="widget_education_content" msgid="1731667670753497052">"Para acessar informações sem precisar abrir os apps, adicione widgets à sua tela inicial"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para mudar as configurações do widget"</string>
<string name="widget_education_close_button" msgid="8676165703104836580">"Ok"</string>
<string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Mudar as configurações do widget"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Pasta renomeada para <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Planos de fundo"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par de apps: <xliff:g id="APP1">%1$s</xliff:g> e <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Plano de fundo e estilo"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Editar tela inicial"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configurações da tela inicial"</string>
@@ -106,7 +108,7 @@
<string name="allow_rotation_title" msgid="7222049633713050106">"Permitir a rotação da tela inicial"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Pontos de notificação"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativado"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativados"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desativado"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Acesso a notificações necessário"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar pontos de notificação, ative as notificações de app para <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Pesquisar no smartphone"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Pesquisar no tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falha: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Espaço particular"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 0f2c079..46f5b40 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ecran împărțit"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informații despre aplicație pentru %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Salvează perechea de aplicații"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Atinge și ține apăsat pentru a muta un widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atinge de două ori și ține apăsat pentru a muta un widget sau folosește acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personale"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Serviciu"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Conversații"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Luare de notițe"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informații utile la îndemâna ta"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Pentru a primi informații fără să deschizi aplicațiile, poți adăuga widgeturi pe ecranul de pornire"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Atinge ca să schimbi setările pentru widgeturi"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Dosar redenumit <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elemente"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> sau mai multe elemente"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Imagini de fundal"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Pereche de aplicații: <xliff:g id="APP1">%1$s</xliff:g> și <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imagine de fundal și stil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Editează ecranul de pornire"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Setări ecran de pornire"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Permite rotirea ecranului de pornire"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Caută pe telefon"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Caută pe tabletă"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Eșuare: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Spațiu privat"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 5d67c6a..79e1781 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделить экран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Сведения о приложении \"%1$s\""</string>
<string name="save_app_pair" msgid="5647523853662686243">"Сохранить настройки одновременного использования двух приложений"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Чтобы переместить виджет, нажмите на него и удерживайте"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Чтобы использовать специальные действия или перенести виджет, нажмите на него дважды и удерживайте."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Личные виджеты"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Рабочие виджеты"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Разговоры"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Создание заметок"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Вся нужная информация перед глазами"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Чтобы не открывать приложения каждый раз, когда нужна информация, добавьте виджеты на главный экран."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Нажмите, чтобы изменить настройки виджета"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Папка переименована в \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g>)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g> или больше)"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Одновременное использование двух приложений: <xliff:g id="APP1">%1$s</xliff:g> и <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Обои и стиль"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Изменить главный экран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Главный экран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Разрешить поворачивать главный экран"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Поиск на телефоне"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Поиск на планшете"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не удалось выполнить действие (<xliff:g id="WHAT">%1$s</xliff:g>)."</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Личное пространство"</string>
</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index c11b8d4..72c0491 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"බෙදුම් තිරය"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s සඳහා යෙදුම් තතු"</string>
<string name="save_app_pair" msgid="5647523853662686243">"යෙදුම් යුගල සුරකින්න"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"විජට් එකක් ගෙන යාමට ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"පුද්ගලික"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"කාර්යාලය"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"සංවාද"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"සටහන් කර ගැනීම"</string>
<string name="widget_education_header" msgid="4874760613775913787">"ප්රයෝජනවත් තොරතුරු ඔබගේ ඇඟිලි තුඩු අග"</string>
<string name="widget_education_content" msgid="1731667670753497052">"යෙදුම් විවෘත නොකර තොරතුරු ලබා ගැනීම සඳහා, ඔබට ඔබගේ මුල් තිරයට විජට් එක් කළ හැකිය"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"විජට් සැකසීම් වෙනස් කිරීමට තට්ටු කරන්න"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"<xliff:g id="NAME">%1$s</xliff:g> වෙත ෆෝල්ඩරය නැවත නම් කෙරිණි"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ෆෝල්ඩර: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>ක් හෝ වැඩි ගණනක්"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"යෙදුම් යුගල: <xliff:g id="APP1">%1$s</xliff:g> සහ <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"වෝල්පේපරය සහ මෝස්තරය"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"මුල් තිරය සංස්කරණය කරන්න"</string>
<string name="settings_button_text" msgid="8873672322605444408">"නිවසේ සැකසීම්"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"මුල් තිරය කරකැවීමට ඉඩ දෙන්න"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ඔබගේ දුරකථනය සොයන්න"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ඔබගේ ටැබ්ලටය සොයන්න"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"අසාර්ථකයි: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"පෞද්ගලික ඉඩ"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 434e416..bf01b32 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdeliť obrazovku"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informácie o aplikácii pre %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Uložiť pár aplikácií"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržaním presuňte miniaplikáciu."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a pridržaním presuňte miniaplikáciu alebo použite vlastné akcie."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobné"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Práca"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Konverzácie"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Zapisovanie poznámok"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Užitočné informácie poruke"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Ak chcete získavať informácie bez otvárania aplikácií, môžete si na plochu pridať miniaplikácie"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím zmeňte nastavenia miniaplikácie"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Priečinok bol premenovaný na <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> položky"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> alebo viac položiek"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Pár aplikácií: <xliff:g id="APP1">%1$s</xliff:g> a <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta a štýl"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Upraviť plochu"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Nastavenia plochy"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Vyhľadávanie v telefóne"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Vyhľadávanie v tablete"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Zlyhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Súkromný priestor"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index cad7f40..52d8584 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Razdeljen zaslon"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Podatki o aplikaciji za: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Shrani par aplikacij"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržite pripomoček, da ga premaknete."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvakrat se dotaknite pripomočka in ga pridržite, da ga premaknete, ali pa uporabite dejanja po meri."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osebni"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Služba"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Pogovori"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Ustvarjanje zapiskov"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Koristne informacije na dosegu prstov"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Če si želite podatke ogledati brez odpiranja aplikacij, lahko na začetni zaslon dodate pripomočke."</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dotaknite se, če želite spremeniti nastavitve pripomočka."</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mapa je preimenovana v <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, št. elementov: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ali več elementov"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Ozadja"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Par aplikacij: <xliff:g id="APP1">%1$s</xliff:g> in <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Zaslonsko ozadje in slog"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Urejanje začetnega zaslona"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Domače nastavitve"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Iskanje po telefonu"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Iskanje po tabličnem računalniku"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Ni uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Zasebni prostor"</string>
</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index ff97f00..2c072ee 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekrani i ndarë"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacioni i aplikacionit për %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Ruaj çiftin e aplikacioneve"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Prek dhe mbaj shtypur një miniaplikacion për ta zhvendosur."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Trokit dy herë dhe mbaje shtypur një miniapliikacion për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personale"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Puna"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Bisedat"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Mbajtja e shënimeve"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Informacione të dobishme në majë të gishtave të tu"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Për të marrë informacione pa i hapur aplikacionet, mund të shtosh miniaplikacione në ekranin bazë"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trokit për të ndryshuar cilësimet e miniaplikacionit"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Dosja u riemërtua në <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> artikuj"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ose më shumë artikuj"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Çifti i aplikacioneve: <xliff:g id="APP1">%1$s</xliff:g> dhe <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imazhi i sfondit dhe stili"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Modifiko ekranin bazë"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Cilësimet e ekranit bazë"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Kërko në telefonin tënd"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Kërko në tabletin tënd"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Dështoi: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Hapësira private"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 1cfda6b..ee66f12 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Подељени екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Информације о апликацији за: %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Сачувај пар апликација"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Додирните и задржите ради померања виџета."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двапут додирните и задржите да бисте померали виџет или користите прилагођене радње."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лично"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Посао"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Конверзације"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Прављење бележака"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Корисне информације надохват руке"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Да бисте пронашли информације без отварања апликација, можете да додате виџете на почетни екран"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Додирните да бисте променили подешавања виџета"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Фолдер је преименован у <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставке"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или више ставки"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Позадине"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Пар апликација: <xliff:g id="APP1">%1$s</xliff:g> и <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Позадина и стил"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Измени почетни екран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Подешавања почетног екрана"</string>
@@ -156,8 +158,8 @@
<string name="action_dismiss_notification" msgid="5909461085055959187">"Одбаци"</string>
<string name="accessibility_close" msgid="2277148124685870734">"Затвори"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Обавештење је одбачено"</string>
- <string name="all_apps_personal_tab" msgid="4190252696685155002">"Личне"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Пословне"</string>
+ <string name="all_apps_personal_tab" msgid="4190252696685155002">"Лично"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Посао"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Пословни профил"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Пословне апликације су означене значком и ИТ администратор може да их види"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"Важи"</string>
@@ -168,9 +170,10 @@
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Пословне апликације су означене значком и ИТ администратор може да их види"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Важи"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"Паузирај пословне апликације"</string>
- <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Опозови паузу"</string>
+ <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Поново активирај"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"Претражите телефон"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Претражите таблет"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Није успело: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Приватни простор"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 8c918a0..57fb8be 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Delad skärm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinformation för %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Spara appar som ska användas tillsammans"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Tryck länge för att flytta en widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryck snabbt två gånger och håll kvar för att flytta en widget eller använda anpassade åtgärder."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Privata"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Arbete"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Konversationer"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Anteckna"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Användbar information nära till hands"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Om du vill ha information utan att öppna appar kan du lägga till widgetar på startskärmen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryck för att ändra inställningarna för widgeten"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Mappen har bytt namn till <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> objekt"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller fler objekt"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunder"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Appar som ska användas tillsammans: <xliff:g id="APP1">%1$s</xliff:g> och <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Bakgrund och utseende"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Redigera startskärm"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Startinställningar"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Tillåt rotering av startskärmen"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Sök på telefonen"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Sök på surfplattan"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misslyckades: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Privat rum"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index b992037..b735318 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Gawa skrini"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Maelezo ya programu ya %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Hifadhi jozi ya programu"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Gusa na ushikilie ili usogeze wijeti."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Gusa mara mbili na ushikilie ili usogeze wijeti au utumie vitendo maalum."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Binafsi"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Kazini"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Mazungumzo"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Kuandika madokezo"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Maelezo muhimu, popote ulipo"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Ili upate maelezo bila kufungua programu, unaweza kuweka wijeti kwenye skrini yako ya kwanza"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Gusa ili ubadilishe mipangilio ya wijeti"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Folda imebadilishwa jina kuwa <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g> au zaidi"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Mandhari"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Jozi ya programu: <xliff:g id="APP1">%1$s</xliff:g> na <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Mandhari na mtindo"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Badilisha Skrini ya Kwanza"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Mipangilio ya mwanzo"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Tafuta kwenye simu yako"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Tafuta kwenye kompyuta kibao yako"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hitilafu: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Nafasi ya faragha"</string>
</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 2742361..85a7a66 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"திரைப் பிரிப்பு"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sக்கான ஆப்ஸ் தகவல்கள்"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ஆப்ஸ் ஜோடியைச் சேமி"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"விட்ஜெட்டை நகர்த்தத் தொட்டுப் பிடிக்கவும்."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"தனிப்பட்டவை"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"பணி"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"உரையாடல்கள்"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"குறிப்பெடுத்தல்"</string>
<string name="widget_education_header" msgid="4874760613775913787">"விரல்நுனியில் பயனுள்ள தகவல்களைப் பெறுங்கள்"</string>
<string name="widget_education_content" msgid="1731667670753497052">"முகப்புத் திரையில் விட்ஜெட்டுகளைச் சேர்த்து ஆப்ஸைத் திறக்காமலேயே தகவல்களைப் பெறலாம்"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"விட்ஜெட் அமைப்புகளை மாற்றத் தட்டவும்"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"ஃபோல்டர் <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ஃபோல்டர்: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ஃபைல்கள்"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ஃபோல்டர்: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> அல்லது அதற்கு அதிகமான ஃபைல்கள்"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ஆப்ஸ் ஜோடி: <xliff:g id="APP1">%1$s</xliff:g> மற்றும் <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"வால்பேப்பர் & ஸ்டைல்"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"முகப்புத் திரையில் மாற்று"</string>
<string name="settings_button_text" msgid="8873672322605444408">"முகப்பு அமைப்புகள்"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"முகப்புத் திரை சுழற்சியை அனுமதித்தல்"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"உங்கள் மொபைலில் தேடுதல்"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"உங்கள் டேப்லெட்டில் தேடுதல்"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"தோல்வி: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"தனிப்பட்ட சேமிப்பிடம்"</string>
</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index bafa955..ee4d7ca 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -27,15 +27,16 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"సురక్షిత మోడ్లో విడ్జెట్లు నిలిపివేయబడ్డాయి"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"షార్ట్కట్ అందుబాటులో లేదు"</string>
<string name="home_screen" msgid="5629429142036709174">"మొదటి ట్యాబ్"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"స్క్రీన్ను విభజించు"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"స్ప్లిట్ స్క్రీన్"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s కోసం యాప్ సమాచారం"</string>
<string name="save_app_pair" msgid="5647523853662686243">"యాప్ పెయిర్ను సేవ్ చేయండి"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"విడ్జెట్ను తరలించడానికి తాకి & నొక్కి ఉంచండి."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"విడ్జెట్ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి & హోల్డ్ చేయి."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> విడ్జెట్"</string>
- <string name="add_item_request_drag_hint" msgid="8730547755622776606">"విడ్జెట్ను మొదటి స్క్రీన్ చుట్టూ తిప్పడానికి దాన్ని తాకి, & నొక్కి ఉంచండి"</string>
+ <string name="add_item_request_drag_hint" msgid="8730547755622776606">"విడ్జెట్ను మొదటి స్క్రీన్లో తిప్పడానికి దాన్ని తాకి, & నొక్కి పట్టుకోండి"</string>
<string name="add_to_home_screen" msgid="9168649446635919791">"మొదటి స్క్రీన్కు జోడించండి"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"మొదటి స్క్రీన్కు <xliff:g id="WIDGET_NAME">%1$s</xliff:g> విడ్జెట్ జోడించబడింది"</string>
<string name="suggested_widgets_header_title" msgid="1844314680798145222">"సూచనలు"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"వ్యక్తిగత గ్యాడ్జెట్స్"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ఆఫీస్"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"సంభాషణలు"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"నోట్-టేకింగ్"</string>
<string name="widget_education_header" msgid="4874760613775913787">"మీ చేతివేళ్ల మీద ఉపయోగకరమైన సమాచారం"</string>
<string name="widget_education_content" msgid="1731667670753497052">"యాప్లను తెరవకుండా సమాచారాన్ని పొందడానికి, మీరు మీ మొదటి స్క్రీన్కు విడ్జెట్లను జోడించవచ్చు"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"విడ్జెట్ సెట్టింగ్లను మార్చడానికి ట్యాప్ చేయండి"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"ఫోల్డర్ పేరు <xliff:g id="NAME">%1$s</xliff:g>గా మార్చబడింది"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ఐటెమ్లు"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> లేదా అంతకంటే ఎక్కువ ఐటెమ్లు"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్పేపర్లు"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"యాప్ పెయిర్: <xliff:g id="APP1">%1$s</xliff:g>, <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"వాల్పేపర్ & స్టయిల్"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"మొదటి స్క్రీన్ను ఎడిట్ చేయండి"</string>
<string name="settings_button_text" msgid="8873672322605444408">"మొదటి స్క్రీన్ సెట్టింగ్లు"</string>
@@ -167,10 +169,11 @@
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"మీ వర్క్ యాప్ల నుండి మీకు ఫోన్ కాల్స్, టెక్స్ట్ మెసేజ్లు, లేదా నోటిఫికేషన్లు అందవు"</string>
<string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"వర్క్ యాప్లకు బ్యాడ్జ్ ఉంటుంది, అవి మీ IT అడ్మిన్కు కనిపిస్తాయి"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"అర్థమైంది"</string>
- <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"వర్క్ యాప్లను పాజ్ చేయి"</string>
+ <string name="work_apps_pause_btn_text" msgid="4669288269140620646">"వర్క్ యాప్లను పాజ్ చేయండి"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"పాజ్ నుండి తీసివేయండి"</string>
<string name="developer_options_filter_hint" msgid="5896817443635989056">"ఫిల్టర్ చేయి"</string>
<string name="search_pref_screen_title" msgid="3258959643336315962">"మీ ఫోన్లో సెర్చ్ చేయండి"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"మీ టాబ్లెట్లో సెర్చ్ చేయండి"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"విఫలమైంది: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"ప్రైవేట్ స్పేస్"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index c75c532..047e2b1 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -27,9 +27,10 @@
<string name="safemode_widget_error" msgid="4863470563535682004">"มีการปิดใช้งานวิดเจ็ตในเซฟโหมด"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ทางลัดไม่พร้อมใช้งาน"</string>
<string name="home_screen" msgid="5629429142036709174">"หน้าแรก"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"แบ่งหน้าจอ"</string>
+ <string name="recent_task_option_split_screen" msgid="6690461455618725183">"แยกหน้าจอ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ข้อมูลแอปสำหรับ %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"บันทึกคู่แอป"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"แตะค้างไว้เพื่อย้ายวิดเจ็ต"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"แตะสองครั้งค้างไว้เพื่อย้ายวิดเจ็ตหรือใช้การดำเนินการที่กำหนดเอง"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ส่วนตัว"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"งาน"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"การสนทนา"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"การจดบันทึก"</string>
<string name="widget_education_header" msgid="4874760613775913787">"เข้าถึงข้อมูลที่เป็นประโยชน์ได้จากปลายนิ้ว"</string>
<string name="widget_education_content" msgid="1731667670753497052">"หากต้องการรับข้อมูลโดยไม่เปิดแอป ให้เพิ่มวิดเจ็ตลงในหน้าจอหลัก"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"แตะเพื่อเปลี่ยนการตั้งค่าวิดเจ็ต"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"เปลี่ยนชื่อโฟลเดอร์เป็น <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, อย่างน้อย <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"คู่แอป: <xliff:g id="APP1">%1$s</xliff:g> และ <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"วอลเปเปอร์และรูปแบบ"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"แก้ไขหน้าจอหลัก"</string>
<string name="settings_button_text" msgid="8873672322605444408">"การตั้งค่าหน้าจอหลัก"</string>
@@ -161,7 +163,7 @@
<string name="work_profile_toggle_label" msgid="3081029915775481146">"โปรไฟล์งาน"</string>
<string name="work_profile_edu_work_apps" msgid="7895468576497746520">"แอปงานจะติดป้ายไว้และผู้ดูแลระบบไอทีจะมองเห็น"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"รับทราบ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"แอปงานปิดอยู่"</string>
+ <string name="work_apps_paused_title" msgid="3040901117349444598">"แอปงานหยุดชั่วคราว"</string>
<string name="work_apps_paused_info_body" msgid="1687828929959237477">"คุณจะไม่ได้รับการแจ้งเตือนจากแอปงาน"</string>
<string name="work_apps_paused_body" msgid="261634750995824906">"แอปงานจะส่งการแจ้งเตือน ใช้แบตเตอรี่ หรือเข้าถึงตำแหน่งของคุณไม่ได้"</string>
<string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"คุณจะไม่ได้รับสายโทรเข้า, SMS หรือการแจ้งเตือนจากแอปงาน"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"ค้นหาในโทรศัพท์"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"ค้นหาในแท็บเล็ต"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ไม่สำเร็จ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"พื้นที่ส่วนตัว"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index b91d67e..e17abc8 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Impormasyon ng app para sa %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"I-save ang pares ng app"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Pindutin nang matagal para ilipat ang widget."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"I-double tap at pindutin nang matagal para ilipat ang widget o gumamit ng mga custom na pagkilos."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabaho"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Mga Pag-uusap"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Pagtatala"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Abot-kamay na mahalagang impormasyon"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Para makakuha ng impormasyon nang hindi nagbubukas ng mga app, puwede kang magdagdag ng mga widget sa iyong home screen"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"I-tap para baguhin ang mga setting ng widget"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Pinalitan ang pangalan ng folder ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> (na) item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o higit pang item"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Mga Wallpaper"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Pares ng app: <xliff:g id="APP1">%1$s</xliff:g> at <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & istilo"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"I-edit ang Home Screen"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Mga setting ng Home"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Maghanap sa iyong telepono"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Maghanap sa iyong tablet"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hindi nagawa: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Pribadong space"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index ed0e6cf..9994adf 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Bölünmüş ekran"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s uygulama bilgileri"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Uygulama çiftini kaydedin"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget\'ı taşımak için dokunup basılı tutun."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Widget\'ı taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Kişisel"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"İş"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Görüşmeler"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Not alma"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Faydalı bilgiler parmaklarınızın ucunda"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Uygulama açmadan bilgi almak için ana ekranınıza widget ekleyebilirsiniz"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Widget ayarlarını değiştirmek için dokunun"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Klasörün adı <xliff:g id="NAME">%1$s</xliff:g> olarak değiştirildi"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> öğe"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> veya daha fazla öğe"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Duvar Kağıtları"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Uygulama çifti: <xliff:g id="APP1">%1$s</xliff:g> ve <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Duvar kağıdı ve stil"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Ana ekranı düzenleyin"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ana ekran ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Ana ekranı döndürmeye izin ver"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"telefonunuzda arama yapmak"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Tabletinizde arama yapma"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Başarısız: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Gizli alan"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 8c9524a..a638609 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Розділити екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Інформація про додаток для %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Зберегти пару додатків"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Натисніть і втримуйте, щоб перемістити віджет."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Особисті"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Робочі"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Розмови"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Створення нотаток"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Корисна інформація завжди під рукою"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Щоб отримувати інформацію, не відкриваючи додатки, ви можете додати на головний екран віджети"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Натисніть, щоб змінити налаштування віджета"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Папку перейменовано на <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g> або більше"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Фонові малюнки"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Одночасне використання двох додатків: <xliff:g id="APP1">%1$s</xliff:g> і <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Оформлення і стиль"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Редагувати головний екран"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Налаштування головного екрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Дозволити обертання головного екрана"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Пошук на телефоні"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Пошук на планшеті"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не вдалося <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Приватний простір"</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 5b10dd2..92b8b41 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"اسپلٹ اسکرین"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s کے لیے ایپ کی معلومات"</string>
<string name="save_app_pair" msgid="5647523853662686243">"ایپس کے جوڑے کو محفوظ کریں"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"ویجیٹ منتقل کرنے کے لیے ٹچ کریں اور پکڑ کر رکھیں۔"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ویجیٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ذاتی"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"دفتری ویجیٹس"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"گفتگوئیں"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"نوٹ لکھنا"</string>
<string name="widget_education_header" msgid="4874760613775913787">"مفید معلومات کو آسانی سے حاصل کریں"</string>
<string name="widget_education_content" msgid="1731667670753497052">"ایپس کو کھولے بغیر معلومات حاصل کرنے کے لیے آپ اپنی ہوم اسکرین پر ویجیٹس شامل کر سکتے ہیں"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ویجیٹ ترتیبات تبدیل کرنے کے لیے تھپتھپائیں"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"فولڈر کا نام تبدیل کر کے <xliff:g id="NAME">%1$s</xliff:g> کر دیا گیا"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> آئٹمز"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> یا مزید آئٹمز"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"ایپس کا جوڑا: <xliff:g id="APP1">%1$s</xliff:g> اور <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"وال پیپر اور طرز"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"ہوم اسکرین میں ترمیم کریں"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ہوم ترتیبات"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"اپنے فون پر تلاش کریں"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"اپنے ٹیبلیٹ پر تلاش کریں"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناکام ہو گيا: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"نجی اسپیس"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 81ad4dc..2e3bfed 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekranni ikkiga ajratish"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ilovasi axboroti"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Ilova juftini saqlash"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidjetni bosib turgan holatda suring."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Shaxsiy"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Ish"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Suhbatlar"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Qayd olish"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Barcha kerakli axborot doim yoningizda"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Kerakli ilovalarni ochmasdan turib ulardan axborot olish uchun vidjetlarni bosh ekranga chiqaring"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidjet sozlamalarini oʻzgartirish uchun bosing"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Jild nomi <xliff:g id="NAME">%1$s</xliff:g>ga o‘zgartirildi"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> fayllar"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> va undan ortiq fayllar"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Ilovani juftlash: <xliff:g id="APP1">%1$s</xliff:g> va <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fon rasmi va uslubi"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Bosh ekranni tahrirlash"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Bosh ekran sozlamalari"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Telefondan qidirish"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Planshetingizni qidiring"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Xato: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Shaxsiy xona"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index ba7b0ce..85f48a6 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Chia đôi màn hình"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Thông tin ứng dụng cho %1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Lưu cặp ứng dụng"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Chạm và giữ để di chuyển một tiện ích."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Nhấn đúp và giữ để di chuyển một tiện ích hoặc sử dụng các thao tác tùy chỉnh."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Cá nhân"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Công việc"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Cuộc trò chuyện"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Ghi chú"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Thông tin hữu ích ngay trong tầm tay bạn"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Để nhận thông tin mà không cần mở các ứng dụng, bạn có thể thêm tiện ích vào màn hình chính"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Nhấn để thay đổi chế độ cài đặt tiện ích"</string>
@@ -98,10 +100,9 @@
<string name="folder_renamed" msgid="1794088362165669656">"Đã đổi tên thư mục thành <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục trở lên"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Hình nền"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Cặp ứng dụng: <xliff:g id="APP1">%1$s</xliff:g> và <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hình nền và phong cách"</string>
- <!-- no translation found for edit_home_screen (8947858375782098427) -->
- <skip />
+ <string name="edit_home_screen" msgid="8947858375782098427">"Chỉnh sửa Màn hình chính"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Cài đặt màn hình chính"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Bị tắt bởi quản trị viên của bạn"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"Cho phép xoay màn hình chính"</string>
@@ -174,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Tìm trên điện thoại"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Tìm kiếm trong máy tính bảng của bạn"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Không thực hiện được thao tác: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Không gian riêng tư"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 415f5fa..69f6bcf 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分屏"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的应用信息"</string>
<string name="save_app_pair" msgid="5647523853662686243">"保存应用对"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"轻触并按住即可移动微件。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"个人"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"对话"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"记事"</string>
<string name="widget_education_header" msgid="4874760613775913787">"实用信息触手可及"</string>
<string name="widget_education_content" msgid="1731667670753497052">"要想不打开应用就能获取信息,您可以将相应微件添加到主屏幕"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"点按即可更改微件设置"</string>
@@ -98,8 +100,8 @@
<string name="folder_renamed" msgid="1794088362165669656">"已将文件夹重命名为“<xliff:g id="NAME">%1$s</xliff:g>”"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个项目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个或更多项目"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"壁纸和样式"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"应用对:“<xliff:g id="APP1">%1$s</xliff:g>”和“<xliff:g id="APP2">%2$s</xliff:g>”"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"壁纸与个性化"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"修改主屏幕"</string>
<string name="settings_button_text" msgid="8873672322605444408">"主屏幕设置"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"手机内搜索"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"平板电脑内搜索"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失败:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"私密空间"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 1429169..1af7766 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割螢幕"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的應用程式資料"</string>
<string name="save_app_pair" msgid="5647523853662686243">"儲存應用程式配對"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"輕觸並按住即可移動小工具。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"對話"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"做筆記"</string>
<string name="widget_education_header" msgid="4874760613775913787">"實用資訊,唾手可得"</string>
<string name="widget_education_content" msgid="1731667670753497052">"只要將小工具新增至主畫面,就可以直接查看資料,無需開啟應用程式"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕按即可變更小工具設定"</string>
@@ -98,13 +100,13 @@
<string name="folder_renamed" msgid="1794088362165669656">"資料夾已重新命名為「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個或以上的項目"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"應用程式配對:<xliff:g id="APP1">%1$s</xliff:g> 和 <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"桌布和樣式"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"編輯主畫面"</string>
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
- <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由您的管理員停用"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
<string name="allow_rotation_title" msgid="7222049633713050106">"允許旋轉主畫面"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"隨手機旋轉"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
@@ -119,12 +121,12 @@
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"尚未安裝這個應用程式"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"您尚未安裝這個圖示代表的應用程式。您可以移除這個圖示,也可以搜尋該應用程式並手動安裝。"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"你尚未安裝這個圖示代表的應用程式。你可以移除這個圖示,也可以搜尋該應用程式並手動安裝。"</string>
<string name="app_installing_title" msgid="5864044122733792085">"正在安裝「<xliff:g id="NAME">%1$s</xliff:g>」(已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下載 <xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"正在等待安裝 <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="dialog_update_title" msgid="114234265740994042">"必須更新應用程式"</string>
- <string name="dialog_update_message" msgid="4176784553982226114">"您尚未更新這個圖示代表的應用程式。您可以手動更新以重新啟用此快速鍵,或者移除圖示。"</string>
+ <string name="dialog_update_message" msgid="4176784553982226114">"你尚未更新這個圖示代表的應用程式。你可以手動更新以重新啟用此快速鍵,或者移除圖示。"</string>
<string name="dialog_update" msgid="2178028071796141234">"更新"</string>
<string name="dialog_remove" msgid="6510806469849709407">"移除"</string>
<string name="widgets_list" msgid="796804551140113767">"小工具清單"</string>
@@ -159,13 +161,13 @@
<string name="all_apps_personal_tab" msgid="4190252696685155002">"個人"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"工作"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"工作設定檔"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"工作應用程式均加有標誌。您的 IT 管理員可以看到這些應用程式"</string>
+ <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"工作應用程式均加有標誌。你的 IT 管理員可以看到這些應用程式"</string>
<string name="work_profile_edu_accept" msgid="6069788082535149071">"知道了"</string>
<string name="work_apps_paused_title" msgid="3040901117349444598">"已暫停工作應用程式"</string>
- <string name="work_apps_paused_info_body" msgid="1687828929959237477">"您不會收到工作應用程式的通知"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"工作應用程式無法向您傳送通知、使用電池電量或存取您的位置"</string>
- <string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"您不會收到工作應用程式的來電、短訊或通知"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"工作應用程式均加有標誌。您的 IT 管理員可以看到這些應用程式"</string>
+ <string name="work_apps_paused_info_body" msgid="1687828929959237477">"你不會收到工作應用程式的通知"</string>
+ <string name="work_apps_paused_body" msgid="261634750995824906">"工作應用程式無法向你傳送通知、使用電池電量或存取你的位置"</string>
+ <string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"你不會收到工作應用程式的來電、短訊或通知"</string>
+ <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"工作應用程式均加有標誌。你的 IT 管理員可以看到這些應用程式"</string>
<string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"知道了"</string>
<string name="work_apps_pause_btn_text" msgid="4669288269140620646">"暫停工作應用程式"</string>
<string name="work_apps_enable_btn_text" msgid="1736198302467317371">"取消暫停"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"搜尋手機內容"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"搜尋平板電腦內容"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"操作失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 7f949e8..47d6f14 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割畫面"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"「%1$s」的應用程式資訊"</string>
<string name="save_app_pair" msgid="5647523853662686243">"儲存應用程式配對"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"按住即可移動小工具。"</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"對話"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"做筆記"</string>
<string name="widget_education_header" msgid="4874760613775913787">"實用資訊隨手可得"</string>
<string name="widget_education_content" msgid="1731667670753497052">"只要將小工具新增到主畫面,就可以直接查看資訊,不必開啟應用程式"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕觸即可變更小工具設定"</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"已將資料夾重新命名為「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個以上的項目"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"應用程式配對:「<xliff:g id="APP1">%1$s</xliff:g>」與「<xliff:g id="APP2">%2$s</xliff:g>」"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"桌布和樣式"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"編輯主畫面"</string>
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"搜尋手機內容"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"搜尋平板電腦內容"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 6b457d1..4871d8f 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -30,6 +30,7 @@
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Hlukanisa isikrini"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Ulwazi lwe-App ye-%1$s"</string>
<string name="save_app_pair" msgid="5647523853662686243">"Londoloza i-app ebhangqiwe"</string>
+ <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="long_press_widget_to_add" msgid="3587712543577675817">"Thinta uphinde ubambe ukuze uhambise iwijethi."</string>
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Thepha kabili uphinde ubambe ukuze uhambise iwijethi noma usebenzise izindlela ezingokwezifiso."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -50,6 +51,7 @@
<string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Okwabantu siqu"</string>
<string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Umsebenzi"</string>
<string name="widget_category_conversations" msgid="8894438636213590446">"Izingxoxo"</string>
+ <string name="widget_category_note_taking" msgid="3469689394504266039">"Ukuthatha amanothi"</string>
<string name="widget_education_header" msgid="4874760613775913787">"Ulwazi oluwusizo phambi nje kwakho"</string>
<string name="widget_education_content" msgid="1731667670753497052">"Ukuze uthole ulwazi ngaphandle kokuvula ama-app, ungakwazi ukwengeza amawijethi kusikrini sakho sasekhaya"</string>
<string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Thepha ukuze ushintshe amasethingi ewijethi"</string>
@@ -59,7 +61,7 @@
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="label_application" msgid="8531721983832654978">"Uhlelo lokusebenza"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Zonke izinhlelo zokusebenza"</string>
+ <string name="all_apps_label" msgid="5015784846527570951">"Wonke ama-app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
<string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Thinta uphinde ubambe ukuze uhambise isinqamuleli."</string>
<string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Thepha kabili uphinde ubambe ukuze uhambise isinqamuleli noma usebenzise izenzo ezingokwezifiso."</string>
@@ -98,7 +100,7 @@
<string name="folder_renamed" msgid="1794088362165669656">"Ifolda iqanjwe kabusha ngo-<xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_name_format_exact" msgid="8626242716117004803">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> izinto"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> noma izinto eziningi"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Izithombe zangemuva"</string>
+ <string name="app_pair_name_format" msgid="8134106404716224054">"Ama-app abhangqwayo: I-<xliff:g id="APP1">%1$s</xliff:g> ne-<xliff:g id="APP2">%2$s</xliff:g>"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Isithombe sangemuva nesitayela"</string>
<string name="edit_home_screen" msgid="8947858375782098427">"Hlela Isikrini Sasekhaya"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Amasethingi asekhaya"</string>
@@ -173,4 +175,5 @@
<string name="search_pref_screen_title" msgid="3258959643336315962">"Sesha ifoni yakho"</string>
<string name="search_pref_screen_title_tablet" msgid="5220319680451343959">"Sesha ithebulethi yakho"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Yehlulekile: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
+ <string name="private_space_label" msgid="2359721649407947001">"Isikhala esiyimfihlo"</string>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 8f9731c..4b15a6b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -241,4 +241,9 @@
<item>@dimen/iconSize66dp</item>
<item>@dimen/iconSize72dp</item>
</integer-array>
+
+ <dimen name="minimum_icon_label_size">8sp</dimen>
+
+ <!-- Used for custom widgets -->
+ <array name="custom_widget_providers"/>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1079e00..81c2337 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -132,6 +132,8 @@
<dimen name="arrow_toast_corner_radius">2dp</dimen>
<dimen name="arrow_toast_elevation">2dp</dimen>
<dimen name="arrow_toast_arrow_width">10dp</dimen>
+ <dimen name="arrow_toast_arrow_height">10dp</dimen>
+ <dimen name="arrow_toast_text_size">14sp</dimen>
<dimen name="all_apps_divider_margin_vertical">8dp</dimen>
@@ -141,6 +143,7 @@
<dimen name="work_fab_icon_size">24dp</dimen>
<dimen name="work_fab_text_start_margin">8dp</dimen>
<dimen name="work_card_padding_horizontal">10dp</dimen>
+ <dimen name="work_fab_width">214dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
<dimen name="work_fab_margin_bottom">20dp</dimen>
@@ -244,8 +247,7 @@
<dimen name="keyboard_drag_stroke_width">4dp</dimen>
<!-- Folders -->
- <dimen name="page_indicator_dot_size">8dp</dimen>
- <dimen name="page_indicator_dot_size_v2">6dp</dimen>
+ <dimen name="page_indicator_dot_size">6dp</dimen>
<dimen name="page_indicator_size">10dp</dimen>
@@ -385,6 +387,9 @@
<dimen name="taskbar_button_margin_split">0dp</dimen>
<dimen name="taskbar_button_margin_6_5">0dp</dimen>
+ <!-- Bubble bar (placeholders to compile in Launcher3 without Quickstep) -->
+ <dimen name="bubblebar_hotseat_adjustment_threshold">0dp</dimen>
+
<!-- Size of the maximum radius for the enforced rounded rectangles. -->
<dimen name="enforced_rounded_corner_max_radius">16dp</dimen>
@@ -395,6 +400,10 @@
<dimen name="task_thumbnail_icon_size">0dp</dimen>
<dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
<dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
+ <dimen name="task_thumbnail_icon_menu_max_width">0dp</dimen>
+ <dimen name="task_thumbnail_icon_menu_drawable_size">0dp</dimen>
+ <dimen name="task_thumbnail_icon_menu_drawable_touch_size">0dp</dimen>
+ <dimen name="task_menu_vertical_padding">0dp</dimen>
<dimen name="overview_task_margin">0dp</dimen>
<dimen name="overview_actions_height">0dp</dimen>
<dimen name="overview_actions_button_spacing">0dp</dimen>
@@ -403,6 +412,9 @@
<dimen name="overview_grid_side_margin">0dp</dimen>
<dimen name="overview_grid_row_spacing">0dp</dimen>
<dimen name="overview_page_spacing">0dp</dimen>
+ <dimen name="overview_top_margin_grid_only">0dp</dimen>
+ <dimen name="overview_bottom_margin_grid_only">0dp</dimen>
+
<dimen name="split_placeholder_size">72dp</dimen>
<dimen name="split_placeholder_inset">16dp</dimen>
<dimen name="split_placeholder_icon_size">44dp</dimen>
@@ -414,7 +426,7 @@
<dimen name="split_instructions_drawable_padding">10dp</dimen>
<dimen name="split_instructions_bottom_margin_phone_landscape">24dp</dimen>
<dimen name="split_instructions_bottom_margin_phone_portrait">60dp</dimen>
-
+
<!-- Workspace grid visualization parameters -->
<dimen name="grid_visualization_rounding_radius">28dp</dimen>
<dimen name="grid_visualization_horizontal_cell_spacing">6dp</dimen>
diff --git a/res/values/id.xml b/res/values/id.xml
index 7b812de..872ae2f 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -43,4 +43,6 @@
<item type="id" name="saved_floating_widget_foreground" />
<item type="id" name="saved_floating_widget_background" />
+ <item type="id" name="dismiss_view" />
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1b46b4d..4e865d0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -44,6 +44,8 @@
<!-- App pairs -->
<string name="save_app_pair">Save app pair</string>
+ <!-- App pair default title -->
+ <string name="app_pair_default_title"><xliff:g id="app1" example="Chrome">%1$s</xliff:g> | <xliff:g id="app2" example="YouTube">%2$s</xliff:g></string>
<!-- Widgets -->
<!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
@@ -248,6 +250,10 @@
<!-- Folder name format when folder has 4 or more items shown in preview-->
<string name="folder_name_format_overflow">Folder: <xliff:g id="name" example="Games">%1$s</xliff:g>, <xliff:g id="size" example="2">%2$d</xliff:g> or more items</string>
+ <!-- App pair accessibility -->
+ <!-- App pair name -->
+ <string name="app_pair_name_format">App pair: <xliff:g id="app1" example="Chrome">%1$s</xliff:g> and <xliff:g id="app2" example="YouTube">%2$s</xliff:g></string>
+
<!-- Strings for the customization mode -->
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
<string name="styles_wallpaper_button_text">Wallpaper & style</string>
@@ -433,7 +439,7 @@
<!-- button string shown to dismiss work tab education -->
<string name="work_apps_paused_edu_accept">Got it</string>
- <!-- button string shown pause work profile -->
+ <!-- button string shown pause work profile [CHAR LIMIT=28] -->
<string name="work_apps_pause_btn_text">Pause work apps</string>
<!-- button string shown enable work profile -->
<string name="work_apps_enable_btn_text">Unpause</string>
@@ -447,4 +453,7 @@
<string name="search_pref_screen_title_tablet">Search your tablet</string>
<!-- Failed action error message: e.g. Failed: Pause -->
<string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
+
+ <!-- Private space label -->
+ <string name="private_space_label">Private space</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 4cb6414..82a227a 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -409,6 +409,12 @@
<item name="android:windowTranslucentStatus">true</item>
</style>
+ <style name="ProxyActivityStarterTheme" parent="@android:style/Theme.Translucent.NoTitleBar">
+ <item name="android:navigationBarColor">@android:color/transparent</item>
+ <item name="android:statusBarColor">@android:color/transparent</item>
+ <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+ </style>
+
<style name="FolderStyleDefault">
<item name="folderTopPadding">24dp</item>
<item name="folderCellHeight">94dp</item>
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 7131452..189db21 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -3,6 +3,7 @@
import static com.android.launcher3.CellLayout.SPRING_LOADED_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH;
+import static com.android.launcher3.LauncherPrefs.RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RESIZE_COMPLETED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RESIZE_STARTED;
import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X;
@@ -11,6 +12,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.appwidget.AppWidgetProviderInfo;
@@ -26,12 +28,14 @@
import android.widget.ImageButton;
import android.widget.ImageView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.InstanceId;
@@ -47,15 +51,16 @@
import java.util.List;
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
- private static final int SNAP_DURATION = 150;
+ private static final int SNAP_DURATION_MS = 150;
private static final float DIMMED_HANDLE_ALPHA = 0f;
private static final float RESIZE_THRESHOLD = 0.66f;
+ private static final int RESIZE_TRANSITION_DURATION_MS = 150;
- private static final String KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
- "launcher.reconfigurable_widget_education_tip_seen";
private static final Rect sTmpRect = new Rect();
private static final Rect sTmpRect2 = new Rect();
+ private static final int[] sDragLayerLoc = new int[2];
+
private static final int HANDLE_COUNT = 4;
private static final int INDEX_LEFT = 0;
private static final int INDEX_TOP = 1;
@@ -124,6 +129,12 @@
private int mTopTouchRegionAdjustment = 0;
private int mBottomTouchRegionAdjustment = 0;
+ private int[] mWidgetViewWindowPos;
+ private final Rect mWidgetViewOldRect = new Rect();
+ private final Rect mWidgetViewNewRect = new Rect();
+ private final @Nullable LauncherAppWidgetHostView.CellChildViewPreLayoutListener
+ mCellChildViewPreLayoutListener;
+
private int mXDown, mYDown;
public AppWidgetResizeFrame(Context context) {
@@ -140,6 +151,18 @@
mLauncher = Launcher.getLauncher(context);
mStateAnnouncer = DragViewStateAnnouncer.createFor(this);
+ mCellChildViewPreLayoutListener = FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()
+ ? (v, left, top, right, bottom) -> {
+ if (mWidgetViewWindowPos == null) {
+ mWidgetViewWindowPos = new int[2];
+ }
+ v.getLocationInWindow(mWidgetViewWindowPos);
+ mWidgetViewOldRect.set(v.getLeft(), v.getTop(), v.getRight(),
+ v.getBottom());
+ mWidgetViewNewRect.set(left, top, right, bottom);
+ }
+ : null;
+
mBackgroundPadding = getResources()
.getDimensionPixelSize(R.dimen.resize_frame_background_padding);
mTouchTargetWidth = 2 * mBackgroundPadding;
@@ -252,14 +275,21 @@
if (!hasSeenReconfigurableWidgetEducationTip()) {
post(() -> {
if (showReconfigurableWidgetEducationTip() != null) {
- mLauncher.getSharedPrefs().edit()
- .putBoolean(KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN,
- true).apply();
+ LauncherPrefs.get(getContext()).put(
+ RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN, true);
}
});
}
}
+ if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+ mWidgetView.setCellChildViewPreLayoutListener(mCellChildViewPreLayoutListener);
+ mWidgetViewOldRect.set(mWidgetView.getLeft(), mWidgetView.getTop(),
+ mWidgetView.getRight(),
+ mWidgetView.getBottom());
+ mWidgetViewNewRect.set(mWidgetViewOldRect);
+ }
+
CellLayoutLayoutParams lp = (CellLayoutLayoutParams) mWidgetView.getLayoutParams();
ItemInfo widgetInfo = (ItemInfo) mWidgetView.getTag();
CellPos presenterPos = mLauncher.getCellPosMapper().mapModelToPresenter(widgetInfo);
@@ -344,22 +374,6 @@
resizeWidgetIfNeeded(false);
- // When the widget resizes in multi-window mode, the translation value changes to maintain
- // a center fit. These overrides ensure the resize frame always aligns with the widget view.
- getSnappedRectRelativeToDragLayer(sTmpRect);
- if (mLeftBorderActive) {
- lp.width = sTmpRect.width() + sTmpRect.left - lp.x;
- }
- if (mTopBorderActive) {
- lp.height = sTmpRect.height() + sTmpRect.top - lp.y;
- }
- if (mRightBorderActive) {
- lp.x = sTmpRect.left;
- }
- if (mBottomBorderActive) {
- lp.y = sTmpRect.top;
- }
-
// Handle invalid resize across CellLayouts in the two panel UI.
if (mCellLayout.getParent() instanceof Workspace) {
Workspace<?> workspace = (Workspace<?>) mCellLayout.getParent();
@@ -508,9 +522,13 @@
* Returns the rect of this view when the frame is snapped around the widget, with the bounds
* relative to the {@link DragLayer}.
*/
- private void getSnappedRectRelativeToDragLayer(Rect out) {
+ private void getSnappedRectRelativeToDragLayer(@NonNull Rect out) {
float scale = mWidgetView.getScaleToFit();
- mDragLayer.getViewRectRelativeToSelf(mWidgetView, out);
+ if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+ getViewRectRelativeToDragLayer(out);
+ } else {
+ mDragLayer.getViewRectRelativeToSelf(mWidgetView, out);
+ }
int width = 2 * mBackgroundPadding + Math.round(scale * out.width());
int height = 2 * mBackgroundPadding + Math.round(scale * out.height());
@@ -523,7 +541,41 @@
out.bottom = out.top + height;
}
+ private void getViewRectRelativeToDragLayer(@NonNull Rect out) {
+ int[] afterPos = getViewPosRelativeToDragLayer();
+ out.set(afterPos[0], afterPos[1], afterPos[0] + mWidgetViewNewRect.width(),
+ afterPos[1] + mWidgetViewNewRect.height());
+ }
+
+ /** Returns the relative x and y values of the widget view after the layout transition */
+ private int[] getViewPosRelativeToDragLayer() {
+ mDragLayer.getLocationInWindow(sDragLayerLoc);
+ int x = sDragLayerLoc[0];
+ int y = sDragLayerLoc[1];
+
+ if (mWidgetViewWindowPos == null) {
+ mWidgetViewWindowPos = new int[2];
+ mWidgetView.getLocationInWindow(mWidgetViewWindowPos);
+ }
+
+ int leftOffset = mWidgetViewNewRect.left - mWidgetViewOldRect.left;
+ int topOffset = mWidgetViewNewRect.top - mWidgetViewOldRect.top;
+
+ return new int[] {mWidgetViewWindowPos[0] - x + leftOffset,
+ mWidgetViewWindowPos[1] - y + topOffset};
+ }
+
private void snapToWidget(boolean animate) {
+ // The widget is guaranteed to be attached to the cell layout at this point, thus setting
+ // the transition here
+ if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()
+ && mWidgetView.getLayoutTransition() == null) {
+ final LayoutTransition transition = new LayoutTransition();
+ transition.setDuration(RESIZE_TRANSITION_DURATION_MS);
+ transition.enableTransitionType(LayoutTransition.CHANGING);
+ mWidgetView.setLayoutTransition(transition);
+ }
+
getSnappedRectRelativeToDragLayer(sTmpRect);
int newWidth = sTmpRect.width();
int newHeight = sTmpRect.height();
@@ -585,7 +637,7 @@
updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
/* springLoadedProgress= */ 0f, /* animatorSet= */ set);
}
- set.setDuration(SNAP_DURATION);
+ set.setDuration(SNAP_DURATION_MS);
set.start();
}
@@ -665,6 +717,10 @@
@Override
protected void handleClose(boolean animate) {
+ if (FeatureFlags.ENABLE_WIDGET_TRANSITION_FOR_RESIZING.get()) {
+ mWidgetView.clearCellChildViewPreLayoutListener();
+ mWidgetView.setLayoutTransition(null);
+ }
mDragLayer.removeView(this);
}
@@ -814,8 +870,7 @@
}
private boolean hasSeenReconfigurableWidgetEducationTip() {
- return mLauncher.getSharedPrefs()
- .getBoolean(KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN, false)
+ return LauncherPrefs.get(getContext()).get(RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN)
|| Utilities.isRunningInTestHarness();
}
}
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index ec874b9..641fd83 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -1,33 +1,20 @@
package com.android.launcher3;
-import static android.os.Process.myUserHandle;
+import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS;
+import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS;
-import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.database.Cursor;
import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.model.LoaderTask;
-import com.android.launcher3.model.ModelDbController;
-import com.android.launcher3.model.WidgetsModel;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.provider.RestoreDbTask;
-import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.widget.LauncherWidgetHolder;
public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
- private static final String TAG = "AWRestoredReceiver";
+ private static final String TAG = "AppWidgetsRestoredReceiver";
@Override
public void onReceive(final Context context, Intent intent) {
@@ -41,137 +28,12 @@
final int[] oldIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
final int[] newIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (oldIds != null && newIds != null && oldIds.length == newIds.length) {
- RestoreDbTask.setRestoredAppWidgetIds(context, oldIds, newIds);
+ LauncherPrefs.get(context).putSync(
+ OLD_APP_WIDGET_IDS.to(IntArray.wrap(oldIds).toConcatString()),
+ APP_WIDGET_IDS.to(IntArray.wrap(newIds).toConcatString()));
} else {
Log.e(TAG, "Invalid host restored received");
}
}
}
-
- /**
- * Updates the app widgets whose id has changed during the restore process.
- */
- @WorkerThread
- public static void restoreAppWidgetIds(Context context, ModelDbController controller,
- int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) {
- if (WidgetsModel.GO_DISABLE_WIDGETS) {
- Log.e(TAG, "Skipping widget ID remap as widgets not supported");
- host.deleteHost();
- return;
- }
- if (!RestoreDbTask.isPending(context)) {
- // Someone has already gone through our DB once, probably LoaderTask. Skip any further
- // modifications of the DB.
- Log.e(TAG, "Skipping widget ID remap as DB already in use");
- for (int widgetId : newWidgetIds) {
- Log.d(TAG, "Deleting widgetId: " + widgetId);
- host.deleteAppWidgetId(widgetId);
- }
- return;
- }
-
- final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
-
- Log.d(TAG, "restoreAppWidgetIds: "
- + "oldWidgetIds=" + IntArray.wrap(oldWidgetIds).toConcatString()
- + ", newWidgetIds=" + IntArray.wrap(newWidgetIds).toConcatString());
-
- // TODO(b/234700507): Remove the logs after the bug is fixed
- logDatabaseWidgetInfo(controller);
-
- for (int i = 0; i < oldWidgetIds.length; i++) {
- Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
-
- final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
- final int state;
- if (LoaderTask.isValidProvider(provider)) {
- // This will ensure that we show 'Click to setup' UI if required.
- state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
- } else {
- state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
- }
-
- // b/135926478: Work profile widget restore is broken in platform. This forces us to
- // recreate the widget during loading with the correct host provider.
- long mainProfileId = UserCache.INSTANCE.get(context)
- .getSerialNumberForUser(myUserHandle());
- long controllerProfileId = controller.getSerialNumberForUser(myUserHandle());
- String oldWidgetId = Integer.toString(oldWidgetIds[i]);
- final String where = "appWidgetId=? and (restored & 1) = 1 and profileId=?";
- String profileId = Long.toString(mainProfileId);
- final String[] args = new String[] { oldWidgetId, profileId };
- Log.d(TAG, "restoreAppWidgetIds: querying profile id=" + profileId
- + " with controller profile ID=" + controllerProfileId);
- int result = new ContentWriter(context,
- new ContentWriter.CommitParams(controller, where, args))
- .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
- .put(LauncherSettings.Favorites.RESTORED, state)
- .commit();
- if (result == 0) {
- // TODO(b/234700507): Remove the logs after the bug is fixed
- Log.e(TAG, "restoreAppWidgetIds: remapping failed since the widget is not in"
- + " the database anymore");
- try (Cursor cursor = controller.getDb().query(
- Favorites.TABLE_NAME,
- new String[]{Favorites.APPWIDGET_ID},
- "appWidgetId=?", new String[]{oldWidgetId}, null, null, null)) {
- if (!cursor.moveToFirst()) {
- // The widget no long exists.
- Log.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: "
- + oldWidgetId);
- host.deleteAppWidgetId(newWidgetIds[i]);
- }
- }
- }
- }
-
- LauncherAppState app = LauncherAppState.getInstanceNoCreate();
- if (app != null) {
- app.getModel().forceReload();
- }
- }
-
- private static void logDatabaseWidgetInfo(ModelDbController controller) {
- try (Cursor cursor = controller.getDb().query(Favorites.TABLE_NAME,
- new String[]{Favorites.APPWIDGET_ID, Favorites.RESTORED, Favorites.PROFILE_ID},
- Favorites.APPWIDGET_ID + "!=" + LauncherAppWidgetInfo.NO_ID, null,
- null, null, null)) {
- IntArray widgetIdList = new IntArray();
- IntArray widgetRestoreList = new IntArray();
- IntArray widgetProfileIdList = new IntArray();
-
- if (cursor.moveToFirst()) {
- final int widgetIdColumnIndex = cursor.getColumnIndex(Favorites.APPWIDGET_ID);
- final int widgetRestoredColumnIndex = cursor.getColumnIndex(Favorites.RESTORED);
- final int widgetProfileIdIndex = cursor.getColumnIndex(Favorites.PROFILE_ID);
- while (!cursor.isAfterLast()) {
- int widgetId = cursor.getInt(widgetIdColumnIndex);
- int widgetRestoredFlag = cursor.getInt(widgetRestoredColumnIndex);
- int widgetProfileId = cursor.getInt(widgetProfileIdIndex);
-
- widgetIdList.add(widgetId);
- widgetRestoreList.add(widgetRestoredFlag);
- widgetProfileIdList.add(widgetProfileId);
- cursor.moveToNext();
- }
- }
-
- StringBuilder builder = new StringBuilder();
- builder.append("[");
- for (int i = 0; i < widgetIdList.size(); i++) {
- builder.append("[")
- .append(widgetIdList.get(i))
- .append(", ")
- .append(widgetRestoreList.get(i))
- .append(", ")
- .append(widgetProfileIdList.get(i))
- .append("]");
- }
- builder.append("]");
- Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: "
- + builder.toString());
- } catch (Exception ex) {
- Log.e(TAG, "Getting widget ids from the database failed", ex);
- }
- }
-}
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 05a6452..1049314 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -29,7 +29,6 @@
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
-import android.view.View;
import android.window.OnBackInvokedDispatcher;
import androidx.annotation.IntDef;
@@ -38,6 +37,7 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
@@ -153,6 +153,18 @@
private final ViewCache mViewCache = new ViewCache();
+ @Retention(SOURCE)
+ @IntDef({EVENT_STARTED, EVENT_RESUMED, EVENT_STOPPED, EVENT_DESTROYED})
+ public @interface ActivityEvent { }
+ public static final int EVENT_STARTED = 0;
+ public static final int EVENT_RESUMED = 1;
+ public static final int EVENT_STOPPED = 2;
+ public static final int EVENT_DESTROYED = 3;
+
+ // Callback array that corresponds to events defined in @ActivityEvent
+ private final RunnableList[] mEventCallbacks =
+ {new RunnableList(), new RunnableList(), new RunnableList(), new RunnableList()};
+
@Override
public ViewCache getViewCache() {
return mViewCache;
@@ -205,12 +217,14 @@
protected void onStart() {
addActivityFlags(ACTIVITY_STATE_STARTED);
super.onStart();
+ mEventCallbacks[EVENT_STARTED].executeAllAndClear();
}
@Override
protected void onResume() {
setResumed();
super.onResume();
+ mEventCallbacks[EVENT_RESUMED].executeAllAndClear();
}
@Override
@@ -232,6 +246,8 @@
removeActivityFlags(ACTIVITY_STATE_STARTED | ACTIVITY_STATE_USER_ACTIVE);
mForceInvisible = 0;
super.onStop();
+ mEventCallbacks[EVENT_STOPPED].executeAllAndClear();
+
// Reset the overridden sysui flags used for the task-swipe launch animation, this is a
// catch all for if we do not get resumed (and therefore not paused below)
@@ -239,6 +255,12 @@
}
@Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mEventCallbacks[EVENT_DESTROYED].executeAllAndClear();
+ }
+
+ @Override
protected void onPause() {
setPaused();
super.onPause();
@@ -258,7 +280,6 @@
} else {
removeActivityFlags(ACTIVITY_STATE_WINDOW_FOCUSED);
}
-
}
protected void registerBackDispatcher() {
@@ -364,9 +385,15 @@
}
/**
- * Attempts to clear accessibility focus on {@param view}.
+ * Adds a callback for the provided activity event
*/
- public void tryClearAccessibilityFocus(View view) {
+ public void addEventCallback(@ActivityEvent int event, Runnable callback) {
+ mEventCallbacks[event].add(callback);
+ }
+
+ /** Removes a previously added callback */
+ public void removeEventCallback(@ActivityEvent int event, Runnable callback) {
+ mEventCallbacks[event].remove(callback);
}
public interface MultiWindowModeChangedListener {
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 808cf70..f8ed4df 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -38,7 +38,6 @@
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.OnColorHintListener;
-import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.WallpaperColorHints;
@@ -51,8 +50,6 @@
public abstract class BaseDraggingActivity extends BaseActivity
implements OnColorHintListener, DisplayInfoChangeListener {
- private static final String TAG = "BaseDraggingActivity";
-
// When starting an action mode, setting this tag will cause the action mode to be cancelled
// automatically when user interacts with the launcher.
public static final Object AUTO_CANCEL_ACTION_MODE = new Object();
@@ -60,8 +57,6 @@
private ActionMode mCurrentActionMode;
protected boolean mIsSafeModeEnabled;
- private Runnable mOnStartCallback;
- private final RunnableList mOnResumeCallbacks = new RunnableList();
private int mThemeRes = R.style.AppTheme;
@Override
@@ -81,16 +76,6 @@
}
}
- @Override
- protected void onResume() {
- super.onResume();
- mOnResumeCallbacks.executeAllAndClear();
- }
-
- public void addOnResumeCallback(Runnable callback) {
- mOnResumeCallbacks.add(callback);
- }
-
@MainThread
@Override
public void onColorHintsChanged(int colorHints) {
@@ -146,42 +131,24 @@
@NonNull
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
ActivityOptionsWrapper wrapper = super.getActivityLaunchOptions(v, item);
- addOnResumeCallback(wrapper.onEndCallback::executeAllAndDestroy);
+ addEventCallback(EVENT_RESUMED, wrapper.onEndCallback::executeAllAndDestroy);
return wrapper;
}
@Override
public ActivityOptionsWrapper makeDefaultActivityOptions(int splashScreenStyle) {
ActivityOptionsWrapper wrapper = super.makeDefaultActivityOptions(splashScreenStyle);
- addOnResumeCallback(wrapper.onEndCallback::executeAllAndDestroy);
+ addEventCallback(EVENT_RESUMED, wrapper.onEndCallback::executeAllAndDestroy);
return wrapper;
}
@Override
- protected void onStart() {
- super.onStart();
-
- if (mOnStartCallback != null) {
- mOnStartCallback.run();
- mOnStartCallback = null;
- }
- }
-
- @Override
protected void onDestroy() {
super.onDestroy();
DisplayController.INSTANCE.get(this).removeChangeListener(this);
WallpaperColorHints.get(this).unregisterOnColorsChangedListener(this);
}
- public void runOnceOnStart(Runnable action) {
- mOnStartCallback = action;
- }
-
- public void clearRunOnceOnStartCallback() {
- mOnStartCallback = null;
- }
-
protected void onDeviceProfileInitiated() {
if (mDeviceProfile.isVerticalBarLayout()) {
mDeviceProfile.updateIsSeascape(this);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index a539148..e2e528c 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,8 +16,9 @@
package com.android.launcher3;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
+import static android.text.Layout.Alignment.ALIGN_NORMAL;
+
+import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
import static com.android.launcher3.icons.BitmapInfo.FLAG_NO_BADGE;
@@ -39,6 +40,7 @@
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.icu.text.MessageFormat;
+import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
@@ -148,6 +150,7 @@
private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this);
private final ActivityContext mActivity;
private FastBitmapDrawable mIcon;
+ private DeviceProfile mDeviceProfile;
private boolean mCenterVertically;
protected int mDisplay;
@@ -199,42 +202,42 @@
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mActivity = ActivityContext.lookupContext(context);
- FastBitmapDrawable.setFlagHoverEnabled(ENABLE_CURSOR_HOVER_STATES.get());
+ FastBitmapDrawable.setFlagHoverEnabled(enableCursorHoverStates());
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
mIsRtl = (getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL);
- DeviceProfile grid = mActivity.getDeviceProfile();
+ mDeviceProfile = mActivity.getDeviceProfile();
mDisplay = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
final int defaultIconSize;
if (mDisplay == DISPLAY_WORKSPACE) {
- setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
- setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
- defaultIconSize = grid.iconSizePx;
- setCenterVertically(grid.iconCenterVertically);
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.iconTextSizePx);
+ setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
+ defaultIconSize = mDeviceProfile.iconSizePx;
+ setCenterVertically(mDeviceProfile.iconCenterVertically);
} else if (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW
|| mDisplay == DISPLAY_SEARCH_RESULT_APP_ROW) {
- setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
- setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
- defaultIconSize = grid.allAppsIconSizePx;
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx);
+ setCompoundDrawablePadding(mDeviceProfile.allAppsIconDrawablePaddingPx);
+ defaultIconSize = mDeviceProfile.allAppsIconSizePx;
} else if (mDisplay == DISPLAY_FOLDER) {
- setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx);
- setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx);
- defaultIconSize = grid.folderChildIconSizePx;
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.folderChildTextSizePx);
+ setCompoundDrawablePadding(mDeviceProfile.folderChildDrawablePaddingPx);
+ defaultIconSize = mDeviceProfile.folderChildIconSizePx;
} else if (mDisplay == DISPLAY_SEARCH_RESULT) {
- setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx);
defaultIconSize = getResources().getDimensionPixelSize(R.dimen.search_row_icon_size);
} else if (mDisplay == DISPLAY_SEARCH_RESULT_SMALL) {
defaultIconSize = getResources().getDimensionPixelSize(
R.dimen.search_row_small_icon_size);
} else if (mDisplay == DISPLAY_TASKBAR) {
- defaultIconSize = grid.iconSizePx;
+ defaultIconSize = mDeviceProfile.iconSizePx;
} else {
// widget_selection or shortcut_popup
- defaultIconSize = grid.iconSizePx;
+ defaultIconSize = mDeviceProfile.iconSizePx;
}
mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false);
@@ -274,8 +277,7 @@
mDotParams.scale = 0f;
mForceHideDot = false;
setBackground(null);
- if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()
- || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) {
+ if (FeatureFlags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) {
setMaxLines(1);
}
@@ -292,7 +294,7 @@
}
}
- private void animateDotScale(float... dotScales) {
+ public void animateDotScale(float... dotScales) {
cancelDotScaleAnim();
mDotScaleAnim = ObjectAnimator.ofFloat(this, DOT_SCALE_PROPERTY, dotScales);
mDotScaleAnim.addListener(new AnimatorListenerAdapter() {
@@ -385,10 +387,12 @@
setTag(itemInfo);
}
+ @VisibleForTesting
@UiThread
- protected void applyIconAndLabel(ItemInfoWithIcon info) {
+ public void applyIconAndLabel(ItemInfoWithIcon info) {
int flags = shouldUseTheme() ? FLAG_THEMED : 0;
- if (mHideBadge) {
+ // Remove badge on icons smaller than 48dp.
+ if (mHideBadge || mDisplay == DISPLAY_SEARCH_RESULT_SMALL) {
flags |= FLAG_NO_BADGE;
}
FastBitmapDrawable iconDrawable = info.newIcon(getContext(), flags);
@@ -399,15 +403,16 @@
}
protected boolean shouldUseTheme() {
- return mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
- || mDisplay == DISPLAY_TASKBAR;
+ return (mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
+ || mDisplay == DISPLAY_TASKBAR) && Themes.isThemedIconEnabled(getContext());
}
/**
* Only if actual text can be displayed in two line, the {@code true} value will be effective.
*/
protected boolean shouldUseTwoLine() {
- return (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() && mDisplay == DISPLAY_ALL_APPS)
+ return ((FeatureFlags.enableTwolineAllapps())
+ && (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW))
|| (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()
&& mDisplay == DISPLAY_SEARCH_RESULT);
}
@@ -641,7 +646,7 @@
return mForceHideDot;
}
- private boolean hasDot() {
+ public boolean hasDot() {
return mDotInfo != null;
}
@@ -690,21 +695,28 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int height = MeasureSpec.getSize(heightMeasureSpec);
if (mCenterVertically) {
Paint.FontMetrics fm = getPaint().getFontMetrics();
int cellHeightPx = mIconSize + getCompoundDrawablePadding() +
(int) Math.ceil(fm.bottom - fm.top);
- int height = MeasureSpec.getSize(heightMeasureSpec);
setPadding(getPaddingLeft(), (height - cellHeightPx) / 2, getPaddingRight(),
getPaddingBottom());
}
// Only apply two line for all_apps and device search only if necessary.
if (shouldUseTwoLine() && (mLastOriginalText != null)) {
+ int allowedVerticalSpace = height - getPaddingTop() - getPaddingBottom()
+ - mDeviceProfile.allAppsIconSizePx
+ - mDeviceProfile.allAppsIconDrawablePaddingPx;
CharSequence modifiedString = modifyTitleToSupportMultiLine(
MeasureSpec.getSize(widthMeasureSpec) - getCompoundPaddingLeft()
- getCompoundPaddingRight(),
+ allowedVerticalSpace,
mLastOriginalText,
- getPaint(), mBreakPointsIntArray);
+ getPaint(),
+ mBreakPointsIntArray,
+ getLineSpacingMultiplier(),
+ getLineSpacingExtra());
if (!TextUtils.equals(modifiedString, mLastModifiedText)) {
mLastModifiedText = modifiedString;
setText(modifiedString);
@@ -784,7 +796,8 @@
* many words as it can until the limit is reached. Once the limit is reached, we decide to
* either return the original title or continue on a new line. How to get the new string is by
* iterating through the list of break points and determining if the strings between the break
- * points can fit within the line it is in.
+ * points can fit within the line it is in. We will show the modified string if there is enough
+ * horizontal and vertical space, otherwise this method will just return the original string.
* Example assuming each character takes up one spot:
* title = "Battery Stats", breakpoint = [6], stringPtr = 0, limitedWidth = 7
* We get the current word -> from sublist(0, breakpoint[i]+1) so sublist (0,7) -> Battery,
@@ -793,8 +806,9 @@
* if the first char is a SPACE, we trim to append "Stats". So resulting string would be
* "Battery\nStats"
*/
- public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, CharSequence title,
- TextPaint paint, IntArray breakPoints) {
+ public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, int limitedHeight,
+ CharSequence title, TextPaint paint, IntArray breakPoints, float spacingMultiplier,
+ float spacingExtra) {
// current title is less than the width allowed so we can just skip
if (title == null || paint.measureText(title, 0, title.length()) <= limitedWidth) {
return title;
@@ -802,6 +816,8 @@
float currentWordWidth, runningWidth = 0;
CharSequence currentWord;
StringBuilder newString = new StringBuilder();
+ // TODO: Remove when ENABLE_ICON_LABEL_AUTO_SCALING feature flag is being cleaned up.
+ paint.setLetterSpacing(MIN_LETTER_SPACING);
int stringPtr = 0;
for (int i = 0; i < breakPoints.size()+1; i++) {
if (i < breakPoints.size()) {
@@ -815,11 +831,7 @@
if (runningWidth <= limitedWidth) {
newString.append(currentWord);
} else {
- // there is no more space
- if (i == 0) {
- // if the first words exceeds width, just return as the first line will ellipse
- return title;
- } else {
+ if (i != 0) {
// If putting word onto a new line, make sure there is no space or new line
// character in the beginning of the current word and just put in the rest of
// the characters.
@@ -833,8 +845,14 @@
: EMPTY;
}
newString.append(NEW_LINE).append(lastCharacters);
- return newString.toString();
+ StaticLayout staticLayout = new StaticLayout(newString, paint, limitedWidth,
+ ALIGN_NORMAL, spacingMultiplier, spacingExtra, false);
+ if (staticLayout.getHeight() < limitedHeight) {
+ return newString.toString();
+ }
}
+ // if the first words exceeds width, just return as the first line will ellipse
+ return title;
}
if (i >= breakPoints.size()) {
// no need to look forward into the string if we've already finished processing
@@ -864,7 +882,7 @@
if ((info.runtimeStatusFlags & FLAG_INCREMENTAL_DOWNLOAD_ACTIVE) != 0
|| info.hasPromiseIconUi()
|| (info.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0
- || (ENABLE_DOWNLOAD_APP_UX_V2.get() && icon != null)) {
+ || (icon != null)) {
updateProgressBarUi(info.getProgressLevel() == 100 ? icon : null);
}
}
@@ -901,9 +919,7 @@
if (mIcon instanceof PreloadIconDrawable) {
preloadIconDrawable = (PreloadIconDrawable) mIcon;
preloadIconDrawable.setLevel(progressLevel);
- preloadIconDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
- ? info.getProgressLevel() == 0
- : !info.isAppStartable());
+ preloadIconDrawable.setIsDisabled(info.getProgressLevel() == 0);
} else {
preloadIconDrawable = makePreloadIcon();
setIcon(preloadIconDrawable);
@@ -928,9 +944,7 @@
final PreloadIconDrawable preloadDrawable = newPendingIcon(getContext(), info);
preloadDrawable.setLevel(progressLevel);
- preloadDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
- ? info.getProgressLevel() == 0
- : !info.isAppStartable());
+ preloadDrawable.setIsDisabled(info.getProgressLevel() == 0);
return preloadDrawable;
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 08e5def..94e5970 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -57,6 +57,7 @@
import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.IntDef;
+import androidx.annotation.Px;
import androidx.core.graphics.ColorUtils;
import androidx.core.view.ViewCompat;
@@ -117,6 +118,8 @@
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
@Thunk final int[] mTmpPoint = new int[2];
@Thunk final int[] mTempLocation = new int[2];
+
+ @Thunk final Rect mTempOnDrawCellToRect = new Rect();
final PointF mTmpPointF = new PointF();
protected GridOccupancy mOccupied;
@@ -173,6 +176,8 @@
private final TimeInterpolator mEaseOutInterpolator;
protected final ShortcutAndWidgetContainer mShortcutsAndWidgets;
+ @Px
+ protected int mSpaceBetweenCellLayoutsPx = 0;
@Retention(RetentionPolicy.SOURCE)
@IntDef({WORKSPACE, HOTSEAT, FOLDER})
@@ -600,23 +605,18 @@
DeviceProfile dp = mActivity.getDeviceProfile();
int paddingX = Math.min((mCellWidth - dp.iconSizePx) / 2, dp.gridVisualizationPaddingX);
int paddingY = Math.min((mCellHeight - dp.iconSizePx) / 2, dp.gridVisualizationPaddingY);
- mVisualizeGridRect.set(paddingX, paddingY,
- mCellWidth - paddingX,
- mCellHeight - paddingY);
mVisualizeGridPaint.setStrokeWidth(8);
- int paintAlpha = (int) (120 * mGridAlpha);
- mVisualizeGridPaint.setColor(ColorUtils.setAlphaComponent(mGridColor, paintAlpha));
+ // This is used for debugging purposes only
if (mVisualizeCells) {
+ int paintAlpha = (int) (120 * mGridAlpha);
+ mVisualizeGridPaint.setColor(ColorUtils.setAlphaComponent(mGridColor, paintAlpha));
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
- int transX = i * mCellWidth + (i * mBorderSpace.x) + getPaddingLeft()
- + paddingX;
- int transY = j * mCellHeight + (j * mBorderSpace.y) + getPaddingTop()
- + paddingY;
-
- mVisualizeGridRect.offsetTo(transX, transY);
+ cellToRect(i, j, 1, 1, mTempOnDrawCellToRect);
+ mVisualizeGridRect.set(mTempOnDrawCellToRect);
+ mVisualizeGridRect.inset(paddingX, paddingY);
mVisualizeGridPaint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(mVisualizeGridRect, mGridVisualizationRoundingRadius,
mGridVisualizationRoundingRadius, mVisualizeGridPaint);
@@ -628,35 +628,30 @@
for (int i = 0; i < mDragOutlines.length; i++) {
final float alpha = mDragOutlineAlphas[i];
if (alpha <= 0) continue;
+ CellLayoutLayoutParams params = mDragOutlines[i];
+ cellToRect(params.getCellX(), params.getCellY(), params.cellHSpan, params.cellVSpan,
+ mTempOnDrawCellToRect);
+ mVisualizeGridRect.set(mTempOnDrawCellToRect);
+ mVisualizeGridRect.inset(paddingX, paddingY);
mVisualizeGridPaint.setAlpha(255);
- int x = mDragOutlines[i].getCellX();
- int y = mDragOutlines[i].getCellY();
- int spanX = mDragOutlines[i].cellHSpan;
- int spanY = mDragOutlines[i].cellVSpan;
-
- // TODO b/194414754 clean this up, reconcile with cellToRect
- mVisualizeGridRect.set(paddingX, paddingY,
- mCellWidth * spanX + mBorderSpace.x * (spanX - 1) - paddingX,
- mCellHeight * spanY + mBorderSpace.y * (spanY - 1) - paddingY);
-
- int transX = x * mCellWidth + (x * mBorderSpace.x)
- + getPaddingLeft() + paddingX;
- int transY = y * mCellHeight + (y * mBorderSpace.y)
- + getPaddingTop() + paddingY;
-
- mVisualizeGridRect.offsetTo(transX, transY);
-
mVisualizeGridPaint.setStyle(Paint.Style.STROKE);
mVisualizeGridPaint.setColor(Color.argb((int) (alpha),
Color.red(mGridColor), Color.green(mGridColor), Color.blue(mGridColor)));
+ canvas.save();
+ canvas.translate(getMarginForGivenCellParams(params), 0);
canvas.drawRoundRect(mVisualizeGridRect, mGridVisualizationRoundingRadius,
mGridVisualizationRoundingRadius, mVisualizeGridPaint);
+ canvas.restore();
}
}
}
+ protected float getMarginForGivenCellParams(CellLayoutLayoutParams params) {
+ return 0;
+ }
+
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
@@ -2859,4 +2854,8 @@
public boolean isRegionVacant(int x, int y, int spanX, int spanY) {
return mOccupied.isRegionVacant(x, y, spanX, spanY);
}
+
+ public void setSpaceBetweenCellLayoutsPx(@Px int spaceBetweenCellLayoutsPx) {
+ mSpaceBetweenCellLayoutsPx = spaceBetweenCellLayoutsPx;
+ }
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 936229a..73cd8c4 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -24,6 +24,7 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.config.FeatureFlags.ENABLE_MULTI_DISPLAY_PARTIAL_DEPTH;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
@@ -62,6 +63,7 @@
import com.android.launcher3.responsive.HotseatSpecs;
import com.android.launcher3.responsive.WorkspaceSpecs;
import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.CellContentDimensions;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IconSizeSteps;
@@ -205,9 +207,11 @@
public int hotseatBarEndOffset;
public int hotseatQsbSpace;
public int springLoadedHotseatBarTopMarginPx;
- // Start is the side next to the nav bar, end is the side next to the workspace
- public final int hotseatBarSidePaddingStartPx;
- public final int hotseatBarSidePaddingEndPx;
+ // These 2 values are only used for isVerticalBar
+ // Padding between edge of screen and hotseat
+ public final int mHotseatBarEdgePaddingPx;
+ // Space between hotseat and workspace (not used in responsive)
+ public final int mHotseatBarWorkspaceSpacePx;
public int hotseatQsbWidth; // only used when isQsbInline
public final int hotseatQsbHeight;
public final int hotseatQsbVisualHeight;
@@ -217,6 +221,9 @@
private final int mMinHotseatQsbWidthPx;
private final int mMaxHotseatIconSpacePx;
public final int inlineNavButtonsEndSpacingPx;
+ // Space required for the bubble bar between the hotseat and the edge of the screen. If there's
+ // not enough space, the hotseat will adjust itself for the bubble bar.
+ private final int mBubbleBarSpaceThresholdPx;
// Bottom sheets
public int bottomSheetTopPadding;
@@ -228,14 +235,13 @@
// All apps
public Point allAppsBorderSpacePx;
public int allAppsShiftRange;
- public int allAppsTopPadding;
+ public Rect allAppsPadding = new Rect();
public int allAppsOpenDuration;
public int allAppsCloseDuration;
public int allAppsCellHeightPx;
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
- public int allAppsLeftRightPadding;
public int allAppsLeftRightMargin;
public final int numShownAllAppsColumns;
public float allAppsIconTextSizePx;
@@ -245,6 +251,7 @@
public int overviewTaskIconSizePx;
public int overviewTaskIconDrawableSizePx;
public int overviewTaskIconDrawableSizeGridPx;
+ public int overviewTaskIconAppChipMenuDrawableSizePx;
public int overviewTaskThumbnailTopMarginPx;
public final int overviewActionsHeight;
public final int overviewActionsTopMarginPx;
@@ -292,10 +299,10 @@
public final int stashedTaskbarHeight;
public final int taskbarBottomMargin;
public final int taskbarIconSize;
+ private final int mTransientTaskbarClaimedSpace;
// If true, used to layout taskbar in 3 button navigation mode.
public final boolean startAlignTaskbar;
public final boolean isTransientTaskbar;
-
// DragController
public int flingToDeleteThresholdVelocity;
@@ -304,7 +311,8 @@
SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode,
boolean transposeLayoutWithOrientation, boolean isMultiDisplay, boolean isGestureMode,
@NonNull final ViewScaleProvider viewScaleProvider,
- @NonNull final Consumer<DeviceProfile> dimensionOverrideProvider) {
+ @NonNull final Consumer<DeviceProfile> dimensionOverrideProvider,
+ boolean isTransientTaskbar) {
this.inv = inv;
this.isLandscape = windowBounds.isLandscape();
@@ -362,19 +370,24 @@
}
}
- isTransientTaskbar = DisplayController.isTransientTaskbar(context);
+ this.isTransientTaskbar = isTransientTaskbar;
+ int transientTaskbarIconSize = pxFromDp(inv.transientTaskbarIconSize[mTypeIndex], mMetrics);
+ int transientTaskbarBottomMargin =
+ res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin);
+ int transientTaskbarHeight =
+ Math.round((transientTaskbarIconSize * ICON_VISIBLE_AREA_FACTOR)
+ + (2 * res.getDimensionPixelSize(R.dimen.transient_taskbar_padding)));
+ mTransientTaskbarClaimedSpace = transientTaskbarHeight + 2 * transientTaskbarBottomMargin;
+
if (!isTaskbarPresent) {
taskbarIconSize = taskbarHeight = stashedTaskbarHeight = taskbarBottomMargin = 0;
startAlignTaskbar = false;
} else if (isTransientTaskbar) {
- float invTransientIconSizeDp = inv.transientTaskbarIconSize[mTypeIndex];
- taskbarIconSize = pxFromDp(invTransientIconSizeDp, mMetrics);
- taskbarHeight = Math.round((taskbarIconSize * ICON_VISIBLE_AREA_FACTOR)
- + (2 * res.getDimensionPixelSize(R.dimen.transient_taskbar_padding)));
+ taskbarIconSize = transientTaskbarIconSize;
+ taskbarHeight = transientTaskbarHeight;
stashedTaskbarHeight =
res.getDimensionPixelSize(R.dimen.transient_taskbar_stashed_height);
- taskbarBottomMargin =
- res.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin);
+ taskbarBottomMargin = transientTaskbarBottomMargin;
startAlignTaskbar = false;
} else {
taskbarIconSize = pxFromDp(ResourcesCompat.getFloat(res, R.dimen.taskbar_icon_size),
@@ -502,46 +515,56 @@
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
- int hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
+ int hotseatBarBottomSpace;
int minQsbMargin = res.getDimensionPixelSize(R.dimen.min_qsb_margin);
if (mIsResponsiveGrid) {
HotseatSpecs hotseatSpecs =
HotseatSpecs.create(new ResourceHelper(context,
isTwoPanels ? inv.hotseatSpecsTwoPanelId : inv.hotseatSpecsId));
- mResponsiveHotseatSpec = hotseatSpecs.getCalculatedHeightSpec(heightPx);
+ mResponsiveHotseatSpec =
+ isVerticalBarLayout() ? hotseatSpecs.getCalculatedWidthSpec(widthPx)
+ : hotseatSpecs.getCalculatedHeightSpec(heightPx);
hotseatQsbSpace = mResponsiveHotseatSpec.getHotseatQsbSpace();
+ hotseatBarBottomSpace =
+ isVerticalBarLayout() ? 0 : mResponsiveHotseatSpec.getEdgePadding();
+ mHotseatBarEdgePaddingPx =
+ isVerticalBarLayout() ? mResponsiveHotseatSpec.getEdgePadding() : 0;
+ mHotseatBarWorkspaceSpacePx = 0;
} else {
hotseatQsbSpace = pxFromDp(inv.hotseatQsbSpace[mTypeIndex], mMetrics);
+ hotseatBarBottomSpace = pxFromDp(inv.hotseatBarBottomSpace[mTypeIndex], mMetrics);
+ mHotseatBarEdgePaddingPx =
+ isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
+ mHotseatBarWorkspaceSpacePx =
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
}
- // Have a little space between the inset and the QSB
- if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) {
- int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace);
+ if (!isVerticalBarLayout()) {
+ // Have a little space between the inset and the QSB
+ if (mInsets.bottom + minQsbMargin > hotseatBarBottomSpace) {
+ int availableSpace = hotseatQsbSpace - (mInsets.bottom - hotseatBarBottomSpace);
- // Only change the spaces if there is space
- if (availableSpace > 0) {
- // Make sure there is enough space between hotseat/QSB and QSB/navBar
- if (availableSpace < minQsbMargin * 2) {
- minQsbMargin = availableSpace / 2;
- hotseatQsbSpace = minQsbMargin;
- } else {
- hotseatQsbSpace -= minQsbMargin;
+ // Only change the spaces if there is space
+ if (availableSpace > 0) {
+ // Make sure there is enough space between hotseat/QSB and QSB/navBar
+ if (availableSpace < minQsbMargin * 2) {
+ minQsbMargin = availableSpace / 2;
+ hotseatQsbSpace = minQsbMargin;
+ } else {
+ hotseatQsbSpace -= minQsbMargin;
+ }
}
- }
- hotseatBarBottomSpacePx = mInsets.bottom + minQsbMargin;
+ hotseatBarBottomSpacePx = mInsets.bottom + minQsbMargin;
- } else {
- hotseatBarBottomSpacePx = hotseatBarBottomSpace;
+ } else {
+ hotseatBarBottomSpacePx = hotseatBarBottomSpace;
+ }
}
springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
R.dimen.spring_loaded_hotseat_top_margin);
- hotseatBarSidePaddingEndPx =
- res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
- // Add a bit of space between nav bar and hotseat in vertical bar layout.
- hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
- updateHotseatSizes(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
+ updateHotseatSizes(pxFromDp(inv.iconSize[mTypeIndex], mMetrics));
if (areNavButtonsInline && !isPhone) {
inlineNavButtonsEndSpacingPx =
res.getDimensionPixelSize(inv.inlineNavButtonsEndSpacing);
@@ -558,6 +581,9 @@
hotseatBarEndOffset = 0;
}
+ mBubbleBarSpaceThresholdPx =
+ res.getDimensionPixelSize(R.dimen.bubblebar_hotseat_adjustment_threshold);
+
// Needs to be calculated after hotseatBarSizePx is correct,
// for the available height to be correct
if (mIsResponsiveGrid) {
@@ -567,10 +593,9 @@
int availableResponsiveWidth =
availableWidthPx - (isVerticalBarLayout() ? hotseatBarSizePx : 0);
int numColumns = getPanelCount() * inv.numColumns;
- // don't use availableHeightPx because it subtracts bottom padding,
- // but the workspace go behind it
- int availableResponsiveHeight =
- heightPx - mInsets.top - (isVerticalBarLayout() ? 0 : hotseatBarSizePx);
+ // don't use availableHeightPx because it subtracts mInsets.bottom
+ int availableResponsiveHeight = heightPx - mInsets.top
+ - (isVerticalBarLayout() ? 0 : hotseatBarSizePx);
mResponsiveWidthSpec = workspaceSpecs.getCalculatedWidthSpec(numColumns,
availableResponsiveWidth);
mResponsiveHeightSpec = workspaceSpecs.getCalculatedHeightSpec(inv.numRows,
@@ -597,12 +622,17 @@
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
- overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
+ overviewTaskIconSizePx = enableOverviewIconMenu() ? res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_drawable_touch_size) : res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_size);
overviewTaskIconDrawableSizePx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size);
overviewTaskIconDrawableSizeGridPx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size_grid);
- overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx;
+ overviewTaskIconAppChipMenuDrawableSizePx = res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_drawable_size);
+ overviewTaskThumbnailTopMarginPx =
+ enableOverviewIconMenu() ? 0 : overviewTaskIconSizePx + overviewTaskMarginPx;
// Don't add margin with floating search bar to minimize risk of overlapping.
overviewActionsTopMarginPx = FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() ? 0
: res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
@@ -647,10 +677,10 @@
res.getDimensionPixelOffset(R.dimen.bottom_sheet_handle_area_height);
int contentHeight = heightPx - collapseHandleHeight - hotseatQsbHeight;
int targetContentHeight = (int) (allAppsCellHeightPx * ALL_APPS_TABLET_MAX_ROWS);
- allAppsTopPadding = Math.max(mInsets.top, contentHeight - targetContentHeight);
- allAppsShiftRange = heightPx - allAppsTopPadding;
+ allAppsPadding.top = Math.max(mInsets.top, contentHeight - targetContentHeight);
+ allAppsShiftRange = heightPx - allAppsPadding.top;
} else {
- allAppsTopPadding = 0;
+ allAppsPadding.top = 0;
allAppsShiftRange =
res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
}
@@ -681,6 +711,17 @@
}
/**
+ * Return maximum of all apps row count displayed on screen. Note that 1) Partially displayed
+ * row is counted as 1 row, and 2) we don't exclude the space of floating search bar. This
+ * method is used for calculating number of {@link BubbleTextView} we need to pre-inflate. Thus
+ * reasonable over estimation is fine.
+ */
+ public int getMaxAllAppsRowCount() {
+ return (int) (Math.ceil((availableHeightPx - allAppsPadding.top)
+ / (float) allAppsCellHeightPx));
+ }
+
+ /**
* QSB width is always calculated because when in 3 button nav the width doesn't follow the
* width of the hotseat.
*/
@@ -743,8 +784,8 @@
hotseatCellHeightPx = getIconSizeWithOverlap(hotseatIconSizePx);
if (isVerticalBarLayout()) {
- hotseatBarSizePx = hotseatIconSizePx + hotseatBarSidePaddingStartPx
- + hotseatBarSidePaddingEndPx;
+ hotseatBarSizePx = hotseatIconSizePx + mHotseatBarEdgePaddingPx
+ + mHotseatBarWorkspaceSpacePx;
} else if (isQsbInline) {
hotseatBarSizePx = Math.max(hotseatIconSizePx, hotseatQsbVisualHeight)
+ hotseatBarBottomSpacePx;
@@ -889,14 +930,11 @@
- iconTextHeight;
if (mIsResponsiveGrid) {
- // Hide text only if doesn't fit inside the cell for responsive grid
- if (workspaceCellPaddingY < 0) {
- iconTextSizePx = 0;
- iconDrawablePaddingPx = 0;
- int iconSizeWithOverlap = getIconSizeWithOverlap(iconSizePx);
- cellYPaddingPx = Math.max(0, getCellSize().y - iconSizeWithOverlap) / 2;
- autoResizeAllAppsCells();
- }
+ iconTextSizePx = 0;
+ iconDrawablePaddingPx = 0;
+ int iconSizeWithOverlap = getIconSizeWithOverlap(iconSizePx);
+ cellYPaddingPx = Math.max(0, getCellSize().y - iconSizeWithOverlap) / 2;
+ autoResizeAllAppsCells();
return;
}
@@ -1013,20 +1051,22 @@
}
iconDrawablePaddingPx = getNormalizedIconDrawablePadding();
- int iconTextHeight = Utilities.calculateTextHeight(iconTextSizePx);
- int cellContentHeight = iconSizePx + iconDrawablePaddingPx + iconTextHeight;
- while (iconSizePx > mIconSizeSteps.minimumIconSize()
- && cellContentHeight > cellHeightPx) {
- iconDrawablePaddingPx -= cellContentHeight - cellHeightPx;
- if (iconDrawablePaddingPx < 0) {
- // get a smaller icon size
- iconSizePx = mIconSizeSteps.getNextLowerIconSize(iconSizePx);
- iconDrawablePaddingPx = getNormalizedIconDrawablePadding();
+ CellContentDimensions cellContentDimensions = new CellContentDimensions(iconSizePx,
+ iconDrawablePaddingPx,
+ iconTextSizePx);
+ if (isVerticalLayout) {
+ if (cellHeightPx < iconSizePx) {
+ cellContentDimensions.setIconSizePx(
+ mIconSizeSteps.getIconSmallerThan(cellHeightPx));
}
- // calculate new cellContentHeight
- cellContentHeight = iconSizePx + iconDrawablePaddingPx + iconTextHeight;
+ } else {
+ cellContentDimensions.resizeToFitCellHeight(cellHeightPx, mIconSizeSteps);
}
+ iconSizePx = cellContentDimensions.getIconSizePx();
+ iconDrawablePaddingPx = cellContentDimensions.getIconDrawablePaddingPx();
+ iconTextSizePx = cellContentDimensions.getIconTextSizePx();
+ int cellContentHeight = cellContentDimensions.getCellContentHeight();
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
} else if (mIsScalableGrid) {
@@ -1115,6 +1155,10 @@
if (isVerticalBarLayout()) {
hideWorkspaceLabelsIfNotEnoughSpace();
}
+ if (FeatureFlags.enableTwolineAllapps()) {
+ // Add extra textHeight to the existing allAppsCellHeight.
+ allAppsCellHeightPx += Utilities.calculateTextHeight(allAppsIconTextSizePx);
+ }
updateHotseatSizes(iconSizePx);
@@ -1214,7 +1258,8 @@
allAppsCellHeightPx = mAllAppsResponsiveHeightSpec.getCellSizePx()
+ mAllAppsResponsiveHeightSpec.getGutterPx();
allAppsCellWidthPx = mAllAppsResponsiveWidthSpec.getCellSizePx();
- allAppsLeftRightPadding = mAllAppsResponsiveWidthSpec.getStartPaddingPx();
+ allAppsPadding.left = mAllAppsResponsiveWidthSpec.getStartPaddingPx();
+ allAppsPadding.right = mAllAppsResponsiveWidthSpec.getEndPaddingPx();
}
/**
@@ -1233,10 +1278,10 @@
if (isTablet) {
int usedWidth = (allAppsCellWidthPx * numShownAllAppsColumns)
+ (allAppsBorderSpacePx.x * (numShownAllAppsColumns - 1))
- + allAppsLeftRightPadding * 2;
+ + allAppsPadding.left + allAppsPadding.right;
allAppsLeftRightMargin = Math.max(1, (availableWidthPx - usedWidth) / 2);
} else {
- allAppsLeftRightPadding =
+ allAppsPadding.left = allAppsPadding.right =
Math.max(0, desiredWorkspaceHorizontalMarginPx + cellLayoutHorizontalPadding
- (allAppsBorderSpacePx.x / 2));
}
@@ -1247,7 +1292,7 @@
inv.allAppsStyle != INVALID_RESOURCE_HANDLE ? inv.allAppsStyle
: R.style.AllAppsStyleDefault, R.styleable.AllAppsStyle);
- allAppsLeftRightPadding = allAppsStyle.getDimensionPixelSize(
+ allAppsPadding.left = allAppsPadding.right = allAppsStyle.getDimensionPixelSize(
R.styleable.AllAppsStyle_horizontalPadding, 0);
allAppsStyle.recycle();
}
@@ -1496,7 +1541,8 @@
if (isVerticalBarLayout()) {
if (mIsResponsiveGrid) {
padding.top = mResponsiveHeightSpec.getStartPaddingPx();
- padding.bottom = mResponsiveHeightSpec.getEndPaddingPx();
+ padding.bottom = Math.max(0,
+ mResponsiveHeightSpec.getEndPaddingPx() - mInsets.bottom);
if (isSeascape()) {
padding.left = hotseatBarSizePx + mResponsiveWidthSpec.getEndPaddingPx();
padding.right = mResponsiveWidthSpec.getStartPaddingPx();
@@ -1509,9 +1555,9 @@
padding.bottom = edgeMarginPx;
if (isSeascape()) {
padding.left = hotseatBarSizePx;
- padding.right = hotseatBarSidePaddingStartPx;
+ padding.right = mHotseatBarEdgePaddingPx;
} else {
- padding.left = hotseatBarSidePaddingStartPx;
+ padding.left = mHotseatBarEdgePaddingPx;
padding.right = hotseatBarSizePx;
}
}
@@ -1545,6 +1591,32 @@
paddings.bottom -= insets.bottom;
}
+
+ /**
+ * Returns the new border space that should be used between hotseat icons after adjusting it to
+ * the bubble bar.
+ *
+ * <p>If there's no adjustment needed, this method returns {@code 0}.
+ */
+ public float getHotseatAdjustedBorderSpaceForBubbleBar(Context context) {
+ // only need to adjust when QSB is on top of the hotseat.
+ if (isQsbInline) {
+ return 0;
+ }
+
+ // no need to adjust if there's enough space for the bubble bar to the right of the hotseat.
+ if (getHotseatLayoutPadding(context).right > mBubbleBarSpaceThresholdPx) {
+ return 0;
+ }
+
+ // The adjustment is shrinking the hotseat's width by 1 icon on either side.
+ int iconsWidth =
+ iconSizePx * numShownHotseatIcons + hotseatBorderSpace * (numShownHotseatIcons - 1);
+ int newWidth = iconsWidth - 2 * iconSizePx;
+ // Evenly space the icons within the boundaries of the new width.
+ return (float) (newWidth - iconSizePx * numShownHotseatIcons) / (numShownHotseatIcons - 1);
+ }
+
/**
* Returns the padding for hotseat view
*/
@@ -1565,11 +1637,11 @@
+ diffOverlapFactor), 0);
if (isSeascape()) {
- hotseatBarPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop,
- hotseatBarSidePaddingEndPx, paddingBottom);
+ hotseatBarPadding.set(mInsets.left + mHotseatBarEdgePaddingPx, paddingTop,
+ mHotseatBarWorkspaceSpacePx, paddingBottom);
} else {
- hotseatBarPadding.set(hotseatBarSidePaddingEndPx, paddingTop,
- mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom);
+ hotseatBarPadding.set(mHotseatBarWorkspaceSpacePx, paddingTop,
+ mInsets.right + mHotseatBarEdgePaddingPx, paddingBottom);
}
} else if (isTaskbarPresent) {
// Center the QSB vertically with hotseat
@@ -1627,13 +1699,14 @@
}
/** The margin between the edge of all apps and the edge of the first icon. */
- public int getAllAppsIconStartMargin() {
+ public int getAllAppsIconStartMargin(Context context) {
int allAppsSpacing;
if (isVerticalBarLayout()) {
// On phones, the landscape layout uses a different setup.
allAppsSpacing = workspacePadding.left + workspacePadding.right;
} else {
- allAppsSpacing = allAppsLeftRightPadding * 2 + allAppsLeftRightMargin * 2;
+ allAppsSpacing =
+ allAppsPadding.left + allAppsPadding.right + allAppsLeftRightMargin * 2;
}
int cellWidth = DeviceProfile.calculateCellWidth(
@@ -1642,7 +1715,9 @@
numShownAllAppsColumns);
int iconVisibleSize = Math.round(ICON_VISIBLE_AREA_FACTOR * allAppsIconSizePx);
int iconAlignmentMargin = (cellWidth - iconVisibleSize) / 2;
- return allAppsLeftRightPadding + iconAlignmentMargin;
+
+ return (Utilities.isRtl(context.getResources()) ? allAppsPadding.right
+ : allAppsPadding.left) + iconAlignmentMargin;
}
private int getAdditionalQsbSpace() {
@@ -1693,19 +1768,14 @@
return getHotseatBarBottomPadding() + launcherIconBottomSpace - taskbarIconBottomSpace;
}
- /**
- * Returns the number of pixels required below OverviewActions excluding insets.
- */
+ /** Returns the number of pixels required below OverviewActions. */
public int getOverviewActionsClaimedSpaceBelow() {
- if (isTaskbarPresent) {
- return taskbarHeight + taskbarBottomMargin * 2;
- }
- return mInsets.bottom;
+ return isTaskbarPresent ? mTransientTaskbarClaimedSpace : mInsets.bottom;
}
/** Gets the space that the overview actions will take, including bottom margin. */
public int getOverviewActionsClaimedSpace() {
- int overviewActionsSpace = isTablet && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
+ int overviewActionsSpace = isTablet && Flags.enableGridOnlyOverview()
? 0
: (overviewActionsTopMarginPx + overviewActionsHeight);
return overviewActionsSpace + getOverviewActionsClaimedSpaceBelow();
@@ -1896,7 +1966,6 @@
writer.println(prefix + "\tbottomSheetDepth: " + bottomSheetDepth);
writer.println(prefix + pxToDpStr("allAppsShiftRange", allAppsShiftRange));
- writer.println(prefix + pxToDpStr("allAppsTopPadding", allAppsTopPadding));
writer.println(prefix + "\tallAppsOpenDuration: " + allAppsOpenDuration);
writer.println(prefix + "\tallAppsCloseDuration: " + allAppsCloseDuration);
writer.println(prefix + pxToDpStr("allAppsIconSizePx", allAppsIconSizePx));
@@ -1908,17 +1977,19 @@
writer.println(prefix + pxToDpStr("allAppsBorderSpacePxX", allAppsBorderSpacePx.x));
writer.println(prefix + pxToDpStr("allAppsBorderSpacePxY", allAppsBorderSpacePx.y));
writer.println(prefix + "\tnumShownAllAppsColumns: " + numShownAllAppsColumns);
- writer.println(prefix + pxToDpStr("allAppsLeftRightPadding", allAppsLeftRightPadding));
+ writer.println(prefix + pxToDpStr("allAppsPadding.top", allAppsPadding.top));
+ writer.println(prefix + pxToDpStr("allAppsPadding.left", allAppsPadding.left));
+ writer.println(prefix + pxToDpStr("allAppsPadding.right", allAppsPadding.right));
writer.println(prefix + pxToDpStr("allAppsLeftRightMargin", allAppsLeftRightMargin));
writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
writer.println(prefix + pxToDpStr("hotseatBarBottomSpacePx", hotseatBarBottomSpacePx));
- writer.println(prefix + pxToDpStr("hotseatBarSidePaddingStartPx",
- hotseatBarSidePaddingStartPx));
- writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
- hotseatBarSidePaddingEndPx));
+ writer.println(prefix + pxToDpStr("mHotseatBarEdgePaddingPx",
+ mHotseatBarEdgePaddingPx));
+ writer.println(prefix + pxToDpStr("mHotseatBarWorkspaceSpacePx",
+ mHotseatBarWorkspaceSpacePx));
writer.println(prefix + pxToDpStr("hotseatBarEndOffset", hotseatBarEndOffset));
writer.println(prefix + pxToDpStr("hotseatQsbSpace", hotseatQsbSpace));
writer.println(prefix + pxToDpStr("hotseatQsbHeight", hotseatQsbHeight));
@@ -1967,6 +2038,8 @@
overviewTaskIconDrawableSizePx));
writer.println(prefix + pxToDpStr("overviewTaskIconDrawableSizeGridPx",
overviewTaskIconDrawableSizeGridPx));
+ writer.println(prefix + pxToDpStr("overviewTaskIconAppChipMenuDrawableSizePx",
+ overviewTaskIconAppChipMenuDrawableSizePx));
writer.println(prefix + pxToDpStr("overviewTaskThumbnailTopMarginPx",
overviewTaskThumbnailTopMarginPx));
writer.println(prefix + pxToDpStr("overviewActionsTopMarginPx",
@@ -2074,10 +2147,13 @@
private Consumer<DeviceProfile> mOverrideProvider;
+ private boolean mIsTransientTaskbar;
+
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
mInv = inv;
mInfo = info;
+ mIsTransientTaskbar = info.isTransientTaskbar();
}
public Builder setMultiWindowMode(boolean isMultiWindowMode) {
@@ -2128,6 +2204,15 @@
return this;
}
+ /**
+ * Set the isTransientTaskbar for the builder
+ * @return This Builder
+ */
+ public Builder setIsTransientTaskbar(boolean isTransientTaskbar) {
+ mIsTransientTaskbar = isTransientTaskbar;
+ return this;
+ }
+
public DeviceProfile build() {
if (mWindowBounds == null) {
throw new IllegalArgumentException("Window bounds not set");
@@ -2149,8 +2234,7 @@
}
return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache,
mIsMultiWindowMode, mTransposeLayoutWithOrientation, mIsMultiDisplay,
- mIsGestureMode, mViewScaleProvider, mOverrideProvider);
+ mIsGestureMode, mViewScaleProvider, mOverrideProvider, mIsTransientTaskbar);
}
}
-
}
diff --git a/src/com/android/launcher3/DropTargetHandler.kt b/src/com/android/launcher3/DropTargetHandler.kt
index 6560e16..78f2862 100644
--- a/src/com/android/launcher3/DropTargetHandler.kt
+++ b/src/com/android/launcher3/DropTargetHandler.kt
@@ -2,6 +2,7 @@
import android.content.ComponentName
import android.view.View
+import com.android.launcher3.BaseDraggingActivity.EVENT_RESUMED
import com.android.launcher3.DropTarget.DragObject
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
import com.android.launcher3.dragndrop.DragLayer
@@ -32,7 +33,7 @@
if (d.dragSource is SecondaryDropTarget.DeferredOnComplete) {
target?.let {
deferred.mPackageName = it.packageName
- mLauncher.addOnResumeCallback { deferred.onLauncherResume() }
+ mLauncher.addEventCallback(EVENT_RESUMED) { deferred.onLauncherResume() }
}
?: deferred.sendFailure()
}
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 8ec5c18..8ff030e 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -101,8 +101,14 @@
}
public void hideKeyboard() {
+ hideKeyboard(/* clearFocus= */ true);
+ }
+
+ public void hideKeyboard(boolean clearFocus) {
ActivityContext.lookupContext(getContext()).hideKeyboard();
- clearFocus();
+ if (clearFocus) {
+ clearFocus();
+ }
}
protected void onKeyboardShown() {
diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java
index c16b319..67ed55d 100644
--- a/src/com/android/launcher3/FastScrollRecyclerView.java
+++ b/src/com/android/launcher3/FastScrollRecyclerView.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import static com.android.launcher3.testing.shared.TestProtocol.SCROLL_FINISHED_MESSAGE;
+
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -170,7 +172,8 @@
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE) {
- AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ SCROLL_FINISHED_MESSAGE);
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 03afba1..3b12b86 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,6 +16,12 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
+import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_BUBBLE_ADJUSTMENT_ANIM;
+
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -27,6 +33,10 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.launcher3.util.HorizontalInsettableView;
+import com.android.launcher3.util.MultiTranslateDelegate;
+import com.android.launcher3.views.ActivityContext;
+
/**
* View class that represents the bottom row of the home screen.
*/
@@ -34,6 +44,7 @@
// Ratio of empty space, qsb should take up to appear visually centered.
public static final float QSB_CENTER_FACTOR = .325f;
+ private static final int BUBBLE_BAR_ADJUSTMENT_ANIMATION_DURATION_MS = 250;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
@@ -72,9 +83,36 @@
}
public void resetLayout(boolean hasVerticalHotseat) {
+ ActivityContext activityContext = ActivityContext.lookupContext(getContext());
+ boolean bubbleBarEnabled = activityContext.isBubbleBarEnabled();
+ boolean hasBubbles = activityContext.hasBubbles();
removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
DeviceProfile dp = mActivity.getDeviceProfile();
+
+ if (bubbleBarEnabled) {
+ float adjustedBorderSpace = dp.getHotseatAdjustedBorderSpaceForBubbleBar(getContext());
+ if (hasBubbles && Float.compare(adjustedBorderSpace, 0f) != 0) {
+ getShortcutsAndWidgets().setTranslationProvider(child -> {
+ int index = getShortcutsAndWidgets().indexOfChild(child);
+ float borderSpaceDelta = adjustedBorderSpace - dp.hotseatBorderSpace;
+ return dp.iconSizePx + index * borderSpaceDelta;
+ });
+ if (mQsb instanceof HorizontalInsettableView) {
+ HorizontalInsettableView insettableQsb = (HorizontalInsettableView) mQsb;
+ final float insetFraction = (float) dp.iconSizePx / dp.hotseatQsbWidth;
+ // post this to the looper so that QSB has a chance to redraw itself, e.g.
+ // after device rotation
+ mQsb.post(() -> insettableQsb.setHorizontalInsets(insetFraction));
+ }
+ } else {
+ getShortcutsAndWidgets().setTranslationProvider(null);
+ if (mQsb instanceof HorizontalInsettableView) {
+ ((HorizontalInsettableView) mQsb).setHorizontalInsets(0);
+ }
+ }
+ }
+
resetCellSize(dp);
if (hasVerticalHotseat) {
setGridSize(1, dp.numShownHotseatIcons);
@@ -83,6 +121,62 @@
}
}
+ /**
+ * Adjust the hotseat icons for the bubble bar.
+ *
+ * <p>When the bubble bar becomes visible, if needed, this method animates the hotseat icons
+ * to reduce the spacing between them and make room for the bubble bar. The QSB width is
+ * animated as well to align with the hotseat icons.
+ *
+ * <p>When the bubble bar goes away, any adjustments that were previously made are reversed.
+ */
+ public void adjustForBubbleBar(boolean isBubbleBarVisible) {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ float adjustedBorderSpace = dp.getHotseatAdjustedBorderSpaceForBubbleBar(getContext());
+ if (Float.compare(adjustedBorderSpace, 0f) == 0) {
+ return;
+ }
+
+ ShortcutAndWidgetContainer icons = getShortcutsAndWidgets();
+ AnimatorSet animatorSet = new AnimatorSet();
+ float borderSpaceDelta = adjustedBorderSpace - dp.hotseatBorderSpace;
+
+ // update the translation provider for future layout passes of hotseat icons.
+ if (isBubbleBarVisible) {
+ icons.setTranslationProvider(child -> {
+ int index = icons.indexOfChild(child);
+ return dp.iconSizePx + index * borderSpaceDelta;
+ });
+ } else {
+ icons.setTranslationProvider(null);
+ }
+
+ for (int i = 0; i < icons.getChildCount(); i++) {
+ View child = icons.getChildAt(i);
+ float tx = isBubbleBarVisible ? dp.iconSizePx + i * borderSpaceDelta : 0;
+ if (child instanceof Reorderable) {
+ MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();
+ animatorSet.play(
+ mtd.getTranslationX(INDEX_BUBBLE_ADJUSTMENT_ANIM).animateToValue(tx));
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, tx));
+ }
+ }
+ if (mQsb instanceof HorizontalInsettableView) {
+ HorizontalInsettableView horizontalInsettableQsb = (HorizontalInsettableView) mQsb;
+ ValueAnimator qsbAnimator = ValueAnimator.ofFloat(0f, 1f);
+ qsbAnimator.addUpdateListener(animation -> {
+ float fraction = qsbAnimator.getAnimatedFraction();
+ float insetFraction = isBubbleBarVisible
+ ? (float) dp.iconSizePx * fraction / dp.hotseatQsbWidth
+ : (float) dp.iconSizePx * (1 - fraction) / dp.hotseatQsbWidth;
+ horizontalInsettableQsb.setHorizontalInsets(insetFraction);
+ });
+ animatorSet.play(qsbAnimator);
+ }
+ animatorSet.setDuration(BUBBLE_BAR_ADJUSTMENT_ANIMATION_DURATION_MS).start();
+ }
+
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index c619bc5..75f4bb2 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
+import static com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.TargetApi;
@@ -224,7 +225,7 @@
DisplayController.INSTANCE.get(context).setPriorityListener(
(displayContext, info, flags) -> {
if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS
- | CHANGE_NAVIGATION_MODE)) != 0) {
+ | CHANGE_NAVIGATION_MODE | CHANGE_TASKBAR_PINNING)) != 0) {
onConfigChanged(displayContext);
}
});
@@ -485,7 +486,9 @@
iconBitmapSize, fillResIconDpi, numDatabaseAllAppsColumns, dbFile};
}
- private void onConfigChanged(Context context) {
+ /** Updates IDP using the provided context. Notifies listeners of change. */
+ @VisibleForTesting
+ public void onConfigChanged(Context context) {
Object[] oldState = toModelState();
// Re-init grid
@@ -888,7 +891,7 @@
deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
DEVICE_CATEGORY_ALL);
- if (FeatureFlags.ENABLE_RESPONSIVE_WORKSPACE.get()) {
+ if (FeatureFlags.enableResponsiveWorkspace()) {
mWorkspaceSpecsId = a.getResourceId(
R.styleable.GridDisplayOption_workspaceSpecsId, INVALID_RESOURCE_HANDLE);
mWorkspaceSpecsTwoPanelId = a.getResourceId(
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 038967c..ec2816b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -26,8 +26,9 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_FOLDER;
import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
-import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
+import static com.android.launcher3.BuildConfig.APPLICATION_ID;
+import static com.android.launcher3.BuildConfig.QSB_ON_FIRST_SCREEN;
import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WIDGET_TRANSITION;
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
@@ -43,10 +44,11 @@
import static com.android.launcher3.LauncherState.NO_SCALE;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
+import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.config.FeatureFlags.MULTI_SELECT_EDIT_MODE;
-import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import static com.android.launcher3.logging.StatsLogManager.EventEnum;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
@@ -68,6 +70,7 @@
import static com.android.launcher3.logging.StatsLogManager.StatsLatencyLogger.LatencyType.WARM;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_ACTIVITY_PAUSED;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP;
+import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
@@ -113,7 +116,6 @@
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
-import android.view.KeyboardShortcutInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
@@ -136,13 +138,11 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.accessibility.BaseAccessibilityDelegate.LauncherAction;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.AllAppsRecyclerView;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.BaseSearchConfig;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.PropertyListBuilder;
@@ -184,7 +184,6 @@
import com.android.launcher3.pageindicators.WorkspacePageIndicator;
import com.android.launcher3.pm.PinRequestHelper;
import com.android.launcher3.popup.ArrowPopup;
-import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.qsb.QsbContainerView;
@@ -199,15 +198,15 @@
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ActivityTracker;
+import com.android.launcher3.util.BackPressHandler;
import com.android.launcher3.util.CannedAnimationCoordinator;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.KeyboardShortcutsDelegate;
import com.android.launcher3.util.LockedUserState;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
-import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
@@ -236,9 +235,9 @@
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.systemui.plugins.LauncherOverlayPlugin;
import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.shared.LauncherExterns;
import com.android.systemui.plugins.shared.LauncherOverlayManager;
import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
+import com.android.wm.shell.Flags;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -258,7 +257,7 @@
* Default launcher application.
*/
public class Launcher extends StatefulActivity<LauncherState>
- implements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener,
+ implements Callbacks, InvariantDeviceProfile.OnIDPChangeListener,
PluginListener<LauncherOverlayPlugin> {
public static final String TAG = "Launcher";
@@ -321,21 +320,26 @@
@Thunk @VisibleForTesting public static final int NEW_APPS_ANIMATION_DELAY = 500;
private static final String DISPLAY_WORKSPACE_TRACE_METHOD_NAME = "DisplayWorkspaceFirstFrame";
- private static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps";
+ public static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps";
public static final int DISPLAY_WORKSPACE_TRACE_COOKIE = 0;
public static final int DISPLAY_ALL_APPS_TRACE_COOKIE = 1;
+ private static final String COLD_STARTUP_TRACE_METHOD_NAME = "LauncherColdStartup";
+ public static final int COLD_STARTUP_TRACE_COOKIE = 2;
private static final FloatProperty<Workspace<?>> WORKSPACE_WIDGET_SCALE =
WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION);
private static final FloatProperty<Hotseat> HOTSEAT_WIDGET_SCALE =
HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION);
- private static final boolean DESKTOP_MODE_1_SUPPORTED =
- "1".equals(Utilities.getSystemProperty("persist.wm.debug.desktop_mode", "0"));
-
- private static final boolean DESKTOP_MODE_2_SUPPORTED =
+ private static final boolean ENABLE_DESKTOP_WINDOWING = Flags.enableDesktopWindowing();
+ private static final boolean DESKTOP_MODE_SUPPORTED =
"1".equals(Utilities.getSystemProperty("persist.wm.debug.desktop_mode_2", "0"));
+ private final ModelCallbacks mModelCallbacks = createModelCallbacks();
+
+ private final KeyboardShortcutsDelegate mKeyboardShortcutsDelegate =
+ new KeyboardShortcutsDelegate(this);
+
@Thunk
Workspace<?> mWorkspace;
@Thunk
@@ -380,13 +384,9 @@
private PopupDataProvider mPopupDataProvider;
- private IntSet mSynchronouslyBoundPages = new IntSet();
- @NonNull private IntSet mPagesToBindSynchronously = new IntSet();
-
// We only want to get the SharedPreferences once since it does an FS stat each time we get
// it from the context.
private SharedPreferences mSharedPrefs;
- private OnboardingPrefs<? extends Launcher> mOnboardingPrefs;
// Activity result which needs to be processed after workspace has loaded.
private ActivityResultInfo mPendingActivityResult;
@@ -419,13 +419,21 @@
private LauncherState mPrevLauncherState;
private StringCache mStringCache;
- private BaseSearchConfig mBaseSearchConfig;
private StartupLatencyLogger mStartupLatencyLogger;
private CellPosMapper mCellPosMapper = CellPosMapper.DEFAULT;
+ private boolean mIsFirstPagePinnedItemEnabled = QSB_ON_FIRST_SCREEN
+ && !ENABLE_SMARTSPACE_REMOVAL.get();
private final CannedAnimationCoordinator mAnimationCoordinator =
new CannedAnimationCoordinator(this);
+ private final List<BackPressHandler> mBackPressedHandlers = new ArrayList<>();
+ private boolean mIsColdStartupAfterReboot;
+
+ public static Launcher getLauncher(Context context) {
+ return fromContext(context);
+ }
+
@Override
@TargetApi(Build.VERSION_CODES.S)
protected void onCreate(Bundle savedInstanceState) {
@@ -435,6 +443,14 @@
? COLD
: COLD_DEVICE_REBOOTING
: WARM);
+
+ mIsColdStartupAfterReboot = sIsNewProcess
+ && !LockedUserState.get(this).isUserUnlockedAtLauncherStartup();
+ if (mIsColdStartupAfterReboot) {
+ Trace.beginAsyncSection(
+ COLD_STARTUP_TRACE_METHOD_NAME, COLD_STARTUP_TRACE_COOKIE);
+ }
+
sIsNewProcess = false;
mStartupLatencyLogger
.logStart(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
@@ -516,11 +532,6 @@
mAllAppsController = new AllAppsTransitionController(this);
mStateManager = new StateManager<>(this, NORMAL);
- mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);
-
- // TODO: move the SearchConfig to SearchState when new LauncherState is created.
- mBaseSearchConfig = new BaseSearchConfig();
-
setupViews();
mAppWidgetManager = new WidgetManagerHelper(this);
@@ -543,7 +554,7 @@
if (savedInstanceState != null) {
int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);
if (pageIds != null) {
- mPagesToBindSynchronously = IntSet.wrap(pageIds);
+ mModelCallbacks.setPagesToBindSynchronously(IntSet.wrap(pageIds));
}
}
@@ -572,9 +583,6 @@
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
- if (mLauncherCallbacks != null) {
- mLauncherCallbacks.onCreate(savedInstanceState);
- }
mOverlayManager = getDefaultOverlay();
PluginManagerWrapper.INSTANCE.get(this).addPluginListener(this,
LauncherOverlayPlugin.class, false /* allowedMultiple */);
@@ -589,6 +597,10 @@
mStartupLatencyLogger.logEnd(LAUNCHER_LATENCY_STARTUP_ACTIVITY_ON_CREATE);
}
+ protected ModelCallbacks createModelCallbacks() {
+ return new ModelCallbacks(this);
+ }
+
/**
* Create {@link StartupLatencyLogger} that only collects launcher startup latency metrics
* without sending them anywhere. Child class can override this method to create logger
@@ -605,6 +617,7 @@
* <li> auto cancel action mode handler
* <li> drag handler
* <li> view handler
+ * <li> registered {@link BackPressHandler}
* <li> state handler
* </ol>
*
@@ -634,7 +647,14 @@
return topView;
}
- // #4 state handler
+ // #4 Custom back handlers
+ for (BackPressHandler handler : mBackPressedHandlers) {
+ if (handler.canHandleBack()) {
+ return handler;
+ }
+ }
+
+ // #5 state handler
return new OnBackAnimationCallback() {
@Override
public void onBackInvoked() {
@@ -658,18 +678,9 @@
return new LauncherOverlayManager() { };
}
- protected OnboardingPrefs<? extends Launcher> createOnboardingPrefs(
- SharedPreferences sharedPrefs) {
- return new OnboardingPrefs<>(this, sharedPrefs);
- }
-
- public OnboardingPrefs<? extends Launcher> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
@Override
public void onPluginConnected(LauncherOverlayPlugin overlayManager, Context context) {
- switchOverlay(() -> overlayManager.createOverlayManager(this, this));
+ switchOverlay(() -> overlayManager.createOverlayManager(this));
}
@Override
@@ -679,7 +690,7 @@
private void switchOverlay(Supplier<LauncherOverlayManager> overlaySupplier) {
if (mOverlayManager != null) {
- mOverlayManager.onActivityDestroyed(this);
+ mOverlayManager.onActivityDestroyed();
}
mOverlayManager = overlaySupplier.get();
if (getRootView().isAttachedToWindow()) {
@@ -781,56 +792,6 @@
}
@Override
- public CellPosMapper getCellPosMapper() {
- return mCellPosMapper;
- }
-
- public RotationHelper getRotationHelper() {
- return mRotationHelper;
- }
-
- public ViewGroupFocusHelper getFocusHandler() {
- return mFocusHandler;
- }
-
- @Override
- public StateManager<LauncherState> getStateManager() {
- return mStateManager;
- }
-
- private LauncherCallbacks mLauncherCallbacks;
-
- /**
- * Call this after onCreate to set or clear overlay.
- */
- @Override
- public void setLauncherOverlay(LauncherOverlay overlay) {
- mWorkspace.setLauncherOverlay(overlay);
- }
-
- public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
- mLauncherCallbacks = callbacks;
- return true;
- }
-
- public boolean isDraggingEnabled() {
- // We prevent dragging when we are loading the workspace as it is possible to pick up a view
- // that is subsequently removed from the workspace in startBinding().
- return !isWorkspaceLoading();
- }
-
- @NonNull
- @Override
- public PopupDataProvider getPopupDataProvider() {
- return mPopupDataProvider;
- }
-
- @Override
- public DotInfo getDotInfoForItem(ItemInfo info) {
- return mPopupDataProvider.getDotInfoForItem(info);
- }
-
- @Override
public void invalidateParent(ItemInfo info) {
if (info.container >= 0) {
View folderIcon = getWorkspace().getHomescreenIconByItemId(info.container);
@@ -878,7 +839,7 @@
if (widgetInfo != null) {
// Since the view was just bound, also launch the configure activity if needed
LauncherAppWidgetProviderInfo provider = mAppWidgetManager
- .getLauncherAppWidgetInfo(widgetId);
+ .getLauncherAppWidgetInfo(widgetId, info.getTargetComponent());
if (provider != null) {
new WidgetAddFlowHandler(provider)
.startConfigActivity(this, widgetInfo,
@@ -1070,7 +1031,7 @@
if (mDeferOverlayCallbacks) {
checkIfOverlayStillDeferred();
} else {
- mOverlayManager.onActivityStopped(this);
+ mOverlayManager.onActivityStopped();
}
hideKeyboard();
logStopAndResume(false /* isResume */);
@@ -1084,7 +1045,7 @@
TraceHelper.INSTANCE.beginSection(ON_START_EVT);
super.onStart();
if (!mDeferOverlayCallbacks) {
- mOverlayManager.onActivityStarted(this);
+ mOverlayManager.onActivityStarted();
}
mAppWidgetHolder.setActivityStarted(true);
@@ -1153,15 +1114,15 @@
// Move the client to the correct state. Calling the same method twice is no-op.
if (isStarted()) {
- mOverlayManager.onActivityStarted(this);
+ mOverlayManager.onActivityStarted();
}
if (hasBeenResumed()) {
- mOverlayManager.onActivityResumed(this);
+ mOverlayManager.onActivityResumed();
} else {
- mOverlayManager.onActivityPaused(this);
+ mOverlayManager.onActivityPaused();
}
if (!isStarted()) {
- mOverlayManager.onActivityStopped(this);
+ mOverlayManager.onActivityStopped();
}
}
@@ -1169,10 +1130,6 @@
mDeferOverlayCallbacks = true;
}
- public LauncherOverlayManager getOverlayManager() {
- return mOverlayManager;
- }
-
@Override
public void onStateSetStart(LauncherState state) {
super.onStateSetStart(state);
@@ -1265,7 +1222,7 @@
if (mDeferOverlayCallbacks) {
scheduleDeferredCheck();
} else {
- mOverlayManager.onActivityResumed(this);
+ mOverlayManager.onActivityResumed();
}
DragView.removeAllViews(this);
@@ -1283,7 +1240,7 @@
mDropTargetBar.animateToVisibility(false);
if (!mDeferOverlayCallbacks) {
- mOverlayManager.onActivityPaused(this);
+ mOverlayManager.onActivityPaused();
}
mAppWidgetHolder.setActivityResumed(false);
}
@@ -1348,7 +1305,9 @@
// Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
// default state, otherwise we will update to the wrong offsets in RTL
mWorkspace.lockWallpaperToDefaultPage();
- mWorkspace.bindAndInitFirstWorkspaceScreen();
+ if (!ENABLE_SMARTSPACE_REMOVAL.get()) {
+ mWorkspace.bindAndInitFirstWorkspaceScreen();
+ }
mDragController.addDragListener(mWorkspace);
// Get the search/delete/uninstall bar
@@ -1365,18 +1324,14 @@
mDropTargetBar.setup(mDragController);
mAllAppsController.setupViews(mScrimView, mAppsView);
- if (SHOW_DOT_PAGINATION.get()) {
- mWorkspace.getPageIndicator().setShouldAutoHide(true);
- mWorkspace.getPageIndicator().setPaintColor(
- Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)
- ? Color.BLACK
- : Color.WHITE);
- }
+ mWorkspace.getPageIndicator().setShouldAutoHide(true);
+ mWorkspace.getPageIndicator().setPaintColor(Themes.getAttrBoolean(
+ this, R.attr.isWorkspaceDarkText) ? Color.BLACK : Color.WHITE);
}
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
- if (SHOW_DOT_PAGINATION.get() && WorkspacePageIndicator.class.getName().equals(name)) {
+ if (WorkspacePageIndicator.class.getName().equals(name)) {
return LayoutInflater.from(context).inflate(R.layout.page_indicator_dots,
(ViewGroup) parent, false);
}
@@ -1492,7 +1447,8 @@
AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) {
if (appWidgetInfo == null) {
- appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId);
+ appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId,
+ itemInfo.getTargetComponent());
}
if (hostView == null) {
@@ -1579,79 +1535,11 @@
return instance;
}
- public AllAppsTransitionController getAllAppsController() {
- return mAllAppsController;
- }
-
- @Override
- public DragLayer getDragLayer() {
- return mDragLayer;
- }
-
- @Override
- public ActivityAllAppsContainerView<Launcher> getAppsView() {
- return mAppsView;
- }
-
- public Workspace<?> getWorkspace() {
- return mWorkspace;
- }
-
- public Hotseat getHotseat() {
- return mHotseat;
- }
-
- public <T extends View> T getOverviewPanel() {
- return (T) mOverviewPanel;
- }
-
- public DropTargetBar getDropTargetBar() {
- return mDropTargetBar;
- }
-
- @Override
- public ScrimView getScrimView() {
- return mScrimView;
- }
-
- public LauncherWidgetHolder getAppWidgetHolder() {
- return mAppWidgetHolder;
- }
-
protected LauncherWidgetHolder createAppWidgetHolder() {
return LauncherWidgetHolder.HolderFactory.newFactory(this).newInstance(
this, appWidgetId -> getWorkspace().removeWidget(appWidgetId));
}
- public LauncherModel getModel() {
- return mModel;
- }
-
- /**
- * Returns the ModelWriter writer, make sure to call the function every time you want to use it.
- */
- public ModelWriter getModelWriter() {
- return mModelWriter;
- }
-
- @Override
- public SharedPreferences getSharedPrefs() {
- return mSharedPrefs;
- }
-
- @Override
- public SharedPreferences getDevicePrefs() {
- return LauncherPrefs.getDevicePrefs(this);
- }
-
- public int getOrientation() {
- return mOldConfig.orientation;
- }
-
- public BaseSearchConfig getSearchConfig() {
- return mBaseSearchConfig;
- }
-
@Override
protected void onNewIntent(Intent intent) {
if (Utilities.isRunningInTestHarness()) {
@@ -1692,10 +1580,7 @@
}
}
- if (mLauncherCallbacks != null) {
- mLauncherCallbacks.onHomeIntent(internalStateHandled);
- }
- if (FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) {
+ if (FeatureFlags.enableSplitContextually()) {
handleSplitAnimationGoingToHome();
}
mOverlayManager.hideOverlay(isStarted() && !isForceInvisible());
@@ -1757,8 +1642,9 @@
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
- if (mSynchronouslyBoundPages != null) {
- mSynchronouslyBoundPages.forEach(screenId -> {
+ IntSet synchronouslyBoundPages = mModelCallbacks.getSynchronouslyBoundPages();
+ if (synchronouslyBoundPages != null) {
+ synchronouslyBoundPages.forEach(screenId -> {
int pageIndex = mWorkspace.getPageIndexForScreenId(screenId);
if (pageIndex != PagedView.INVALID_PAGE) {
mWorkspace.restoreInstanceStateForChild(pageIndex);
@@ -1799,7 +1685,6 @@
}
super.onSaveInstanceState(outState);
- mOverlayManager.onActivitySaveInstanceState(this, outState);
}
@Override
@@ -1825,7 +1710,7 @@
clearPendingBinds();
LauncherAppState.getIDP(this).removeOnChangeListener(this);
- mOverlayManager.onActivityDestroyed(this);
+ mOverlayManager.onActivityDestroyed();
}
public LauncherAccessibilityDelegate getAccessibilityDelegate() {
@@ -1858,54 +1743,11 @@
try {
super.startIntentSenderForResult(intent, requestCode,
fillInIntent, flagsMask, flagsValues, extraFlags, options);
- } catch (IntentSender.SendIntentException e) {
+ } catch (Exception e) {
throw new ActivityNotFoundException();
}
}
- /**
- * Indicates that we want global search for this activity by setting the globalSearch
- * argument for {@link #startSearch} to true.
- */
- @Override
- public void startSearch(String initialQuery, boolean selectInitialQuery,
- Bundle appSearchData, boolean globalSearch) {
- if (appSearchData == null) {
- appSearchData = new Bundle();
- appSearchData.putString("source", "launcher-search");
- }
-
- if (mLauncherCallbacks == null ||
- !mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData)) {
- // Starting search from the callbacks failed. Start the default global search.
- super.startSearch(initialQuery, selectInitialQuery, appSearchData, true);
- }
-
- // We need to show the workspace after starting the search
- mStateManager.goToState(NORMAL);
- }
-
- public boolean isWorkspaceLocked() {
- return mWorkspaceLoading || mPendingRequestArgs != null;
- }
-
- public boolean isWorkspaceLoading() {
- return mWorkspaceLoading;
- }
-
- @Override
- public boolean isBindingItems() {
- return mWorkspaceLoading;
- }
-
- private void setWorkspaceLoading(boolean value) {
- mWorkspaceLoading = value;
- }
-
- public void setWaitingForResult(PendingRequestArgs args) {
- mPendingRequestArgs = args;
- }
-
void addAppWidgetFromDropImpl(int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget,
WidgetAddFlowHandler addFlowHandler) {
if (LOGD) {
@@ -1987,8 +1829,8 @@
// In this case, we either need to start an activity to get permission to bind
// the widget, or we need to start an activity to configure the widget, or both.
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET) {
- appWidgetId = CustomWidgetManager.INSTANCE.get(this).getWidgetIdForCustomProvider(
- info.componentName);
+ appWidgetId = CustomWidgetManager.INSTANCE.get(this)
+ .allocateCustomAppWidgetId(info.componentName);
} else {
appWidgetId = getAppWidgetHolder().allocateAppWidgetId();
}
@@ -2135,13 +1977,6 @@
return super.dispatchTouchEvent(ev);
}
- /**
- * Returns true if a touch interaction is in progress
- */
- public boolean isTouchInProgress() {
- return mTouchInProgress;
- }
-
@Override
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public void onBackPressed() {
@@ -2170,7 +2005,7 @@
// Workaround an issue where the WM launch animation is clobbered when finishing the
// recents animation into launcher. Defer launching the activity until Launcher is
// next resumed.
- addOnResumeCallback(() -> {
+ addEventCallback(EVENT_RESUMED, () -> {
RunnableList actualResult = startActivitySafely(v, intent, item);
if (actualResult != null) {
actualResult.add(result::executeAllAndDestroy);
@@ -2203,16 +2038,6 @@
return mHotseat != null && (layout == mHotseat);
}
- /**
- * Returns the CellLayout of the specified container at the specified screen.
- *
- * @param screenId must be presenterPos and not modelPos.
- */
- public CellLayout getCellLayout(int container, int screenId) {
- return (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)
- ? mHotseat : mWorkspace.getScreenWithId(screenId);
- }
-
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
@@ -2239,59 +2064,9 @@
return result;
}
- /**
- * Persistant callback which notifies when an activity launch is deferred because the activity
- * was not yet resumed.
- */
- public void setOnDeferredActivityLaunchCallback(Runnable callback) {
- mOnDeferredActivityLaunchCallback = callback;
- }
-
- /**
- * Sets the next pages to bind synchronously on next bind.
- * @param pages should not be null.
- */
- public void setPagesToBindSynchronously(@NonNull IntSet pages) {
- mPagesToBindSynchronously = pages;
- }
-
@Override
public IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
- IntSet visibleIds;
- if (!mPagesToBindSynchronously.isEmpty()) {
- visibleIds = mPagesToBindSynchronously;
- } else if (!mWorkspaceLoading) {
- visibleIds = mWorkspace.getCurrentPageScreenIds();
- } else {
- // If workspace binding is still in progress, getCurrentPageScreenIds won't be accurate,
- // and we should use mSynchronouslyBoundPages that's set during initial binding.
- visibleIds = mSynchronouslyBoundPages;
- }
- IntArray actualIds = new IntArray();
-
- IntSet result = new IntSet();
- if (visibleIds.isEmpty()) {
- return result;
- }
- for (int id : orderedScreenIds.toArray()) {
- actualIds.add(id);
- }
- int firstId = visibleIds.getArray().get(0);
- int pairId = mWorkspace.getScreenPair(firstId);
- // Double check that actual screenIds contains the visibleId, as empty screens are hidden
- // in single panel.
- if (actualIds.contains(firstId)) {
- result.add(firstId);
- if (mDeviceProfile.isTwoPanels && actualIds.contains(pairId)) {
- result.add(pairId);
- }
- } else if (LauncherAppState.getIDP(this).supportedProfiles.stream().anyMatch(
- deviceProfile -> deviceProfile.isTwoPanels) && actualIds.contains(pairId)) {
- // Add the right panel if left panel is hidden when switching display, due to empty
- // pages being hidden in single panel.
- result.add(pairId);
- }
- return result;
+ return mModelCallbacks.getPagesToBindSynchronously(orderedScreenIds);
}
/**
@@ -2315,6 +2090,7 @@
* <p>
* Implementation of the method from LauncherModel.Callbacks.
*/
+ @Override
public void startBinding() {
TraceHelper.INSTANCE.beginSection("startBinding");
// Floating panels (except the full widget sheet) are associated with individual icons. If
@@ -2338,14 +2114,24 @@
}
@Override
+ public void setIsFirstPagePinnedItemEnabled(boolean isFirstPagePinnedItemEnabled) {
+ mIsFirstPagePinnedItemEnabled = isFirstPagePinnedItemEnabled;
+ mWorkspace.bindAndInitFirstWorkspaceScreen();
+ }
+
+ @Override
public void bindScreens(IntArray orderedScreenIds) {
- mWorkspace.mPageIndicator.setAreScreensBinding(true);
+ mWorkspace.mPageIndicator.setAreScreensBinding(true, mDeviceProfile.isTwoPanels);
int firstScreenPosition = 0;
- if (FeatureFlags.QSB_ON_FIRST_SCREEN &&
- orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != firstScreenPosition) {
- orderedScreenIds.removeValue(Workspace.FIRST_SCREEN_ID);
- orderedScreenIds.add(firstScreenPosition, Workspace.FIRST_SCREEN_ID);
- } else if (!FeatureFlags.QSB_ON_FIRST_SCREEN && orderedScreenIds.isEmpty()) {
+ if ((FeatureFlags.QSB_ON_FIRST_SCREEN
+ && mIsFirstPagePinnedItemEnabled
+ && !shouldShowFirstPageWidget())
+ && orderedScreenIds.indexOf(FIRST_SCREEN_ID) != firstScreenPosition) {
+ orderedScreenIds.removeValue(FIRST_SCREEN_ID);
+ orderedScreenIds.add(firstScreenPosition, FIRST_SCREEN_ID);
+ } else if (((!FeatureFlags.QSB_ON_FIRST_SCREEN && !mIsFirstPagePinnedItemEnabled)
+ || shouldShowFirstPageWidget())
+ && orderedScreenIds.isEmpty()) {
// If there are no screens, we need to have an empty screen
mWorkspace.addExtraEmptyScreens();
}
@@ -2393,7 +2179,10 @@
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
int screenId = orderedScreenIds.get(i);
- if (FeatureFlags.QSB_ON_FIRST_SCREEN && screenId == Workspace.FIRST_SCREEN_ID) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && mIsFirstPagePinnedItemEnabled
+ && !shouldShowFirstPageWidget()
+ && screenId == FIRST_SCREEN_ID) {
// No need to bind the first screen, as its always bound.
continue;
}
@@ -2403,13 +2192,7 @@
@Override
public void preAddApps() {
- // If there's an undo snackbar, force it to complete to ensure empty screens are removed
- // before trying to add new items.
- mModelWriter.commitDelete();
- AbstractFloatingView snackbar = AbstractFloatingView.getOpenView(this, TYPE_SNACKBAR);
- if (snackbar != null) {
- snackbar.post(() -> snackbar.close(true));
- }
+ mModelCallbacks.preAddApps();
}
@Override
@@ -2634,9 +2417,10 @@
}
}
} else {
- appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(item.appWidgetId);
+ appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(item.appWidgetId,
+ item.getTargetComponent());
if (appWidgetInfo == null) {
- if (item.appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
+ if (item.appWidgetId <= CUSTOM_WIDGET_ID) {
removalReason =
"CustomWidgetManager cannot find provider from that widget id.";
} else {
@@ -2784,8 +2568,8 @@
@TargetApi(Build.VERSION_CODES.S)
public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks,
int workspaceItemCount, boolean isBindSync) {
- mSynchronouslyBoundPages = boundPages;
- mPagesToBindSynchronously = new IntSet();
+ mModelCallbacks.setSynchronouslyBoundPages(boundPages);
+ mModelCallbacks.setPagesToBindSynchronously(new IntSet());
clearPendingBinds();
ViewOnDrawExecutor executor = new ViewOnDrawExecutor(pendingTasks);
@@ -2812,16 +2596,20 @@
.logEnd(isBindSync
? LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_SYNC
: LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_ASYNC);
- // In the first rootview's onDraw after onInitialBindComplete(), log end of startup latency.
+ MAIN_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
+ mStartupLatencyLogger
+ .logEnd(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
+ .log()
+ .reset();
+ if (mIsColdStartupAfterReboot) {
+ Trace.endAsyncSection(COLD_STARTUP_TRACE_METHOD_NAME,
+ COLD_STARTUP_TRACE_COOKIE);
+ }
+ });
getRootView().getViewTreeObserver().addOnDrawListener(
new ViewTreeObserver.OnDrawListener() {
-
@Override
public void onDraw() {
- mStartupLatencyLogger
- .logEnd(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
- .log()
- .reset();
MAIN_EXECUTOR.getHandler().postAtFrontOfQueue(
() -> getRootView().getViewTreeObserver()
.removeOnDrawListener(this));
@@ -2853,7 +2641,7 @@
// Since we are just resetting the current page without user interaction,
// override the previous page so we don't log the page switch.
mWorkspace.setCurrentPage(currentPage, currentPage /* overridePrevPage */);
- mPagesToBindSynchronously = new IntSet();
+ mModelCallbacks.setPagesToBindSynchronously(new IntSet());
// Cache one page worth of icons
getViewCache().setCacheSize(R.layout.folder_application,
@@ -2862,7 +2650,7 @@
TraceHelper.INSTANCE.endSection();
mWorkspace.removeExtraEmptyScreen(/* stripEmptyScreens= */ true);
- mWorkspace.mPageIndicator.setAreScreensBinding(false);
+ mWorkspace.mPageIndicator.setAreScreensBinding(false, mDeviceProfile.isTwoPanels);
}
private boolean canAnimatePageChange() {
@@ -3006,90 +2794,100 @@
public void onPageEndTransition() {}
/**
- * Add the icons for all apps.
- *
- * Implementation of the method from LauncherModel.Callbacks.
+ * See {@code LauncherBindingDelegate}
*/
@Override
@TargetApi(Build.VERSION_CODES.S)
@UiThread
public void bindAllApplications(AppInfo[] apps, int flags,
Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
- Preconditions.assertUIThread();
- boolean hadWorkApps = mAppsView.shouldShowTabs();
- AllAppsStore<Launcher> appsStore = mAppsView.getAppsStore();
- appsStore.setApps(apps, flags, packageUserKeytoUidMap);
- PopupContainerWithArrow.dismissInvalidPopup(this);
- if (hadWorkApps != mAppsView.shouldShowTabs()) {
- getStateManager().goToState(NORMAL);
- }
-
+ mModelCallbacks.bindAllApplications(apps, flags, packageUserKeytoUidMap);
if (Utilities.ATLEAST_S) {
- Trace.endAsyncSection(DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
- DISPLAY_ALL_APPS_TRACE_COOKIE);
+ Trace.endAsyncSection(
+ Launcher.DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
+ Launcher.DISPLAY_ALL_APPS_TRACE_COOKIE
+ );
}
}
/**
- * Copies LauncherModel's map of activities to shortcut counts to Launcher's. This is necessary
- * because LauncherModel's map is updated in the background, while Launcher runs on the UI.
+ * See {@code LauncherBindingDelegate}
*/
@Override
public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy) {
- mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
+ mModelCallbacks.bindDeepShortcutMap(deepShortcutMapCopy);
}
@Override
public void bindIncrementalDownloadProgressUpdated(AppInfo app) {
- mAppsView.getAppsStore().updateProgressBar(app);
+ mModelCallbacks.bindIncrementalDownloadProgressUpdated(app);
}
@Override
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) {
- mWorkspace.widgetsRestored(widgets);
+ mModelCallbacks.bindWidgetsRestored(widgets);
}
/**
- * Some shortcuts were updated in the background.
- * Implementation of the method from LauncherModel.Callbacks.
- *
- * @param updated list of shortcuts which have changed.
+ * See {@code LauncherBindingDelegate}
*/
@Override
public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
- if (!updated.isEmpty()) {
- mWorkspace.updateWorkspaceItems(updated, this);
- PopupContainerWithArrow.dismissInvalidPopup(this);
- }
+ mModelCallbacks.bindWorkspaceItemsChanged(updated);
}
/**
- * Update the state of a package, typically related to install state.
- *
- * Implementation of the method from LauncherModel.Callbacks.
+ * See {@code LauncherBindingDelegate}
*/
@Override
public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
- mWorkspace.updateRestoreItems(updates, this);
+ mModelCallbacks.bindRestoreItemsChange(updates);
}
/**
- * A package was uninstalled/updated. We take both the super set of packageNames
- * in addition to specific applications to remove, the reason being that
- * this can be called when a package is updated as well. In that scenario,
- * we only remove specific components from the workspace and hotseat, where as
- * package-removal should clear all items by package name.
+ * See {@code LauncherBindingDelegate}
*/
@Override
public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) {
- mWorkspace.removeItemsByMatcher(matcher);
- mDragController.onAppsRemoved(matcher);
- PopupContainerWithArrow.dismissInvalidPopup(this);
+ mModelCallbacks.bindWorkspaceComponentsRemoved(matcher);
+ }
+
+ /**
+ * See {@code LauncherBindingDelegate}
+ */
+ @Override
+ public void bindAllWidgets(final List<WidgetsListBaseEntry> allWidgets) {
+ mModelCallbacks.bindAllWidgets(allWidgets);
}
@Override
- public void bindAllWidgets(final List<WidgetsListBaseEntry> allWidgets) {
- mPopupDataProvider.setAllWidgets(allWidgets);
+ public void bindSmartspaceWidget() {
+ CellLayout cl = mWorkspace.getScreenWithId(FIRST_SCREEN_ID);
+ int spanX = InvariantDeviceProfile.INSTANCE.get(this).numSearchContainerColumns;
+ if (cl != null) {
+ for (int col = 0; col < spanX; col++) {
+ if (cl.isOccupied(col, 0)) {
+ return;
+ }
+ }
+ } else {
+ return;
+ }
+
+ WidgetsListBaseEntry widgetsListBaseEntry = getPopupDataProvider()
+ .getAllWidgets().stream().filter(
+ item -> item.mPkgItem.packageName.equals(
+ APPLICATION_ID))
+ .findFirst()
+ .orElse(null);
+ if (widgetsListBaseEntry != null) {
+ LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
+ widgetsListBaseEntry.mWidgets.get(0).widgetInfo;
+ PendingAddWidgetInfo info = new PendingAddWidgetInfo(launcherAppWidgetProviderInfo,
+ CONTAINER_DESKTOP);
+ addPendingItem(info, info.container, FIRST_SCREEN_ID, new int[]{0, 0}, info.spanX,
+ info.spanY);
+ }
}
@Override
@@ -3098,11 +2896,6 @@
mAppsView.updateWorkUI();
}
- @Override
- public StringCache getStringCache() {
- return mStringCache;
- }
-
/**
* @param packageUser if null, refreshes all widgets and shortcuts, otherwise only
* refreshes the widgets and shortcuts associated with the given package/user
@@ -3127,7 +2920,7 @@
for (int j = 0; j < layout.getChildCount(); j++) {
Object tag = layout.getChildAt(j).getTag();
if (tag != null) {
- writer.println(prefix + " " + tag.toString());
+ writer.println(prefix + " " + tag);
}
}
}
@@ -3137,7 +2930,7 @@
for (int j = 0; j < layout.getChildCount(); j++) {
Object tag = layout.getChildAt(j).getTag();
if (tag != null) {
- writer.println(prefix + " " + tag.toString());
+ writer.println(prefix + " " + tag);
}
}
}
@@ -3156,6 +2949,7 @@
mStateManager.dump(prefix, writer);
mPopupDataProvider.dump(prefix, writer);
mDeviceProfile.dump(this, prefix, writer);
+ mAppsView.getAppsStore().dump(prefix, writer);
try {
FileLog.flushAll(writer);
@@ -3164,91 +2958,54 @@
}
mModel.dumpState(prefix, fd, writer, args);
-
- if (mLauncherCallbacks != null) {
- mLauncherCallbacks.dump(prefix, fd, writer, args);
- }
mOverlayManager.dump(prefix, writer);
}
+ /**
+ * Populates the list of shortcuts. Logic delegated to {@Link KeyboardShortcutsDelegate}.
+ *
+ * @param data The data list to populate with shortcuts.
+ * @param menu The current menu, which may be null.
+ * @param deviceId The id for the connected device the shortcuts should be provided for.
+ */
@Override
public void onProvideKeyboardShortcuts(
List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
-
- ArrayList<KeyboardShortcutInfo> shortcutInfos = new ArrayList<>();
- if (isInState(NORMAL)) {
- shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.all_apps_button_label),
- KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON));
- shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.widget_button_text),
- KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON));
- }
- getSupportedActions(this, getCurrentFocus()).forEach(la ->
- shortcutInfos.add(new KeyboardShortcutInfo(
- la.accessibilityAction.getLabel(), la.keyCode, KeyEvent.META_CTRL_ON)));
- if (!shortcutInfos.isEmpty()) {
- data.add(new KeyboardShortcutGroup(getString(R.string.home_screen), shortcutInfos));
- }
-
+ mKeyboardShortcutsDelegate.onProvideKeyboardShortcuts(data, menu, deviceId);
super.onProvideKeyboardShortcuts(data, menu, deviceId);
}
+ /**
+ * Logic delegated to {@Link KeyboardShortcutsDelegate}.
+ * @param keyCode The value in event.getKeyCode().
+ * @param event Description of the key event.
+ */
@Override
public boolean onKeyShortcut(int keyCode, KeyEvent event) {
- if (event.hasModifiers(KeyEvent.META_CTRL_ON)) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_A:
- if (isInState(NORMAL)) {
- getStateManager().goToState(ALL_APPS);
- return true;
- }
- break;
- case KeyEvent.KEYCODE_W:
- if (isInState(NORMAL)) {
- OptionsPopupView.openWidgets(this);
- return true;
- }
- break;
- default:
- for (LauncherAction la : getSupportedActions(this, getCurrentFocus())) {
- if (la.keyCode == keyCode) {
- return la.invokeFromKeyboard(getCurrentFocus());
- }
- }
- }
- }
- return super.onKeyShortcut(keyCode, event);
+ Boolean result = mKeyboardShortcutsDelegate.onKeyShortcut(keyCode, event);
+ return result != null ? result : super.onKeyShortcut(keyCode, event);
}
+ /**
+ * Logic delegated to {@Link KeyboardShortcutsDelegate}.
+ * @param keyCode The value in event.getKeyCode().
+ * @param event Description of the key event.
+ */
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
- // Close any open floating views.
- closeOpenViews();
- return true;
- }
- return super.onKeyDown(keyCode, event);
+ Boolean result = mKeyboardShortcutsDelegate.onKeyDown(keyCode, event);
+ return result != null ? result : super.onKeyDown(keyCode, event);
}
+ /**
+ * Logic delegated to {@Link KeyboardShortcutsDelegate}.
+ * @param keyCode The value in event.getKeyCode().
+ * @param event Description of the key event.
+ */
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_MENU) {
- // KEYCODE_MENU is sent by some tests, for example
- // LauncherJankTests#testWidgetsContainerFling. Don't just remove its handling.
- if (!mDragController.isDragging() && !mWorkspace.isSwitchingState() &&
- isInState(NORMAL)) {
- // Close any open floating views.
- closeOpenViews();
-
- // Setting the touch point to (-1, -1) will show the options popup in the center of
- // the screen.
- if (Utilities.isRunningInTestHarness()) {
- Log.d(TestProtocol.PERMANENT_DIAG_TAG, "Opening options popup on key up");
- }
- showDefaultOptions(-1, -1);
- }
- return true;
- }
- return super.onKeyUp(keyCode, event);
+ Boolean result = mKeyboardShortcutsDelegate.onKeyUp(keyCode, event);
+ return result != null ? result : super.onKeyUp(keyCode, event);
}
/**
@@ -3259,18 +3016,6 @@
false);
}
- /**
- * Returns target rectangle for anchoring a popup menu.
- */
- protected RectF getPopupTarget(float x, float y) {
- float halfSize = getResources().getDimension(R.dimen.options_menu_thumb_size) / 2;
- if (x < 0 || y < 0) {
- x = mDragLayer.getWidth() / 2;
- y = mDragLayer.getHeight() / 2;
- }
- return new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
- }
-
@Override
public boolean canUseMultipleShadesForPopup() {
return getTopOpenViewWithType(this, TYPE_FOLDER) == null
@@ -3291,26 +3036,48 @@
updateDisallowBack();
}
+ protected void addBackAnimationCallback(BackPressHandler callback) {
+ mBackPressedHandlers.add(callback);
+ }
+
+ protected void removeBackAnimationCallback(BackPressHandler callback) {
+ mBackPressedHandlers.remove(callback);
+ }
+
private void updateDisallowBack() {
- if (DESKTOP_MODE_1_SUPPORTED || DESKTOP_MODE_2_SUPPORTED) {
+ // TODO(b/304778354): remove sysprop once desktop aconfig flag supports dynamic overriding
+ if (ENABLE_DESKTOP_WINDOWING || DESKTOP_MODE_SUPPORTED) {
// Do not disable back in launcher when prototype behavior is enabled
return;
}
LauncherRootView rv = getRootView();
if (rv != null) {
+ boolean isSplitSelectionEnabled = isSplitSelectionEnabled();
boolean disableBack = getStateManager().getState() == NORMAL
- && AbstractFloatingView.getTopOpenView(this) == null;
+ && AbstractFloatingView.getTopOpenView(this) == null
+ && !isSplitSelectionEnabled;
rv.setDisallowBackGesture(disableBack);
}
}
+ /** To be overridden by subclasses */
+ public boolean isSplitSelectionEnabled() {
+ // Overridden
+ return false;
+ }
+
+ /** Call to dismiss the intermediary split selection state. */
+ public void dismissSplitSelection() {
+ // Overridden; move this into ActivityContext if necessary for Taskbar
+ }
+
@Override
public void returnToHomescreen() {
super.returnToHomescreen();
getStateManager().goToState(LauncherState.NORMAL);
}
- private void closeOpenViews() {
+ public void closeOpenViews() {
closeOpenViews(true);
}
@@ -3318,10 +3085,6 @@
AbstractFloatingView.closeAllOpenViews(this, animate);
}
- public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
- return Stream.of(APP_INFO, WIDGETS, INSTALL);
- }
-
protected LauncherAccessibilityDelegate createAccessibilityDelegate() {
return new LauncherAccessibilityDelegate(this);
}
@@ -3330,16 +3093,6 @@
@VisibleForTesting
public void enableHotseatEdu(boolean enable) {}
- /**
- * @see LauncherState#getOverviewScaleAndOffset(Launcher)
- */
- public float[] getNormalOverviewScaleAndOffset() {
- return new float[] {NO_SCALE, NO_OFFSET};
- }
-
- public static Launcher getLauncher(Context context) {
- return fromContext(context);
- }
/**
* Just a wrapper around the type cast to allow easier tracking of calls.
@@ -3377,20 +3130,6 @@
public Configuration config;
}
- @Override
- public StatsLogManager getStatsLogManager() {
- return super.getStatsLogManager().withDefaultInstanceId(mAllAppsSessionLogId);
- }
-
- /**
- * Returns the current popup for testing, if any.
- */
- @VisibleForTesting
- @Nullable
- public ArrowPopup<?> getOptionsPopup() {
- return findViewById(R.id.popup_container);
- }
-
/** Pauses view updates that should not be run during the app launch animation. */
public void pauseExpensiveViewUpdates() {
// Pause page indicator animations as they lead to layer trashing.
@@ -3424,9 +3163,192 @@
return false; // Base launcher does not track freeform tasks
}
+ // Getters and Setters
+
+ private void setWorkspaceLoading(boolean value) {
+ mWorkspaceLoading = value;
+ }
+
+ public boolean isWorkspaceLocked() {
+ return mWorkspaceLoading || mPendingRequestArgs != null;
+ }
+
+ public boolean isWorkspaceLoading() {
+ return mWorkspaceLoading;
+ }
+
@Override
- public View.OnLongClickListener getAllAppsItemLongClickListener() {
- return ItemLongClickListener.INSTANCE_ALL_APPS;
+ public boolean isBindingItems() {
+ return mWorkspaceLoading;
+ }
+
+ /**
+ * Returns true if a touch interaction is in progress
+ */
+ public boolean isTouchInProgress() {
+ return mTouchInProgress;
+ }
+
+ public boolean isDraggingEnabled() {
+ // We prevent dragging when we are loading the workspace as it is possible to pick up a view
+ // that is subsequently removed from the workspace in startBinding().
+ return !isWorkspaceLoading();
+ }
+
+ public void setWaitingForResult(PendingRequestArgs args) {
+ mPendingRequestArgs = args;
+ }
+
+ /**
+ * Call this after onCreate to set or clear overlay.
+ */
+ public void setLauncherOverlay(LauncherOverlay overlay) {
+ mWorkspace.setLauncherOverlay(overlay);
+ }
+
+ /**
+ * Persistent callback which notifies when an activity launch is deferred because the activity
+ * was not yet resumed.
+ */
+ public void setOnDeferredActivityLaunchCallback(Runnable callback) {
+ mOnDeferredActivityLaunchCallback = callback;
+ }
+
+ /**
+ * Sets the next pages to bind synchronously on next bind.
+ * @param pages should not be null.
+ */
+ public void setPagesToBindSynchronously(@NonNull IntSet pages) {
+ mModelCallbacks.setPagesToBindSynchronously(pages);
+ }
+
+ @Override
+ public CellPosMapper getCellPosMapper() {
+ return mCellPosMapper;
+ }
+
+ public RotationHelper getRotationHelper() {
+ return mRotationHelper;
+ }
+
+ public ViewGroupFocusHelper getFocusHandler() {
+ return mFocusHandler;
+ }
+
+ @Override
+ public StateManager<LauncherState> getStateManager() {
+ return mStateManager;
+ }
+
+ @NonNull
+ @Override
+ public PopupDataProvider getPopupDataProvider() {
+ return mPopupDataProvider;
+ }
+
+ @Override
+ public DotInfo getDotInfoForItem(ItemInfo info) {
+ return mPopupDataProvider.getDotInfoForItem(info);
+ }
+
+ public LauncherOverlayManager getOverlayManager() {
+ return mOverlayManager;
+ }
+
+ public AllAppsTransitionController getAllAppsController() {
+ return mAllAppsController;
+ }
+
+ @Override
+ public DragLayer getDragLayer() {
+ return mDragLayer;
+ }
+
+ @Override
+ public ActivityAllAppsContainerView<Launcher> getAppsView() {
+ return mAppsView;
+ }
+
+ public Workspace<?> getWorkspace() {
+ return mWorkspace;
+ }
+
+ public Hotseat getHotseat() {
+ return mHotseat;
+ }
+
+ public <T extends View> T getOverviewPanel() {
+ return (T) mOverviewPanel;
+ }
+
+ public DropTargetBar getDropTargetBar() {
+ return mDropTargetBar;
+ }
+
+ @Override
+ public ScrimView getScrimView() {
+ return mScrimView;
+ }
+
+ public LauncherWidgetHolder getAppWidgetHolder() {
+ return mAppWidgetHolder;
+ }
+
+ public LauncherModel getModel() {
+ return mModel;
+ }
+
+ /**
+ * Returns the ModelWriter writer, make sure to call the function every time you want to use it.
+ */
+ public ModelWriter getModelWriter() {
+ return mModelWriter;
+ }
+
+ public SharedPreferences getSharedPrefs() {
+ return mSharedPrefs;
+ }
+
+ public int getOrientation() {
+ return mOldConfig.orientation;
+ }
+
+ /**
+ * Returns the CellLayout of the specified container at the specified screen.
+ *
+ * @param screenId must be presenterPos and not modelPos.
+ */
+ public CellLayout getCellLayout(int container, int screenId) {
+ return (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)
+ ? mHotseat : mWorkspace.getScreenWithId(screenId);
+ }
+
+ @Override
+ public StringCache getStringCache() {
+ return mStringCache;
+ }
+
+ /**
+ * Returns target rectangle for anchoring a popup menu.
+ */
+ protected RectF getPopupTarget(float x, float y) {
+ float halfSize = getResources().getDimension(R.dimen.options_menu_thumb_size) / 2;
+ if (x < 0 || y < 0) {
+ x = mDragLayer.getWidth() / 2;
+ y = mDragLayer.getHeight() / 2;
+ }
+ return new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
+ }
+
+ public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
+ return Stream.of(APP_INFO, WIDGETS, INSTALL);
+ }
+
+ /**
+ * @see LauncherState#getOverviewScaleAndOffset(Launcher)
+ */
+ public float[] getNormalOverviewScaleAndOffset() {
+ return new float[] {NO_SCALE, NO_OFFSET};
}
/**
@@ -3437,10 +3359,35 @@
// Overridden
}
+ public boolean getIsFirstPagePinnedItemEnabled() {
+ return mIsFirstPagePinnedItemEnabled;
+ }
+
/**
* Returns the animation coordinator for playing one-off animations
*/
public CannedAnimationCoordinator getAnimationCoordinator() {
return mAnimationCoordinator;
}
-}
+
+ @Override
+ public View.OnLongClickListener getAllAppsItemLongClickListener() {
+ return ItemLongClickListener.INSTANCE_ALL_APPS;
+ }
+
+ @Override
+ public StatsLogManager getStatsLogManager() {
+ return super.getStatsLogManager().withDefaultInstanceId(mAllAppsSessionLogId);
+ }
+
+ /**
+ * Returns the current popup for testing, if any.
+ */
+ @VisibleForTesting
+ @Nullable
+ public ArrowPopup<?> getOptionsPopup() {
+ return findViewById(R.id.popup_container);
+ }
+
+ // End of Getters and Setters
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 9db8c82..34bfdb7 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -21,6 +21,8 @@
import static com.android.launcher3.LauncherPrefs.ICON_STATE;
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
+import static com.android.launcher3.model.LoaderTask.SMARTSPACE_ON_HOME_SCREEN;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@@ -62,8 +64,6 @@
public class LauncherAppState implements SafeCloseable {
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
- public static final String KEY_ICON_STATE = "pref_icon_shape_path";
- public static final String KEY_ALL_APPS_OVERVIEW_THRESHOLD = "pref_all_apps_overview_threshold";
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<LauncherAppState> INSTANCE =
@@ -123,6 +123,23 @@
.addUserEventListener(mModel::onUserEvent);
mOnTerminateCallback.add(userChangeListener::close);
+ if (ENABLE_SMARTSPACE_REMOVAL.get()) {
+ OnSharedPreferenceChangeListener firstPagePinnedItemListener =
+ new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(
+ SharedPreferences sharedPreferences, String key) {
+ if (SMARTSPACE_ON_HOME_SCREEN.equals(key)) {
+ mModel.forceReload();
+ }
+ }
+ };
+ LauncherPrefs.getPrefs(mContext).registerOnSharedPreferenceChangeListener(
+ firstPagePinnedItemListener);
+ mOnTerminateCallback.add(() -> LauncherPrefs.getPrefs(mContext)
+ .unregisterOnSharedPreferenceChangeListener(firstPagePinnedItemListener));
+ }
+
LockedUserState.get(context).runOnUserUnlocked(() -> {
CustomWidgetManager cwm = CustomWidgetManager.INSTANCE.get(mContext);
cwm.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/src/com/android/launcher3/LauncherApplication.java
similarity index 68%
copy from src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
copy to src/com/android/launcher3/LauncherApplication.java
index 68843f2..40873be 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/LauncherApplication.java
@@ -13,10 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.uioverrides.flags;
+package com.android.launcher3;
+
+import android.app.Application;
/**
- * Place holder class for developer options.
+ * Main application class for Launcher
*/
-public class DeveloperOptionsFragment {
+public class LauncherApplication extends Application {
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ MainProcessInitializer.initialize(this);
+ }
}
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
deleted file mode 100644
index 0e529bd..0000000
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.launcher3;
-
-import android.os.Bundle;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * LauncherCallbacks is an interface used to extend the Launcher activity. It includes many hooks
- * in order to add additional functionality. Some of these are very general, and give extending
- * classes the ability to react to Activity life-cycle or specific user interactions. Others
- * are more specific and relate to replacing parts of the application, for example, the search
- * interface or the wallpaper picker.
- */
-public interface LauncherCallbacks {
-
- /*
- * Activity life-cycle methods. These methods are triggered after
- * the code in the corresponding Launcher method is executed.
- */
- void onCreate(Bundle savedInstanceState);
- void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
- void onHomeIntent(boolean internalStateHandled);
-
- /**
- * Starts a search with {@param initialQuery}. Return false if search was not started.
- */
- boolean startSearch(
- String initialQuery, boolean selectInitialQuery, Bundle appSearchData);
-}
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 427eaa3..aa06089 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -21,9 +21,11 @@
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.util.Log
import androidx.annotation.VisibleForTesting
+import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
import com.android.launcher3.LauncherFiles.SHARED_PREFERENCES_KEY
-import com.android.launcher3.allapps.WorkProfileManager
+import com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE
+import com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS
import com.android.launcher3.model.DeviceGridState
import com.android.launcher3.pm.InstallSessionHelper
import com.android.launcher3.provider.RestoreDbTask
@@ -60,7 +62,11 @@
)
private fun chooseSharedPreferences(item: Item): SharedPreferences =
- if (isBootAwareStartupDataEnabled && item.isBootAware && isStartupDataMigrated)
+ if (
+ (moveStartupDataToDeviceProtectedStorageIsEnabled &&
+ item.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+ isStartupDataMigrated) || item.encryptionType == EncryptionType.DEVICE_PROTECTED
+ )
bootAwarePrefs
else item.encryptedPrefs
@@ -134,13 +140,20 @@
private fun prepareToPutValues(
updates: Array<out Pair<Item, Any>>
): List<SharedPreferences.Editor> {
- val updatesPerPrefFile = updates.groupBy { it.first.encryptedPrefs }.toMutableMap()
+ val updatesPerPrefFile =
+ updates
+ .filter { it.first.encryptionType != EncryptionType.DEVICE_PROTECTED }
+ .groupBy { it.first.encryptedPrefs }
+ .toMutableMap()
- if (isBootAwareStartupDataEnabled) {
- val bootAwareUpdates = updates.filter { it.first.isBootAware }
- if (bootAwareUpdates.isNotEmpty()) {
- updatesPerPrefFile[bootAwarePrefs] = bootAwareUpdates
+ val bootAwareUpdates =
+ updates.filter {
+ (it.first.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+ moveStartupDataToDeviceProtectedStorageIsEnabled) ||
+ it.first.encryptionType == EncryptionType.DEVICE_PROTECTED
}
+ if (bootAwareUpdates.isNotEmpty()) {
+ updatesPerPrefFile[bootAwarePrefs] = bootAwareUpdates
}
return updatesPerPrefFile.map { prefToItemValueList ->
@@ -233,13 +246,20 @@
* .apply() or .commit()
*/
private fun prepareToRemove(items: Array<out Item>): List<SharedPreferences.Editor> {
- val itemsPerFile = items.groupBy { it.encryptedPrefs }.toMutableMap()
+ val itemsPerFile =
+ items
+ .filter { it.encryptionType != EncryptionType.DEVICE_PROTECTED }
+ .groupBy { it.encryptedPrefs }
+ .toMutableMap()
- if (isBootAwareStartupDataEnabled) {
- val bootAwareUpdates = items.filter { it.isBootAware }
- if (bootAwareUpdates.isNotEmpty()) {
- itemsPerFile[bootAwarePrefs] = bootAwareUpdates
+ val bootAwareUpdates =
+ items.filter {
+ (it.encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+ moveStartupDataToDeviceProtectedStorageIsEnabled) ||
+ it.encryptionType == EncryptionType.DEVICE_PROTECTED
}
+ if (bootAwareUpdates.isNotEmpty()) {
+ itemsPerFile[bootAwarePrefs] = bootAwareUpdates
}
return itemsPerFile.map { (prefs, items) ->
@@ -250,7 +270,7 @@
}
fun migrateStartupDataToDeviceProtectedStorage() {
- if (!isBootAwareStartupDataEnabled) return
+ if (!moveStartupDataToDeviceProtectedStorageIsEnabled) return
Log.d(
TAG,
@@ -259,7 +279,7 @@
)
with(bootAwarePrefs.edit()) {
- BOOT_AWARE_ITEMS.forEach { putValue(it, get(it)) }
+ ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.forEach { putValue(it, get(it)) }
putBoolean(IS_STARTUP_DATA_MIGRATED.sharedPrefKey, true)
apply()
}
@@ -274,27 +294,109 @@
@JvmStatic fun get(context: Context): LauncherPrefs = INSTANCE.get(context)
const val TASKBAR_PINNING_KEY = "TASKBAR_PINNING_KEY"
- @JvmField val ICON_STATE = nonRestorableItem(LauncherAppState.KEY_ICON_STATE, "", true)
+ const val SHOULD_SHOW_SMARTSPACE_KEY = "SHOULD_SHOW_SMARTSPACE_KEY"
+ @JvmField
+ val ICON_STATE =
+ nonRestorableItem(
+ "pref_icon_shape_path",
+ "",
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
@JvmField
val ALL_APPS_OVERVIEW_THRESHOLD =
- nonRestorableItem(LauncherAppState.KEY_ALL_APPS_OVERVIEW_THRESHOLD, 180, true)
- @JvmField val THEMED_ICONS = backedUpItem(Themes.KEY_THEMED_ICONS, false, true)
+ nonRestorableItem(
+ "pref_all_apps_overview_threshold",
+ 180,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_slop_percentage",
+ LPNH_SLOP_PERCENTAGE.get(),
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_timeout_ms",
+ LPNH_TIMEOUT_MS.get(),
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_haptic_hint_start_scale_percent",
+ 0,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_haptic_hint_end_scale_percent",
+ 100,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_haptic_hint_scale_exponent",
+ 1,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS =
+ nonRestorableItem(
+ "pref_long_press_nav_handle_haptic_hint_iterations",
+ 50,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val THEMED_ICONS =
+ backedUpItem(Themes.KEY_THEMED_ICONS, false, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
@JvmField val PROMISE_ICON_IDS = backedUpItem(InstallSessionHelper.PROMISE_ICON_IDS, "")
- @JvmField val WORK_EDU_STEP = backedUpItem(WorkProfileManager.KEY_WORK_EDU_STEP, 0)
- @JvmField val WORKSPACE_SIZE = backedUpItem(DeviceGridState.KEY_WORKSPACE_SIZE, "", true)
- @JvmField val HOTSEAT_COUNT = backedUpItem(DeviceGridState.KEY_HOTSEAT_COUNT, -1, true)
- @JvmField val TASKBAR_PINNING = backedUpItem(TASKBAR_PINNING_KEY, false)
+ @JvmField val WORK_EDU_STEP = backedUpItem("showed_work_profile_edu", 0)
+ @JvmField
+ val WORKSPACE_SIZE =
+ backedUpItem(
+ DeviceGridState.KEY_WORKSPACE_SIZE,
+ "",
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val HOTSEAT_COUNT =
+ backedUpItem(
+ DeviceGridState.KEY_HOTSEAT_COUNT,
+ -1,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val TASKBAR_PINNING =
+ backedUpItem(TASKBAR_PINNING_KEY, false, EncryptionType.DEVICE_PROTECTED)
@JvmField
val DEVICE_TYPE =
- backedUpItem(DeviceGridState.KEY_DEVICE_TYPE, InvariantDeviceProfile.TYPE_PHONE, true)
- @JvmField val DB_FILE = backedUpItem(DeviceGridState.KEY_DB_FILE, "", true)
+ backedUpItem(
+ DeviceGridState.KEY_DEVICE_TYPE,
+ InvariantDeviceProfile.TYPE_PHONE,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
+ @JvmField
+ val DB_FILE =
+ backedUpItem(DeviceGridState.KEY_DB_FILE, "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+ @JvmField
+ val SHOULD_SHOW_SMARTSPACE =
+ backedUpItem(
+ SHOULD_SHOW_SMARTSPACE_KEY,
+ WIDGET_ON_FIRST_SCREEN,
+ EncryptionType.DEVICE_PROTECTED
+ )
@JvmField
val RESTORE_DEVICE =
backedUpItem(
RestoreDbTask.RESTORED_DEVICE_TYPE,
InvariantDeviceProfile.TYPE_PHONE,
- true
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField val APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_IDS, "")
@JvmField val OLD_APP_WIDGET_IDS = backedUpItem(RestoreDbTask.APPWIDGET_OLD_IDS, "")
@@ -304,7 +406,7 @@
"idp_grid_name",
isBackedUp = true,
defaultValue = null,
- isBootAware = true,
+ encryptionType = EncryptionType.MOVE_TO_DEVICE_PROTECTED,
type = String::class.java
)
@JvmField
@@ -318,41 +420,49 @@
"is_startup_data_boot_aware",
isBackedUp = false,
defaultValue = false,
- isBootAware = true
+ encryptionType = EncryptionType.DEVICE_PROTECTED
)
- @VisibleForTesting
+ // Preferences for widget configurations
+ @JvmField
+ val RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
+ backedUpItem("launcher.reconfigurable_widget_education_tip_seen", false)
+ @JvmField
+ val WIDGETS_EDUCATION_DIALOG_SEEN =
+ backedUpItem("launcher.widgets_education_dialog_seen", false)
+ @JvmField
+ val WIDGETS_EDUCATION_TIP_SEEN = backedUpItem("launcher.widgets_education_tip_seen", false)
+
@JvmStatic
fun <T> backedUpItem(
sharedPrefKey: String,
defaultValue: T,
- isBootAware: Boolean = false
+ encryptionType: EncryptionType = EncryptionType.ENCRYPTED
): ConstantItem<T> =
- ConstantItem(sharedPrefKey, isBackedUp = true, defaultValue, isBootAware)
+ ConstantItem(sharedPrefKey, isBackedUp = true, defaultValue, encryptionType)
@JvmStatic
fun <T> backedUpItem(
sharedPrefKey: String,
type: Class<out T>,
- isBootAware: Boolean = false,
+ encryptionType: EncryptionType = EncryptionType.ENCRYPTED,
defaultValueFromContext: (c: Context) -> T
): ContextualItem<T> =
ContextualItem(
sharedPrefKey,
isBackedUp = true,
defaultValueFromContext,
- isBootAware,
+ encryptionType,
type
)
- @VisibleForTesting
@JvmStatic
fun <T> nonRestorableItem(
sharedPrefKey: String,
defaultValue: T,
- isBootAware: Boolean = false
+ encryptionType: EncryptionType = EncryptionType.ENCRYPTED
): ConstantItem<T> =
- ConstantItem(sharedPrefKey, isBackedUp = false, defaultValue, isBootAware)
+ ConstantItem(sharedPrefKey, isBackedUp = false, defaultValue, encryptionType)
@Deprecated("Don't use shared preferences directly. Use other LauncherPref methods.")
@JvmStatic
@@ -376,17 +486,17 @@
}
}
-// This is hard-coded to false for now until it is time to release this optimization. It is only
-// a var because the unit tests are setting this to true so they can run.
-@VisibleForTesting var isBootAwareStartupDataEnabled: Boolean = false
+// It is a var because the unit tests are setting this to true so they can run.
+var moveStartupDataToDeviceProtectedStorageIsEnabled: Boolean =
+ com.android.launcher3.config.FeatureFlags.MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE.get()
-private val BOOT_AWARE_ITEMS: MutableSet<ConstantItem<*>> = mutableSetOf()
+private val ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE: MutableSet<ConstantItem<*>> = mutableSetOf()
abstract class Item {
abstract val sharedPrefKey: String
abstract val isBackedUp: Boolean
abstract val type: Class<*>
- abstract val isBootAware: Boolean
+ abstract val encryptionType: EncryptionType
val sharedPrefFile: String
get() = if (isBackedUp) SHARED_PREFERENCES_KEY else DEVICE_PREFERENCES_KEY
@@ -397,22 +507,27 @@
override val sharedPrefKey: String,
override val isBackedUp: Boolean,
val defaultValue: T,
- override val isBootAware: Boolean,
+ override val encryptionType: EncryptionType,
// The default value can be null. If so, the type needs to be explicitly stated, or else NPE
override val type: Class<out T> = defaultValue!!::class.java
) : Item() {
init {
- if (isBootAware && isBootAwareStartupDataEnabled) {
- BOOT_AWARE_ITEMS.add(this)
+ if (
+ encryptionType == EncryptionType.MOVE_TO_DEVICE_PROTECTED &&
+ moveStartupDataToDeviceProtectedStorageIsEnabled
+ ) {
+ ITEMS_TO_MOVE_TO_DEVICE_PROTECTED_STORAGE.add(this)
}
}
+
+ fun get(c: Context): T = LauncherPrefs.get(c).get(this)
}
data class ContextualItem<T>(
override val sharedPrefKey: String,
override val isBackedUp: Boolean,
private val defaultSupplier: (c: Context) -> T,
- override val isBootAware: Boolean,
+ override val encryptionType: EncryptionType,
override val type: Class<out T>
) : Item() {
private var default: T? = null
@@ -423,4 +538,12 @@
}
return default!!
}
+
+ fun get(c: Context): T = LauncherPrefs.get(c).get(this)
+}
+
+enum class EncryptionType {
+ ENCRYPTED,
+ DEVICE_PROTECTED,
+ MOVE_TO_DEVICE_PROTECTED
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 440e146..4e0ba62 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -33,7 +33,6 @@
import android.util.Log;
import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.ModelDbController;
import com.android.launcher3.widget.LauncherWidgetHolder;
@@ -44,8 +43,6 @@
public class LauncherProvider extends ContentProvider {
private static final String TAG = "LauncherProvider";
- public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".settings";
-
/**
* $ adb shell dumpsys activity provider com.android.launcher3
*/
@@ -60,13 +57,6 @@
@Override
public boolean onCreate() {
- if (FeatureFlags.IS_STUDIO_BUILD) {
- Log.d(TAG, "Launcher process started");
- }
-
- // The content provider exists for the entire duration of the launcher main process and
- // is the first component to get created.
- MainProcessInitializer.initialize(getContext().getApplicationContext());
return true;
}
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 105d5f3..34ebaf2 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -19,8 +19,13 @@
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.model.data.ItemInfo;
+import java.util.LinkedHashMap;
+import java.util.stream.Collectors;
+
/**
* Settings related utilities.
*/
@@ -289,28 +294,51 @@
public static void addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional,
String tableName) {
- String ifNotExists = optional ? " IF NOT EXISTS " : "";
- db.execSQL("CREATE TABLE " + ifNotExists + tableName + " (" +
- "_id INTEGER PRIMARY KEY," +
- "title TEXT," +
- "intent TEXT," +
- "container INTEGER," +
- "screen INTEGER," +
- "cellX INTEGER," +
- "cellY INTEGER," +
- "spanX INTEGER," +
- "spanY INTEGER," +
- "itemType INTEGER," +
- "appWidgetId INTEGER NOT NULL DEFAULT -1," +
- "icon BLOB," +
- "appWidgetProvider TEXT," +
- "modified INTEGER NOT NULL DEFAULT 0," +
- "restored INTEGER NOT NULL DEFAULT 0," +
- "profileId INTEGER DEFAULT " + myProfileId + "," +
- "rank INTEGER NOT NULL DEFAULT 0," +
- "options INTEGER NOT NULL DEFAULT 0," +
- APPWIDGET_SOURCE + " INTEGER NOT NULL DEFAULT " + CONTAINER_UNKNOWN +
- ");");
+ db.execSQL("CREATE TABLE " + (optional ? " IF NOT EXISTS " : "") + tableName + " ("
+ + getJoinedColumnsToTypes(myProfileId) + ");");
+ }
+
+ // LinkedHashMap maintains Order of Insertion
+ @NonNull
+ private static LinkedHashMap<String, String> getColumnsToTypes(long profileId) {
+ final LinkedHashMap<String, String> columnsToTypes = new LinkedHashMap<>();
+ columnsToTypes.put(_ID, "INTEGER PRIMARY KEY");
+ columnsToTypes.put(TITLE, "TEXT");
+ columnsToTypes.put(INTENT, "TEXT");
+ columnsToTypes.put(CONTAINER, "INTEGER");
+ columnsToTypes.put(SCREEN, "INTEGER");
+ columnsToTypes.put(CELLX, "INTEGER");
+ columnsToTypes.put(CELLY, "INTEGER");
+ columnsToTypes.put(SPANX, "INTEGER");
+ columnsToTypes.put(SPANY, "INTEGER");
+ columnsToTypes.put(ITEM_TYPE, "INTEGER");
+ columnsToTypes.put(APPWIDGET_ID, "INTEGER NOT NULL DEFAULT -1");
+ columnsToTypes.put(ICON, "BLOB");
+ columnsToTypes.put(APPWIDGET_PROVIDER, "TEXT");
+ columnsToTypes.put(MODIFIED, "INTEGER NOT NULL DEFAULT 0");
+ columnsToTypes.put(RESTORED, "INTEGER NOT NULL DEFAULT 0");
+ columnsToTypes.put(PROFILE_ID, "INTEGER DEFAULT " + profileId);
+ columnsToTypes.put(RANK, "INTEGER NOT NULL DEFAULT 0");
+ columnsToTypes.put(OPTIONS, "INTEGER NOT NULL DEFAULT 0");
+ columnsToTypes.put(APPWIDGET_SOURCE, "INTEGER NOT NULL DEFAULT -1");
+ return columnsToTypes;
+ }
+
+ private static String getJoinedColumnsToTypes(long profileId) {
+ return getColumnsToTypes(profileId)
+ .entrySet()
+ .stream()
+ .map(it -> it.getKey() + " " + it.getValue())
+ .collect(Collectors.joining(", "));
+ }
+
+ /**
+ * Returns an ordered list of columns in the Favorites table as one string, ready to use in
+ * an SQL statement.
+ */
+ @NonNull
+ public static String getColumns(long profileId) {
+ return String.join(", ", getColumnsToTypes(profileId).keySet());
}
}
diff --git a/src/com/android/launcher3/ModelCallbacks.kt b/src/com/android/launcher3/ModelCallbacks.kt
new file mode 100644
index 0000000..8304e96
--- /dev/null
+++ b/src/com/android/launcher3/ModelCallbacks.kt
@@ -0,0 +1,138 @@
+package com.android.launcher3
+
+import androidx.annotation.UiThread
+import com.android.launcher3.model.BgDataModel
+import com.android.launcher3.model.data.AppInfo
+import com.android.launcher3.model.data.ItemInfo
+import com.android.launcher3.model.data.LauncherAppWidgetInfo
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.popup.PopupContainerWithArrow
+import com.android.launcher3.util.ComponentKey
+import com.android.launcher3.util.IntArray as LIntArray
+import com.android.launcher3.util.IntSet as LIntSet
+import com.android.launcher3.util.PackageUserKey
+import com.android.launcher3.util.Preconditions
+import com.android.launcher3.widget.model.WidgetsListBaseEntry
+import java.util.function.Predicate
+
+class ModelCallbacks(private var launcher: Launcher) : BgDataModel.Callbacks {
+
+ var synchronouslyBoundPages = LIntSet()
+ var pagesToBindSynchronously = LIntSet()
+
+ override fun preAddApps() {
+ // If there's an undo snackbar, force it to complete to ensure empty screens are removed
+ // before trying to add new items.
+ launcher.modelWriter.commitDelete()
+ val snackbar =
+ AbstractFloatingView.getOpenView<AbstractFloatingView>(
+ launcher,
+ AbstractFloatingView.TYPE_SNACKBAR
+ )
+ snackbar?.post { snackbar.close(true) }
+ }
+
+ @UiThread
+ override fun bindAllApplications(
+ apps: Array<AppInfo?>?,
+ flags: Int,
+ packageUserKeytoUidMap: Map<PackageUserKey?, Int?>?
+ ) {
+ Preconditions.assertUIThread()
+ val hadWorkApps = launcher.appsView.shouldShowTabs()
+ launcher.appsView.appsStore.setApps(apps, flags, packageUserKeytoUidMap)
+ PopupContainerWithArrow.dismissInvalidPopup(launcher)
+ if (hadWorkApps != launcher.appsView.shouldShowTabs()) {
+ launcher.stateManager.goToState(LauncherState.NORMAL)
+ }
+ }
+
+ /**
+ * Copies LauncherModel's map of activities to shortcut counts to Launcher's. This is necessary
+ * because LauncherModel's map is updated in the background, while Launcher runs on the UI.
+ */
+ override fun bindDeepShortcutMap(deepShortcutMapCopy: HashMap<ComponentKey?, Int?>?) {
+ launcher.popupDataProvider.setDeepShortcutMap(deepShortcutMapCopy)
+ }
+
+ override fun bindIncrementalDownloadProgressUpdated(app: AppInfo?) {
+ launcher.appsView.appsStore.updateProgressBar(app)
+ }
+
+ override fun bindWidgetsRestored(widgets: ArrayList<LauncherAppWidgetInfo?>?) {
+ launcher.workspace.widgetsRestored(widgets)
+ }
+
+ /**
+ * Some shortcuts were updated in the background. Implementation of the method from
+ * LauncherModel.Callbacks.
+ *
+ * @param updated list of shortcuts which have changed.
+ */
+ override fun bindWorkspaceItemsChanged(updated: List<WorkspaceItemInfo?>) {
+ if (updated.isNotEmpty()) {
+ launcher.workspace.updateWorkspaceItems(updated, launcher)
+ PopupContainerWithArrow.dismissInvalidPopup(launcher)
+ }
+ }
+
+ /**
+ * Update the state of a package, typically related to install state. Implementation of the
+ * method from LauncherModel.Callbacks.
+ */
+ override fun bindRestoreItemsChange(updates: HashSet<ItemInfo?>?) {
+ launcher.workspace.updateRestoreItems(updates, launcher)
+ }
+
+ /**
+ * A package was uninstalled/updated. We take both the super set of packageNames in addition to
+ * specific applications to remove, the reason being that this can be called when a package is
+ * updated as well. In that scenario, we only remove specific components from the workspace and
+ * hotseat, where as package-removal should clear all items by package name.
+ */
+ override fun bindWorkspaceComponentsRemoved(matcher: Predicate<ItemInfo?>?) {
+ launcher.workspace.removeItemsByMatcher(matcher)
+ launcher.dragController.onAppsRemoved(matcher)
+ PopupContainerWithArrow.dismissInvalidPopup(launcher)
+ }
+
+ override fun bindAllWidgets(allWidgets: List<WidgetsListBaseEntry?>?) {
+ launcher.popupDataProvider.allWidgets = allWidgets
+ }
+
+ /** Returns the ids of the workspaces to bind. */
+ override fun getPagesToBindSynchronously(orderedScreenIds: LIntArray): LIntSet {
+ // If workspace binding is still in progress, getCurrentPageScreenIds won't be
+ // accurate, and we should use mSynchronouslyBoundPages that's set during initial binding.
+ val visibleIds =
+ when {
+ !pagesToBindSynchronously.isEmpty -> pagesToBindSynchronously
+ !launcher.isWorkspaceLoading -> launcher.workspace.currentPageScreenIds
+ else -> synchronouslyBoundPages
+ }
+ // Launcher IntArray has the same name as Kotlin IntArray
+ val result = LIntSet()
+ if (visibleIds.isEmpty) {
+ return result
+ }
+ val actualIds = orderedScreenIds.clone()
+ val firstId = visibleIds.first()
+ val pairId = launcher.workspace.getScreenPair(firstId)
+ // Double check that actual screenIds contains the visibleId, as empty screens are hidden
+ // in single panel.
+ if (actualIds.contains(firstId)) {
+ result.add(firstId)
+ if (launcher.deviceProfile.isTwoPanels && actualIds.contains(pairId)) {
+ result.add(pairId)
+ }
+ } else if (
+ LauncherAppState.getIDP(launcher).supportedProfiles.any(DeviceProfile::isTwoPanels) &&
+ actualIds.contains(pairId)
+ ) {
+ // Add the right panel if left panel is hidden when switching display, due to empty
+ // pages being hidden in single panel.
+ result.add(pairId)
+ }
+ return result
+ }
+}
diff --git a/src/com/android/launcher3/MultipageCellLayout.java b/src/com/android/launcher3/MultipageCellLayout.java
index 44a1414..4b5c9ef 100644
--- a/src/com/android/launcher3/MultipageCellLayout.java
+++ b/src/com/android/launcher3/MultipageCellLayout.java
@@ -26,6 +26,7 @@
import com.android.launcher3.celllayout.MulticellReorderAlgorithm;
import com.android.launcher3.util.CellAndSpan;
import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.MultiTranslateDelegate;
/**
* CellLayout that simulates a split in the middle for use in foldable devices.
@@ -139,18 +140,59 @@
@Override
protected void onDraw(Canvas canvas) {
+ float animatedWorkspaceMargin = mSpaceBetweenCellLayoutsPx * mSpringLoadedProgress;
if (mLeftBackground.getAlpha() > 0) {
+ canvas.save();
+ canvas.translate(-animatedWorkspaceMargin, 0);
mLeftBackground.setState(mBackground.getState());
mLeftBackground.draw(canvas);
+ canvas.restore();
}
if (mRightBackground.getAlpha() > 0) {
+ canvas.save();
+ canvas.translate(animatedWorkspaceMargin, 0);
mRightBackground.setState(mBackground.getState());
mRightBackground.draw(canvas);
+ canvas.restore();
}
-
super.onDraw(canvas);
}
+ private void updateMarginBetweenCellLayouts() {
+ for (int i = 0; i < mShortcutsAndWidgets.getChildCount(); i++) {
+ View workspaceItem = mShortcutsAndWidgets.getChildAt(i);
+ if (!(workspaceItem instanceof Reorderable)) {
+ continue;
+ }
+ CellLayoutLayoutParams params =
+ (CellLayoutLayoutParams) workspaceItem.getLayoutParams();
+ ((Reorderable) workspaceItem).getTranslateDelegate().setTranslation(
+ MultiTranslateDelegate.INDEX_CELLAYOUT_MULTIPAGE_SPACING,
+ getMarginForGivenCellParams(params),
+ 0
+ );
+
+ }
+ }
+
+ @Override
+ protected float getMarginForGivenCellParams(CellLayoutLayoutParams params) {
+ float margin = mSpaceBetweenCellLayoutsPx * mSpringLoadedProgress;
+ return params.getCellX() >= mCountX / 2 ? margin : -margin;
+ }
+
+ @Override
+ public void setSpringLoadedProgress(float progress) {
+ super.setSpringLoadedProgress(progress);
+ updateMarginBetweenCellLayouts();
+ }
+
+ @Override
+ public void setSpaceBetweenCellLayoutsPx(int spaceBetweenCellLayoutsPx) {
+ super.setSpaceBetweenCellLayoutsPx(spaceBetweenCellLayoutsPx);
+ updateMarginBetweenCellLayouts();
+ }
+
@Override
protected void updateBgAlpha() {
mLeftBackground.setAlpha((int) (mSpringLoadedProgress * 255));
@@ -161,8 +203,9 @@
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
Rect rect = mBackground.getBounds();
- mLeftBackground.setBounds(rect.left, rect.top, rect.right / 2 - 20, rect.bottom);
- mRightBackground.setBounds(rect.right / 2 + 20, rect.top, rect.right, rect.bottom);
+ int middlePointInPixels = rect.centerX();
+ mLeftBackground.setBounds(rect.left, rect.top, middlePointInPixels, rect.bottom);
+ mRightBackground.setBounds(middlePointInPixels, rect.top, rect.right, rect.bottom);
}
public void setCountX(int countX) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 4b4a4a5..f355ae7 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -19,6 +19,7 @@
import static com.android.app.animation.Interpolators.SCROLL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
+import static com.android.launcher3.testing.shared.TestProtocol.SCROLL_FINISHED_MESSAGE;
import static com.android.launcher3.touch.OverScroll.OVERSCROLL_DAMP_FACTOR;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_BY;
import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_TO;
@@ -492,7 +493,8 @@
*/
protected void onPageEndTransition() {
mCurrentPageScrollDiff = 0;
- AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ SCROLL_FINISHED_MESSAGE);
AccessibilityManagerCompat.sendCustomAccessibilityEvent(getPageAt(mCurrentPage),
AccessibilityEvent.TYPE_VIEW_FOCUSED, null);
if (mOnPageTransitionEndCallback != null) {
@@ -1571,7 +1573,9 @@
@Override
public void requestChildFocus(View child, View focused) {
super.requestChildFocus(child, focused);
-
+ if (!shouldHandleRequestChildFocus()) {
+ return;
+ }
// In case the device is controlled by a controller, mCurrentPage isn't updated properly
// which results in incorrect navigation
int nextPage = getNextPage();
@@ -1585,6 +1589,10 @@
}
}
+ protected boolean shouldHandleRequestChildFocus() {
+ return true;
+ }
+
public int getDestinationPage() {
return getDestinationPage(mOrientationHandler.getPrimaryScroll(this));
}
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index f0fea61..b22b690 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.CellLayout.FOLDER;
import static com.android.launcher3.CellLayout.HOTSEAT;
import static com.android.launcher3.CellLayout.WORKSPACE;
+import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_BUBBLE_ADJUSTMENT_ANIM;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_WIDGET_CENTERING;
import android.app.WallpaperManager;
@@ -33,11 +34,14 @@
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.NavigableAppWidgetHostView;
public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.FolderIconParent {
@@ -61,6 +65,9 @@
private final ActivityContext mActivity;
private boolean mInvertIfRtl = false;
+ @Nullable
+ private TranslationProvider mTranslationProvider = null;
+
public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
super(context);
mActivity = ActivityContext.lookupContext(context);
@@ -217,7 +224,27 @@
int childLeft = lp.x;
int childTop = lp.y;
+
+ // We want to get the layout position of the widget, but layout() is a final function in
+ // ViewGroup which makes it impossible to be overridden. Overriding onLayout() will have no
+ // effect since it will not be called when the transition is enabled. The only possible
+ // solution here seems to be sending the positions when CellLayout is laying out the views
+ if (child instanceof LauncherAppWidgetHostView widgetView
+ && widgetView.getCellChildViewPreLayoutListener() != null) {
+ widgetView.getCellChildViewPreLayoutListener().notifyBoundChangeOnPreLayout(child,
+ childLeft, childTop, childLeft + lp.width, childTop + lp.height);
+ }
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
+ if (mTranslationProvider != null) {
+ final float tx = mTranslationProvider.getTranslationX(child);
+ if (child instanceof Reorderable) {
+ ((Reorderable) child).getTranslateDelegate()
+ .getTranslationX(INDEX_BUBBLE_ADJUSTMENT_ANIM)
+ .setValue(tx);
+ } else {
+ child.setTranslationX(tx);
+ }
+ }
if (lp.dropped) {
lp.dropped = false;
@@ -287,4 +314,13 @@
cl.clearFolderLeaveBehind();
}
}
+
+ void setTranslationProvider(@Nullable TranslationProvider provider) {
+ mTranslationProvider = provider;
+ }
+
+ /** Provides translation values to apply when laying out child views. */
+ interface TranslationProvider {
+ float getTranslationX(View child);
+ }
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index e8c6ff9..8ba6d2c 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,13 +16,14 @@
package com.android.launcher3;
+import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFraction;
+
import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
-import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ICON_BADGED;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
-import android.annotation.TargetApi;
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.Person;
@@ -33,6 +34,9 @@
import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
@@ -43,22 +47,23 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Message;
-import android.os.Process;
import android.os.TransactionTooLargeException;
-import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.TtsSpan;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
@@ -68,15 +73,21 @@
import androidx.annotation.ChecksSdkIntAtLeast;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.TintedDrawableSpan;
+import com.android.launcher3.icons.BaseIconFactory;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.testing.shared.ResourceUtils;
@@ -158,11 +169,6 @@
return nightMode == Configuration.UI_MODE_NIGHT_YES;
}
- public static boolean isDevelopersOptionsEnabled(Context context) {
- return Settings.Global.getInt(context.getApplicationContext().getContentResolver(),
- Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
- }
-
private static boolean sIsRunningInTestHarness = ActivityManager.isRunningInTestHarness();
public static boolean isRunningInTestHarness() {
@@ -571,103 +577,116 @@
}
/**
- * Returns the full drawable for info without any flattening or pre-processing.
+ * Returns the full drawable for info as multiple layers of AdaptiveIconDrawable. The second
+ * drawable in the Pair is the badge used with the icon.
*
- * @param shouldThemeIcon If true, will theme icons when applicable
- * @param outObj this is set to the internal data associated with {@code info},
- * eg {@link LauncherActivityInfo} or {@link ShortcutInfo}.
+ * @param useTheme If true, will theme icons when applicable
*/
- @TargetApi(Build.VERSION_CODES.TIRAMISU)
- public static Drawable getFullDrawable(Context context, ItemInfo info, int width, int height,
- boolean shouldThemeIcon, Object[] outObj, boolean[] outIsIconThemed) {
- Drawable icon = loadFullDrawableWithoutTheme(context, info, width, height, outObj);
- if (ATLEAST_T && icon instanceof AdaptiveIconDrawable && shouldThemeIcon) {
- AdaptiveIconDrawable aid = (AdaptiveIconDrawable) icon.mutate();
- Drawable mono = aid.getMonochrome();
- if (mono != null && Themes.isThemedIconEnabled(context)) {
- outIsIconThemed[0] = true;
- int[] colors = ThemedIconDrawable.getColors(context);
- mono = mono.mutate();
- mono.setTint(colors[1]);
- return new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
- }
- }
- return icon;
- }
-
- private static Drawable loadFullDrawableWithoutTheme(Context context, ItemInfo info,
- int width, int height, Object[] outObj) {
- ActivityContext activity = ActivityContext.lookupContext(context);
+ @SuppressLint("UseCompatLoadingForDrawables")
+ @Nullable
+ @WorkerThread
+ public static <T extends Context & ActivityContext> Pair<AdaptiveIconDrawable, Drawable>
+ getFullDrawable(T context, ItemInfo info, int width, int height, boolean useTheme) {
+ useTheme &= Themes.isThemedIconEnabled(context);
LauncherAppState appState = LauncherAppState.getInstance(context);
+ Drawable mainIcon = null;
+
+ Drawable badge = null;
+ if ((info instanceof ItemInfoWithIcon iiwi) && !iiwi.usingLowResIcon()) {
+ badge = iiwi.bitmap.getBadgeDrawable(context, useTheme);
+ }
+
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
((PendingAddShortcutInfo) info).getActivityInfo(context);
- outObj[0] = activityInfo;
- return activityInfo.getFullResIcon(appState.getIconCache());
- }
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+ mainIcon = activityInfo.getFullResIcon(appState.getIconCache());
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
LauncherActivityInfo activityInfo = context.getSystemService(LauncherApps.class)
.resolveActivity(info.getIntent(), info.user);
- outObj[0] = activityInfo;
- return activityInfo == null ? null : LauncherAppState.getInstance(context)
- .getIconProvider().getIcon(
- activityInfo, activity.getDeviceProfile().inv.fillResIconDpi);
+ if (activityInfo == null) {
+ return null;
+ }
+ mainIcon = appState.getIconProvider().getIcon(
+ activityInfo, appState.getInvariantDeviceProfile().fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- List<ShortcutInfo> si = ShortcutKey.fromItemInfo(info)
+ List<ShortcutInfo> siList = ShortcutKey.fromItemInfo(info)
.buildRequest(context)
.query(ShortcutRequest.ALL);
- if (si.isEmpty()) {
+ if (siList.isEmpty()) {
return null;
} else {
- outObj[0] = si.get(0);
- return ShortcutCachingLogic.getIcon(context, si.get(0),
+ ShortcutInfo si = siList.get(0);
+ mainIcon = ShortcutCachingLogic.getIcon(context, si,
appState.getInvariantDeviceProfile().fillResIconDpi);
+ // Only fetch badge if the icon is on workspace
+ if (info.id != ItemInfo.NO_ID && badge == null) {
+ badge = appState.getIconCache().getShortcutInfoBadge(si)
+ .newIcon(context, FLAG_THEMED);
+ }
}
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
FolderAdaptiveIcon icon = FolderAdaptiveIcon.createFolderAdaptiveIcon(
- activity, info.id, new Point(width, height));
+ context, info.id, new Point(width, height));
if (icon == null) {
return null;
}
- outObj[0] = icon;
- return icon;
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION
- && info instanceof ItemInfoWithIcon) {
- return ((ItemInfoWithIcon) info).bitmap.newIcon(context);
- } else {
+ mainIcon = icon;
+ badge = icon.getBadge();
+ }
+
+ if (mainIcon == null) {
return null;
}
- }
-
- /**
- * For apps icons and shortcut icons that have badges, this method creates a drawable that can
- * later on be rendered on top of the layers for the badges. For app icons, work profile badges
- * can only be applied. For deep shortcuts, when dragged from the pop up container, there's no
- * badge. When dragged from workspace or folder, it may contain app AND/OR work profile badge
- **/
- @TargetApi(Build.VERSION_CODES.O)
- public static Drawable getBadge(Context context, ItemInfo info, Object obj,
- boolean isIconThemed) {
- LauncherAppState appState = LauncherAppState.getInstance(context);
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- boolean iconBadged = (info instanceof ItemInfoWithIcon)
- && (((ItemInfoWithIcon) info).runtimeStatusFlags & FLAG_ICON_BADGED) > 0;
- if ((info.id == ItemInfo.NO_ID && !iconBadged)
- || !(obj instanceof ShortcutInfo)) {
- // The item is not yet added on home screen.
- return new ColorDrawable(Color.TRANSPARENT);
- }
- ShortcutInfo si = (ShortcutInfo) obj;
- return LauncherAppState.getInstance(appState.getContext())
- .getIconCache().getShortcutInfoBadge(si).newIcon(context, FLAG_THEMED);
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- return ((FolderAdaptiveIcon) obj).getBadge();
+ AdaptiveIconDrawable result;
+ if (mainIcon instanceof AdaptiveIconDrawable aid) {
+ result = aid;
} else {
- return Process.myUserHandle().equals(info.user)
- ? new ColorDrawable(Color.TRANSPARENT)
- : context.getDrawable(isIconThemed
- ? R.drawable.ic_work_app_badge_themed : R.drawable.ic_work_app_badge);
+ // Wrap the main icon in AID
+ try (LauncherIcons li = LauncherIcons.obtain(context)) {
+ result = li.wrapToAdaptiveIcon(mainIcon);
+ }
}
+ if (result == null) {
+ return null;
+ }
+
+ // Inject monochrome icon drawable
+ if (ATLEAST_T && useTheme) {
+ result.mutate();
+ int[] colors = ThemedIconDrawable.getColors(context);
+ Drawable mono = result.getMonochrome();
+
+ if (mono != null) {
+ mono.setTint(colors[1]);
+ } else if (info instanceof ItemInfoWithIcon iiwi) {
+ // Inject a previously generated monochrome icon
+ Bitmap monoBitmap = iiwi.bitmap.getMono();
+ if (monoBitmap != null) {
+ // Use BitmapDrawable instead of FastBitmapDrawable so that the colorState is
+ // preserved in constantState
+ mono = new BitmapDrawable(monoBitmap);
+ mono.setColorFilter(new BlendModeColorFilter(colors[1], BlendMode.SRC_IN));
+ // Inset the drawable according to the AdaptiveIconDrawable layers
+ mono = new InsetDrawable(mono, getExtraInsetFraction() / 2);
+ }
+ }
+ if (mono != null) {
+ result = new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
+ }
+ }
+
+ if (badge == null) {
+ try (LauncherIcons li = LauncherIcons.obtain(context)) {
+ badge = BitmapInfo.LOW_RES_INFO.withFlags(
+ li.getBitmapFlagOp(new BaseIconFactory.IconOptions().setUser(
+ UserCache.INSTANCE.get(context).getUserInfo(info.user))))
+ .getBadgeDrawable(context, useTheme);
+ }
+ if (badge == null) {
+ badge = new ColorDrawable(Color.TRANSPARENT);
+ }
+ }
+ return Pair.create(result, badge);
}
public static float squaredHypot(float x, float y) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 8be8fed..30f3f5f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -28,7 +28,9 @@
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
@@ -71,6 +73,7 @@
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.apppairs.AppPairIcon;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
@@ -346,7 +349,7 @@
setPageSpacing(Math.max(maxInsets, maxPadding));
}
- updateCellLayoutPadding();
+ updateCellLayoutMeasures();
updateWorkspaceWidgetsSizes();
setPageIndicatorInset();
}
@@ -370,10 +373,12 @@
mPageIndicator.setLayoutParams(lp);
}
- private void updateCellLayoutPadding() {
+ private void updateCellLayoutMeasures() {
Rect padding = mLauncher.getDeviceProfile().cellLayoutPaddingPx;
- mWorkspaceScreens.forEach(
- s -> s.setPadding(padding.left, padding.top, padding.right, padding.bottom));
+ mWorkspaceScreens.forEach(cellLayout -> {
+ cellLayout.setPadding(padding.left, padding.top, padding.right, padding.bottom);
+ cellLayout.setSpaceBetweenCellLayoutsPx(getPageSpacing() / 4);
+ });
}
private void updateWorkspaceWidgetsSizes() {
@@ -594,17 +599,19 @@
* Initializes and binds the first page
*/
public void bindAndInitFirstWorkspaceScreen() {
- if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if ((!FeatureFlags.QSB_ON_FIRST_SCREEN
+ || !mLauncher.getIsFirstPagePinnedItemEnabled())
+ || shouldShowFirstPageWidget()) {
+ mFirstPagePinnedItem = null;
return;
}
// Add the first page
CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
- // Always add a first page pinned widget on the first screen.
if (mFirstPagePinnedItem == null) {
// In transposed layout, we add the first page pinned widget in the Grid.
// As workspace does not touch the edges, we do not need a full
- // width first page pinned widget.
+ // width first page pinned item.
mFirstPagePinnedItem = LayoutInflater.from(getContext())
.inflate(R.layout.search_container_workspace, firstPage, false);
}
@@ -624,7 +631,7 @@
// transition animations competing with us changing the scroll when we add pages
disableLayoutTransitions();
- // Recycle the first page pinned widget
+ // Recycle the first page pinned item
if (mFirstPagePinnedItem != null) {
((ViewGroup) mFirstPagePinnedItem.getParent()).removeView(mFirstPagePinnedItem);
}
@@ -635,12 +642,14 @@
mScreenOrder.clear();
mWorkspaceScreens.clear();
+ // Ensure that the first page is always present
+ if (!ENABLE_SMARTSPACE_REMOVAL.get()) {
+ bindAndInitFirstWorkspaceScreen();
+ }
+
// Remove any deferred refresh callbacks
mLauncher.mHandler.removeCallbacksAndMessages(DeferredWidgetRefresh.class);
- // Ensure that the first page is always present
- bindAndInitFirstWorkspaceScreen();
-
// Re-enable the layout transitions
enableLayoutTransitions();
}
@@ -683,7 +692,7 @@
mLauncher.getStateManager().getState(), newScreen, insertIndex);
updatePageScrollValues();
- updateCellLayoutPadding();
+ updateCellLayoutMeasures();
return newScreen;
}
@@ -799,6 +808,13 @@
// and we store them as extra empty screens.
for (int i = 0; i < finalScreens.size(); i++) {
int screenId = finalScreens.keyAt(i);
+
+ // We don't want to remove the first screen even if it's empty because that's where
+ // first page pinned item would go if it gets turned back on.
+ if (ENABLE_SMARTSPACE_REMOVAL.get() && screenId == FIRST_SCREEN_ID) {
+ continue;
+ }
+
CellLayout screen = finalScreens.get(screenId);
mWorkspaceScreens.remove(screenId);
@@ -1012,7 +1028,9 @@
int id = mWorkspaceScreens.keyAt(i);
CellLayout cl = mWorkspaceScreens.valueAt(i);
// FIRST_SCREEN_ID can never be removed.
- if ((!FeatureFlags.QSB_ON_FIRST_SCREEN || id > FIRST_SCREEN_ID)
+ if (((!FeatureFlags.QSB_ON_FIRST_SCREEN
+ || shouldShowFirstPageWidget())
+ || id > FIRST_SCREEN_ID)
&& cl.getShortcutsAndWidgets().getChildCount() == 0) {
removeScreens.add(id);
}
@@ -2858,6 +2876,10 @@
view = FolderIcon.inflateFolderAndIcon(R.layout.folder_icon, mLauncher, cellLayout,
(FolderInfo) info);
break;
+ case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
+ view = AppPairIcon.inflateIcon(R.layout.app_pair_icon, mLauncher, cellLayout,
+ (FolderInfo) info);
+ break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
@@ -3413,7 +3435,8 @@
if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
widgetInfo = widgetHelper.findProvider(item.providerName, item.user);
} else {
- widgetInfo = widgetHelper.getLauncherAppWidgetInfo(item.appWidgetId);
+ widgetInfo = widgetHelper.getLauncherAppWidgetInfo(item.appWidgetId,
+ item.getTargetComponent());
}
if (widgetInfo != null) {
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index e4f34ae..2315111 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -34,6 +34,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.WORKSPACE_PAGE_INDICATOR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
@@ -48,6 +49,7 @@
import android.animation.ValueAnimator;
import android.util.FloatProperty;
import android.view.View;
+import android.view.ViewGroup;
import android.view.animation.Interpolator;
import com.android.launcher3.LauncherState.PageAlphaProvider;
@@ -163,6 +165,8 @@
state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE)
? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
: View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ hotseat.setDescendantFocusability(state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE)
+ ? ViewGroup.FOCUS_BLOCK_DESCENDANTS : ViewGroup.FOCUS_BEFORE_DESCENDANTS);
Interpolator translationInterpolator =
config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
@@ -172,9 +176,13 @@
scaleAndTranslation.translationY, translationInterpolator);
PageTranslationProvider pageTranslationProvider = state.getWorkspacePageTranslationProvider(
mLauncher);
- for (int i = 0; i < childCount; i++) {
- applyPageTranslation((CellLayout) mWorkspace.getChildAt(i), i, pageTranslationProvider,
- propertySetter, config);
+
+ if (!FOLDABLE_SINGLE_PAGE.get()) {
+ for (int i = 0; i < childCount; i++) {
+ applyPageTranslation((CellLayout) mWorkspace.getChildAt(i), i,
+ pageTranslationProvider,
+ propertySetter, config);
+ }
}
Interpolator hotseatTranslationInterpolator = config.getInterpolator(
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 40382b2..72c6cb8 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.allapps;
+import static com.android.launcher3.Flags.enableExpandingPauseWorkButton;
import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
@@ -79,6 +80,7 @@
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.recyclerview.AllAppsRecyclerViewPool;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
@@ -92,7 +94,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
-import java.util.stream.Stream;
/**
* All apps container view with search support for use in a dragging activity.
@@ -130,7 +131,7 @@
protected final List<AdapterHolder> mAH;
protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
Process.myUserHandle());
- protected final WorkProfileManager mWorkManager;
+ protected WorkProfileManager mWorkManager;
protected final Point mFastScrollerOffset = new Point();
protected final int mScrimColor;
protected final float mHeaderThreshold;
@@ -561,7 +562,8 @@
mAH.get(AdapterHolder.MAIN).setup(mainRecyclerView, mPersonalMatcher);
mAH.get(AdapterHolder.WORK).setup(workRecyclerView, mWorkManager.getMatcher());
workRecyclerView.setId(R.id.apps_list_view_work);
- if (FeatureFlags.ENABLE_EXPANDING_PAUSE_WORK_BUTTON.get()) {
+ if (enableExpandingPauseWorkButton()
+ || FeatureFlags.ENABLE_EXPANDING_PAUSE_WORK_BUTTON.get()) {
mAH.get(AdapterHolder.WORK).mRecyclerView.addOnScrollListener(
mWorkManager.newScrollListener());
}
@@ -621,16 +623,18 @@
private static void setUpCustomRecyclerViewPool(
@NonNull AllAppsRecyclerView mainRecyclerView,
@Nullable AllAppsRecyclerView workRecyclerView,
- @NonNull RecyclerView.RecycledViewPool recycledViewPool) {
+ @NonNull AllAppsRecyclerViewPool recycledViewPool) {
if (!ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
return;
}
+ final boolean hasWorkProfile = workRecyclerView != null;
+ recycledViewPool.setHasWorkProfile(hasWorkProfile);
mainRecyclerView.setRecycledViewPool(recycledViewPool);
if (workRecyclerView != null) {
workRecyclerView.setRecycledViewPool(recycledViewPool);
}
if (ALL_APPS_GONE_VISIBILITY.get()) {
- mainRecyclerView.updatePoolSize();
+ mainRecyclerView.updatePoolSize(hasWorkProfile);
}
}
@@ -793,7 +797,7 @@
*/
public int getFloatingSearchBarRestingMarginStart() {
DeviceProfile dp = mActivityContext.getDeviceProfile();
- return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin();
+ return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(mActivityContext);
}
/**
@@ -806,7 +810,7 @@
*/
public int getFloatingSearchBarRestingMarginEnd() {
DeviceProfile dp = mActivityContext.getDeviceProfile();
- return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin();
+ return dp.allAppsLeftRightMargin + dp.getAllAppsIconStartMargin(mActivityContext);
}
private void layoutBelowSearchContainer(View v, boolean includeTabsMargin) {
@@ -964,13 +968,14 @@
mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha;
}
- private void onAppsUpdated() {
- mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
+ @VisibleForTesting
+ public void onAppsUpdated() {
+ mHasWorkApps = mWorkManager.hasWorkApps();
if (!isSearching()) {
rebindAdapters();
- if (mHasWorkApps) {
- mWorkManager.reset();
- }
+ }
+ if (mHasWorkApps) {
+ mWorkManager.reset();
}
mActivityContext.getStatsLogManager().logger()
@@ -1096,7 +1101,7 @@
if (grid.isVerticalBarLayout()) {
setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
} else {
- int topPadding = grid.allAppsTopPadding;
+ int topPadding = grid.allAppsPadding.top;
if (isSearchBarFloating() && !grid.isTablet) {
topPadding += getResources().getDimensionPixelSize(
R.dimen.all_apps_additional_top_padding_floating_search);
@@ -1157,8 +1162,8 @@
int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
mAH.forEach(adapterHolder -> {
adapterHolder.mPadding.bottom = bottomPadding;
- adapterHolder.mPadding.left =
- adapterHolder.mPadding.right = grid.allAppsLeftRightPadding;
+ adapterHolder.mPadding.left = grid.allAppsPadding.left;
+ adapterHolder.mPadding.right = grid.allAppsPadding.right;
adapterHolder.applyPadding();
});
}
@@ -1215,6 +1220,11 @@
}
@VisibleForTesting
+ public void setWorkManager(WorkProfileManager workManager) {
+ mWorkManager = workManager;
+ }
+
+ @VisibleForTesting
public boolean isPersonalTabVisible() {
return isDescendantViewVisible(R.id.tab_personal);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 7edbeac..b0f13ef 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -16,6 +16,7 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.config.FeatureFlags.ALL_APPS_GONE_VISIBILITY;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_RV_PREINFLATION;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import static com.android.launcher3.logger.LauncherAtom.SearchResultContainer;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_PERSONAL_SCROLLED_DOWN;
@@ -94,21 +95,29 @@
}
protected void updatePoolSize() {
+ updatePoolSize(false);
+ }
+
+ void updatePoolSize(boolean hasWorkProfile) {
DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
- int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ALL_APPS_DIVIDER, 1);
- // If all apps' hidden visibility is INVISIBLE, we will need to preinflate one page of
- // all apps icons for smooth scrolling.
- int maxPoolSizeForAppIcons = (approxRows + 1) * grid.numShownAllAppsColumns;
- if (ALL_APPS_GONE_VISIBILITY.get()) {
- // If all apps' hidden visibility is GONE, we need to increase prefinated icons number
- // by [PREINFLATE_ICONS_ROW_COUNT] rows + [EXTRA_ICONS_COUNT] for fast opening all apps.
+ // By default the max num of pool size for app icons is num of app icons in one page of
+ // all apps.
+ int maxPoolSizeForAppIcons = grid.getMaxAllAppsRowCount()
+ * grid.numShownAllAppsColumns;
+ if (ALL_APPS_GONE_VISIBILITY.get() && ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
+ // If we set all apps' hidden visibility to GONE and enable pre-inflation, we want to
+ // preinflate one page of all apps icons plus [PREINFLATE_ICONS_ROW_COUNT] rows +
+ // [EXTRA_ICONS_COUNT]. Thus we need to bump the max pool size of app icons accordingly.
maxPoolSizeForAppIcons +=
PREINFLATE_ICONS_ROW_COUNT * grid.numShownAllAppsColumns + EXTRA_ICONS_COUNT;
}
+ if (hasWorkProfile) {
+ maxPoolSizeForAppIcons *= 2;
+ }
pool.setMaxRecycledViews(
AllAppsGridAdapter.VIEW_TYPE_ICON, maxPoolSizeForAppIcons);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index e724858..9f6e0fc 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -27,7 +27,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView.RecycledViewPool;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.model.data.AppInfo;
@@ -37,6 +36,7 @@
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.views.ActivityContext;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -82,22 +82,34 @@
}
/**
+ * Calling {@link #setApps(AppInfo[], int, Map, boolean)} with shouldPreinflate set to
+ * {@code true}. This method should be called in launcher (not for taskbar).
+ */
+ public void setApps(@Nullable AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map) {
+ setApps(apps, flags, map, /* shouldPreinflate= */ true);
+ }
+
+ /**
* Sets the current set of apps and sets mapping for {@link PackageUserKey} to Uid for
* the current set of apps.
+ *
+ * <p> Note that shouldPreinflate param should be set to {@code false} for taskbar, because this
+ * method is too late to preinflate all apps, as user will open all apps in the same frame.
*/
- public void setApps(@Nullable AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map) {
+ public void setApps(@Nullable AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map,
+ boolean shouldPreinflate) {
mApps = apps == null ? EMPTY_ARRAY : apps;
mModelFlags = flags;
notifyUpdate();
mPackageUserKeytoUidMap = map;
// Preinflate all apps RV when apps has changed, which can happen after unlocking screen,
// rotating screen, or downloading/upgrading apps.
- if (ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
+ if (shouldPreinflate && ENABLE_ALL_APPS_RV_PREINFLATION.get()) {
mAllAppsRecyclerViewPool.preInflateAllAppsViewHolders(mContext);
}
}
- RecycledViewPool getRecyclerViewPool() {
+ AllAppsRecyclerViewPool getRecyclerViewPool() {
return mAllAppsRecyclerViewPool;
}
@@ -226,4 +238,13 @@
public interface OnUpdateListener {
void onAppsUpdated();
}
+
+ /** Generate a dumpsys for each app package name and position in the apps list */
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + "\tAllAppsStore Apps[] size: " + mApps.length);
+ for (int i = 0; i < mApps.length; i++) {
+ writer.println(String.format("%s\tPackage index and name: %d/%s", prefix, i,
+ mApps[i].componentName.getPackageName()));
+ }
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index c09a5b9..03ac9df 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -33,7 +33,6 @@
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALL_APPS;
import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.util.FloatProperty;
@@ -54,7 +53,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatedFloat;
-import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
@@ -171,9 +169,6 @@
private boolean mIsVerticalLayout;
- // Whether this class should take care of closing the keyboard.
- private boolean mShouldControlKeyboard;
-
// Animation in this class is controlled by a single variable {@link mProgress}.
// Visually, it represents top y coordinate of the all apps container if multiplied with
// {@link mShiftRange}.
@@ -276,7 +271,6 @@
public void setState(LauncherState state) {
setProgress(state.getVerticalProgress(mLauncher));
setAlphas(state, new StateAnimationConfig(), NO_ANIM_PROPERTY_SETTER);
- onProgressAnimationEnd();
}
@Override
@@ -339,25 +333,11 @@
public void setStateWithAnimation(LauncherState toState,
StateAnimationConfig config, PendingAnimation builder) {
if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) {
- // For atomic animations, we close the keyboard immediately.
- if (!config.userControlled && mShouldControlKeyboard) {
- mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
- }
-
builder.addEndListener(success -> {
// Reset pull back progress and alpha after switching states.
ALL_APPS_PULL_BACK_TRANSLATION.set(this, ALL_APPS_PULL_BACK_TRANSLATION_DEFAULT);
ALL_APPS_PULL_BACK_ALPHA.set(this, ALL_APPS_PULL_BACK_ALPHA_DEFAULT);
- // We only want to close the keyboard if the animation has completed successfully.
- // The reason is that with keyboard sync, if the user swipes down from All Apps with
- // the keyboard open and then changes their mind and swipes back up, we want the
- // keyboard to remain open. However an onCancel signal is sent to the listeners
- // (success = false), so we need to check for that.
- if (config.userControlled && success && mShouldControlKeyboard) {
- mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
- }
-
mAllAppScale.updateValue(1f);
});
}
@@ -373,7 +353,9 @@
new VibrationAnimatorUpdateListener(this, mVibratorWrapper,
0, SWIPE_DRAG_COMMIT_THRESHOLD));
}
- builder.addEndListener(mVibratorWrapper::cancelVibrate);
+ builder.addEndListener((unused) -> {
+ mVibratorWrapper.cancelVibrate();
+ });
}
float targetProgress = toState.getVerticalProgress(mLauncher);
@@ -388,7 +370,6 @@
config.userControlled ? LINEAR : DECELERATE_1_7);
Animator anim = createSpringAnimation(mProgress, targetProgress);
anim.setInterpolator(verticalProgressInterpolator);
- anim.addListener(getProgressAnimatorListener());
builder.add(anim);
setAlphas(toState, config, builder);
@@ -426,10 +407,6 @@
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
}
- public AnimatorListener getProgressAnimatorListener() {
- return AnimatorListeners.forSuccessCallback(this::onProgressAnimationEnd);
- }
-
/**
* see Launcher#setupViews
*/
@@ -443,8 +420,6 @@
mAppsViewAlpha.setUpdateVisibility(true);
mAppsViewTranslationY = new MultiPropertyFactory<>(
mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum);
-
- mShouldControlKeyboard = !mLauncher.getSearchConfig().isKeyboardSyncEnabled();
}
/**
@@ -528,18 +503,6 @@
}
/**
- * Set the final view states based on the progress.
- * TODO: This logic should go in {@link LauncherState}
- */
- private void onProgressAnimationEnd() {
- if (Float.compare(mProgress, 1f) == 0) {
- if (mShouldControlKeyboard) {
- mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
- }
- }
- }
-
- /**
* This VibrationAnimatorUpdateListener class takes in four parameters, a controller, start
* threshold, end threshold, and a Vibrator wrapper. We use the progress given by the controller
* as it gives an accurate progress that dictates where the vibrator should vibrate.
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
index be0a898..7baf7d3 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
@@ -28,7 +28,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.AppInfo;
@@ -137,7 +136,6 @@
protected final OnClickListener mOnIconClickListener;
protected final OnLongClickListener mOnIconLongClickListener;
protected OnFocusChangeListener mIconFocusListener;
- private final int mExtraTextHeight;
public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater,
AlphabeticalAppsList<T> apps, SearchAdapterProvider<?> adapterProvider) {
@@ -149,8 +147,6 @@
mOnIconLongClickListener = mActivityContext.getAllAppsItemLongClickListener();
mAdapterProvider = adapterProvider;
- mExtraTextHeight = Utilities.calculateTextHeight(
- mActivityContext.getDeviceProfile().allAppsIconTextSizePx);
}
/** Checks if the passed viewType represents all apps divider. */
@@ -176,8 +172,8 @@
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_ICON:
- int layout = !FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() ? R.layout.all_apps_icon
- : R.layout.all_apps_icon_twoline;
+ int layout = !FeatureFlags.enableTwolineAllapps() ? R.layout.all_apps_icon
+ : R.layout.all_apps_icon_twoline;
BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
layout, parent, false);
icon.setLongPressTimeoutFactor(1f);
@@ -187,9 +183,6 @@
// Ensure the all apps icon height matches the workspace icons in portrait mode.
icon.getLayoutParams().height =
mActivityContext.getDeviceProfile().allAppsCellHeightPx;
- if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) {
- icon.getLayoutParams().height += mExtraTextHeight;
- }
return new ViewHolder(icon);
case VIEW_TYPE_EMPTY_SEARCH:
return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search,
@@ -219,6 +212,7 @@
BubbleTextView icon = (BubbleTextView) holder.itemView;
icon.reset();
icon.applyFromApplicationInfo(adapterItem.itemInfo);
+ icon.setOnFocusChangeListener(mIconFocusListener);
break;
}
case VIEW_TYPE_EMPTY_SEARCH: {
diff --git a/src/com/android/launcher3/allapps/BaseSearchConfig.java b/src/com/android/launcher3/allapps/BaseSearchConfig.java
deleted file mode 100644
index 9f47e8d..0000000
--- a/src/com/android/launcher3/allapps/BaseSearchConfig.java
+++ /dev/null
@@ -1,28 +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.launcher3.allapps;
-
-/** Base config values for search. */
-public class BaseSearchConfig {
- public BaseSearchConfig() {}
-
- /**
- * Returns whether to enable the synchronized keyboard transition between Home and All Apps.
- */
- public boolean isKeyboardSyncEnabled() {
- return false;
- }
-}
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index df22425..1692912 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -17,6 +17,7 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
import android.animation.Animator;
import android.animation.AnimatorInflater;
@@ -122,9 +123,8 @@
}
private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) {
- OnboardingPrefs onboardingPrefs = launcher.getOnboardingPrefs();
if (!launcher.isInState(NORMAL)
- || onboardingPrefs.getBoolean(OnboardingPrefs.HOME_BOUNCE_SEEN)
+ || HOME_BOUNCE_SEEN.get(launcher)
|| AbstractFloatingView.getTopOpenView(launcher) != null
|| launcher.getSystemService(UserManager.class).isDemoUser()
|| Utilities.isRunningInTestHarness()) {
@@ -135,7 +135,7 @@
new Handler().postDelayed(() -> showForHomeIfNeeded(launcher, false), DELAY_MS);
return;
}
- onboardingPrefs.incrementEventCount(OnboardingPrefs.HOME_BOUNCE_COUNT);
+ OnboardingPrefs.HOME_BOUNCE_COUNT.increment(launcher);
new DiscoveryBounce(launcher).show();
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 330d13d..1ba5f8e 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -451,9 +451,9 @@
@Override
public void setInsets(Rect insets) {
- int leftRightPadding = ActivityContext.lookupContext(getContext())
- .getDeviceProfile().allAppsLeftRightPadding;
- setPadding(leftRightPadding, getPaddingTop(), leftRightPadding, getPaddingBottom());
+ Rect allAppsPadding = ActivityContext.lookupContext(getContext())
+ .getDeviceProfile().allAppsPadding;
+ setPadding(allAppsPadding.left, getPaddingTop(), allAppsPadding.right, getPaddingBottom());
}
public <T extends FloatingHeaderRow> T findFixedRowByType(Class<T> type) {
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 144381c..48400b2 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -117,12 +117,13 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
View parent = (View) getParent();
- int allAppsLeftRightPadding = mActivityContext.getDeviceProfile().allAppsLeftRightPadding;
+ boolean isRtl = Utilities.isRtl(getResources());
+ Rect allAppsPadding = mActivityContext.getDeviceProfile().allAppsPadding;
int size = parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight()
- - 2 * allAppsLeftRightPadding;
+ - (allAppsPadding.left + allAppsPadding.right);
int tabWidth = getTabWidth(getContext(), size);
- int shift = (size - tabWidth) / 2 + allAppsLeftRightPadding;
- setTranslationX(Utilities.isRtl(getResources()) ? shift : -shift);
+ int shift = (size - tabWidth) / 2 + (isRtl ? allAppsPadding.left : allAppsPadding.right);
+ setTranslationX(isRtl ? shift : -shift);
}
@Override
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index 1ac8d87..ac0e5a4 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -52,6 +52,7 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.function.Predicate;
+import java.util.stream.Stream;
/**
* Companion class for {@link ActivityAllAppsContainerView} to manage work tab and personal tab
@@ -61,8 +62,6 @@
public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActivePageChangedListener {
private static final String TAG = "WorkProfileManager";
- public static final String KEY_WORK_EDU_STEP = "showed_work_profile_edu";
-
public static final int STATE_ENABLED = 1;
public static final int STATE_DISABLED = 2;
public static final int STATE_TRANSITION = 3;
@@ -215,6 +214,10 @@
return mCurrentState != WorkProfileManager.STATE_DISABLED;
}
+ public boolean hasWorkApps() {
+ return Stream.of(mAllApps.getAppsStore().getApps()).anyMatch(mMatcher);
+ }
+
/**
* Adds work profile specific adapter items to adapterItems and returns number of items added
*/
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 7316420..fd731f4 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -22,8 +22,10 @@
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
+import android.os.Trace;
import android.util.FloatProperty;
+import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController.Holder;
import java.util.ArrayList;
@@ -82,6 +84,15 @@
add(anim);
}
+ /** If trace is enabled, add counter to trace animation progress. */
+ public void logAnimationProgressToTrace(String counterName) {
+ if (Utilities.ATLEAST_Q && Trace.isEnabled()) {
+ super.addOnFrameListener(
+ animation -> Trace.setCounter(
+ counterName, (long) (animation.getAnimatedFraction() * 100)));
+ }
+ }
+
/**
* Creates and returns the underlying AnimatorSet
*/
diff --git a/src/com/android/launcher3/apppairs/AppPairIcon.java b/src/com/android/launcher3/apppairs/AppPairIcon.java
index 1dc4ad2..8121245 100644
--- a/src/com/android/launcher3/apppairs/AppPairIcon.java
+++ b/src/com/android/launcher3/apppairs/AppPairIcon.java
@@ -17,7 +17,9 @@
package com.android.launcher3.apppairs;
import android.content.Context;
+import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -26,6 +28,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.model.data.FolderInfo;
@@ -37,11 +40,41 @@
/**
* A {@link android.widget.FrameLayout} used to represent an app pair icon on the workspace.
+ * <br>
+ * The app pair icon is two parallel background rectangles with rounded corners. Icons of the two
+ * member apps are set into these rectangles.
*/
public class AppPairIcon extends FrameLayout implements DraggableView {
+ /**
+ * Design specs -- the below ratios are in relation to the size of a standard app icon.
+ */
+ private static final float OUTER_PADDING_SCALE = 1 / 30f;
+ private static final float INNER_PADDING_SCALE = 1 / 24f;
+ private static final float MEMBER_ICON_SCALE = 11 / 30f;
+ private static final float CENTER_CHANNEL_SCALE = 1 / 30f;
+ private static final float BIG_RADIUS_SCALE = 1 / 5f;
+ private static final float SMALL_RADIUS_SCALE = 1 / 15f;
+
+ // App pair icons are slightly smaller than regular icons, so we pad the icon by this much on
+ // each side.
+ float mOuterPadding;
+ // Inside of the icon, the two member apps are padded by this much.
+ float mInnerPadding;
+ // The two member apps have icons that are this big (in diameter).
+ float mMemberIconSize;
+ // The size of the center channel.
+ float mCenterChannelSize;
+ // The large outer radius of the background rectangles.
+ float mBigRadius;
+ // The small inner radius of the background rectangles.
+ float mSmallRadius;
+ // The app pairs icon appears differently in portrait and landscape.
+ boolean mIsLandscape;
private ActivityContext mActivity;
+ // A view that holds the app pair's title.
private BubbleTextView mAppPairName;
+ // The underlying ItemInfo that stores info about the app pair members, etc.
private FolderInfo mInfo;
public AppPairIcon(Context context, AttributeSet attrs) {
@@ -53,11 +86,11 @@
}
/**
- * Builds an AppPairIcon to be added to the Launcher
+ * Builds an AppPairIcon to be added to the Launcher.
*/
public static AppPairIcon inflateIcon(int resId, ActivityContext activity,
@Nullable ViewGroup group, FolderInfo appPairInfo) {
-
+ DeviceProfile grid = activity.getDeviceProfile();
LayoutInflater inflater = (group != null)
? LayoutInflater.from(group.getContext())
: activity.getLayoutInflater();
@@ -67,26 +100,114 @@
Collections.sort(appPairInfo.contents, Comparator.comparingInt(a -> a.rank));
icon.setClipToPadding(false);
- icon.mAppPairName = icon.findViewById(R.id.app_pair_icon_name);
-
- // TODO (jeremysim b/274189428): Replace this placeholder icon
- WorkspaceItemInfo placeholder = new WorkspaceItemInfo();
- placeholder.newIcon(icon.getContext());
- icon.mAppPairName.applyFromWorkspaceItem(placeholder);
-
- icon.mAppPairName.setText(appPairInfo.title);
-
icon.setTag(appPairInfo);
icon.setOnClickListener(activity.getItemOnClickListener());
icon.mInfo = appPairInfo;
icon.mActivity = activity;
+ // Set up app pair title
+ icon.mAppPairName = icon.findViewById(R.id.app_pair_icon_name);
+ icon.mAppPairName.setCompoundDrawablePadding(0);
+ FrameLayout.LayoutParams lp =
+ (FrameLayout.LayoutParams) icon.mAppPairName.getLayoutParams();
+ lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx;
+ icon.mAppPairName.setText(appPairInfo.title);
+
+ // Set up accessibility
+ icon.setContentDescription(icon.getAccessibilityTitle(
+ appPairInfo.contents.get(0).title, appPairInfo.contents.get(1).title));
icon.setAccessibilityDelegate(activity.getAccessibilityDelegate());
return icon;
}
@Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ // Calculate device-specific measurements
+ DeviceProfile grid = mActivity.getDeviceProfile();
+ int defaultIconSize = grid.iconSizePx;
+ mOuterPadding = OUTER_PADDING_SCALE * defaultIconSize;
+ mInnerPadding = INNER_PADDING_SCALE * defaultIconSize;
+ mMemberIconSize = MEMBER_ICON_SCALE * defaultIconSize;
+ mCenterChannelSize = CENTER_CHANNEL_SCALE * defaultIconSize;
+ mBigRadius = BIG_RADIUS_SCALE * defaultIconSize;
+ mSmallRadius = SMALL_RADIUS_SCALE * defaultIconSize;
+ mIsLandscape = grid.isLandscape;
+
+ // Calculate drawable area position
+ float leftBound = (canvas.getWidth() / 2f) - (defaultIconSize / 2f);
+ float topBound = getPaddingTop();
+
+ // Prepare to draw app pair icon background
+ Drawable background = new AppPairIconBackground(getContext(), this);
+ background.setBounds(0, 0, defaultIconSize, defaultIconSize);
+
+ // Draw background
+ canvas.save();
+ canvas.translate(leftBound, topBound);
+ background.draw(canvas);
+ canvas.restore();
+
+ // Prepare to draw icons
+ WorkspaceItemInfo app1 = mInfo.contents.get(0);
+ WorkspaceItemInfo app2 = mInfo.contents.get(1);
+ Drawable app1Icon = app1.newIcon(getContext());
+ Drawable app2Icon = app2.newIcon(getContext());
+ app1Icon.setBounds(0, 0, defaultIconSize, defaultIconSize);
+ app2Icon.setBounds(0, 0, defaultIconSize, defaultIconSize);
+
+ // Draw first icon
+ canvas.save();
+ canvas.translate(leftBound, topBound);
+ // The app icons are placed differently depending on device orientation.
+ if (mIsLandscape) {
+ canvas.translate(
+ (defaultIconSize / 2f) - (mCenterChannelSize / 2f) - mInnerPadding
+ - mMemberIconSize,
+ (defaultIconSize / 2f) - (mMemberIconSize / 2f)
+ );
+ } else {
+ canvas.translate(
+ (defaultIconSize / 2f) - (mMemberIconSize / 2f),
+ (defaultIconSize / 2f) - (mCenterChannelSize / 2f) - mInnerPadding
+ - mMemberIconSize
+ );
+
+ }
+ canvas.scale(MEMBER_ICON_SCALE, MEMBER_ICON_SCALE);
+ app1Icon.draw(canvas);
+ canvas.restore();
+
+ // Draw second icon
+ canvas.save();
+ canvas.translate(leftBound, topBound);
+ // The app icons are placed differently depending on device orientation.
+ if (mIsLandscape) {
+ canvas.translate(
+ (defaultIconSize / 2f) + (mCenterChannelSize / 2f) + mInnerPadding,
+ (defaultIconSize / 2f) - (mMemberIconSize / 2f)
+ );
+ } else {
+ canvas.translate(
+ (defaultIconSize / 2f) - (mMemberIconSize / 2f),
+ (defaultIconSize / 2f) + (mCenterChannelSize / 2f) + mInnerPadding
+ );
+ }
+ canvas.scale(MEMBER_ICON_SCALE, MEMBER_ICON_SCALE);
+ app2Icon.draw(canvas);
+ canvas.restore();
+ }
+
+ /**
+ * Returns a formatted accessibility title for app pairs.
+ */
+ public String getAccessibilityTitle(CharSequence app1, CharSequence app2) {
+ return getContext().getString(R.string.app_pair_name_format, app1, app2);
+ }
+
+ @Override
public int getViewType() {
return DRAGGABLE_ICON;
}
diff --git a/src/com/android/launcher3/apppairs/AppPairIconBackground.java b/src/com/android/launcher3/apppairs/AppPairIconBackground.java
new file mode 100644
index 0000000..735c82f
--- /dev/null
+++ b/src/com/android/launcher3/apppairs/AppPairIconBackground.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.apppairs;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+
+import com.android.launcher3.R;
+
+/**
+ * A Drawable for the background behind the twin app icons (looks like two rectangles).
+ */
+class AppPairIconBackground extends Drawable {
+ // The icon that we will draw this background on.
+ private final AppPairIcon icon;
+ private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ /**
+ * Null values to use with
+ * {@link Canvas#drawDoubleRoundRect(RectF, float[], RectF, float[], Paint)}, since there
+ * doesn't seem to be any other API for drawing rectangles with 4 different corner radii.
+ */
+ private static final RectF EMPTY_RECT = new RectF();
+ private static final float[] ARRAY_OF_ZEROES = new float[8];
+
+ AppPairIconBackground(Context context, AppPairIcon appPairIcon) {
+ icon = appPairIcon;
+ // Set up background paint color
+ TypedArray ta = context.getTheme().obtainStyledAttributes(R.styleable.FolderIconPreview);
+ mBackgroundPaint.setStyle(Paint.Style.FILL);
+ mBackgroundPaint.setColor(
+ ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0));
+ ta.recycle();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (icon.mIsLandscape) {
+ drawLeftRightSplit(canvas);
+ } else {
+ drawTopBottomSplit(canvas);
+ }
+ }
+
+ /**
+ * When device is in landscape, we draw the rectangles with a left-right split.
+ */
+ private void drawLeftRightSplit(Canvas canvas) {
+ // Get the bounds where we will draw the background image
+ int width = getBounds().width();
+ int height = getBounds().height();
+
+ // The left half of the background image, excluding center channel
+ RectF leftSide = new RectF(
+ icon.mOuterPadding,
+ icon.mOuterPadding,
+ (width / 2f) - (icon.mCenterChannelSize / 2f),
+ height - icon.mOuterPadding
+ );
+ // The right half of the background image, excluding center channel
+ RectF rightSide = new RectF(
+ (width / 2f) + (icon.mCenterChannelSize / 2f),
+ icon.mOuterPadding,
+ width - icon.mOuterPadding,
+ height - icon.mOuterPadding
+ );
+
+ drawCustomRoundedRect(canvas, leftSide, new float[]{
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mBigRadius, icon.mBigRadius});
+ drawCustomRoundedRect(canvas, rightSide, new float[]{
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mSmallRadius, icon.mSmallRadius});
+ }
+
+ /**
+ * When device is in portrait, we draw the rectangles with a top-bottom split.
+ */
+ private void drawTopBottomSplit(Canvas canvas) {
+ // Get the bounds where we will draw the background image
+ int width = getBounds().width();
+ int height = getBounds().height();
+
+ // The top half of the background image, excluding center channel
+ RectF topSide = new RectF(
+ icon.mOuterPadding,
+ icon.mOuterPadding,
+ width - icon.mOuterPadding,
+ (height / 2f) - (icon.mCenterChannelSize / 2f)
+ );
+ // The bottom half of the background image, excluding center channel
+ RectF bottomSide = new RectF(
+ icon.mOuterPadding,
+ (height / 2f) + (icon.mCenterChannelSize / 2f),
+ width - icon.mOuterPadding,
+ height - icon.mOuterPadding
+ );
+
+ drawCustomRoundedRect(canvas, topSide, new float[]{
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mSmallRadius, icon.mSmallRadius});
+ drawCustomRoundedRect(canvas, bottomSide, new float[]{
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mSmallRadius, icon.mSmallRadius,
+ icon.mBigRadius, icon.mBigRadius,
+ icon.mBigRadius, icon.mBigRadius});
+ }
+
+ /**
+ * Draws a rectangle with custom rounded corners.
+ * @param c The Canvas to draw on.
+ * @param rect The bounds of the rectangle.
+ * @param radii An array of 8 radii for the corners: top left x, top left y, top right x, top
+ * right y, bottom right x, and so on.
+ */
+ private void drawCustomRoundedRect(Canvas c, RectF rect, float[] radii) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ // Canvas.drawDoubleRoundRect is supported from Q onward
+ c.drawDoubleRoundRect(rect, radii, EMPTY_RECT, ARRAY_OF_ZEROES, mBackgroundPaint);
+ } else {
+ // Fallback rectangle with uniform rounded corners
+ c.drawRoundRect(rect, icon.mBigRadius, icon.mBigRadius, mBackgroundPaint);
+ }
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+
+ @Override
+ public void setAlpha(int i) {
+ // Required by Drawable but not used.
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ // Required by Drawable but not used.
+ }
+}
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 24cc0ac..d37b1f0 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -74,38 +74,12 @@
Log.d(TestProtocol.PERMANENT_DIAG_TAG, "sendStateEventToTest: " + stateOrdinal);
}
- public static void sendScrollFinishedEventToTest(Context context) {
+ public static void sendTestProtocolEventToTest(Context context, String testProtocolEvent) {
final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
if (accessibilityManager == null) return;
- sendEventToTest(accessibilityManager, context, TestProtocol.SCROLL_FINISHED_MESSAGE, null);
+ sendEventToTest(accessibilityManager, context, testProtocolEvent, null);
}
-
- public static void sendPauseDetectedEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.PAUSE_DETECTED_MESSAGE, null);
- }
-
- public static void sendDismissAnimationEndsEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE,
- null);
- }
-
- /**
- * Notify running tests of a folder opened.
- */
- public static void sendFolderOpenedEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.FOLDER_OPENED_MESSAGE, null);
- }
-
private static void sendEventToTest(
AccessibilityManager accessibilityManager,
Context context, String eventTag, Bundle data) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 77bd898..73861c1 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -16,31 +16,27 @@
package com.android.launcher3.config;
+import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getDebugFlag;
+import static com.android.launcher3.uioverrides.flags.FlagsFactory.getIntFlag;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getReleaseFlag;
-import android.content.Context;
+import android.view.ViewConfiguration;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BuildConfig;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.Flags;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
/**
* Defines a set of flags used to control various launcher behaviors.
- *
- * Please only add flags to your assigned block to prevent merge conflicts. If you do not have
- * a block, please update the current empty block and add a new empty block below to prevent
- * merge conflicts with the previous block.
- * List of blocks can be found:
- * <a href="http://go/gnl-flags-block-directory">here</a>
- *
+ * <p>
* <p>All the flags should be defined here with appropriate default values.
*/
public final class FeatureFlags {
@@ -52,10 +48,6 @@
private FeatureFlags() { }
- public static boolean showFlagTogglerUi(Context context) {
- return BuildConfig.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context);
- }
-
/**
* True when the build has come from Android Studio and is being used for local debugging.
* @deprecated Use {@link BuildConfig#IS_STUDIO_BUILD} directly
@@ -123,6 +115,22 @@
getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
"Allow entering All Apps from Overview (e.g. long swipe up from app)");
+ public static final BooleanFlag CUSTOM_LPNH_THRESHOLDS =
+ getReleaseFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", DISABLED,
+ "Add dev options to customize the LPNH trigger slop and milliseconds");
+
+ public static final BooleanFlag ANIMATE_LPNH =
+ getReleaseFlag(308693847, "ANIMATE_LPNH", TEAMFOOD,
+ "Animates navbar when long pressing");
+
+ public static final IntFlag LPNH_SLOP_PERCENTAGE =
+ getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
+ "Controls touch slop percentage for lpnh");
+
+ public static final IntFlag LPNH_TIMEOUT_MS =
+ getIntFlag(301680992, "LPNH_TIMEOUT_MS", ViewConfiguration.getLongPressTimeout(),
+ "Controls lpnh timeout in milliseconds");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
"Enable option to show keyboard when going to all-apps");
@@ -141,7 +149,7 @@
// TODO(Block 6): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_SEARCH_IN_TASKBAR = getDebugFlag(270393900,
- "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", DISABLED,
+ "ENABLE_ALL_APPS_SEARCH_IN_TASKBAR", ENABLED,
"Enables Search box in Taskbar All Apps.");
public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(270395140,
@@ -154,29 +162,27 @@
"Enable the ability to generate monochromatic icons, if it is not provided by the app");
// TODO(Block 8): Clean up flags
- public static final BooleanFlag ENABLE_MATERIAL_U_POPUP = getDebugFlag(270395516,
- "ENABLE_MATERIAL_U_POPUP", ENABLED, "Switch popup UX to use material U");
// TODO(Block 9): Clean up flags
- public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = getReleaseFlag(270395134,
- "ENABLE_DOWNLOAD_APP_UX_V2", ENABLED, "Updates the download app UX"
- + " to have better visuals");
-
- public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V3 = getDebugFlag(270395186,
- "ENABLE_DOWNLOAD_APP_UX_V3", ENABLED, "Updates the download app UX"
- + " to have better visuals, improve contrast, and color");
-
- public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(270395278,
- "SHOW_DOT_PAGINATION", ENABLED, "Enable showing dot pagination in workspace");
-
- public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag(270395809,
- "LARGE_SCREEN_WIDGET_PICKER", ENABLED, "Enable new widget picker that takes "
- + "advantage of large screen format");
+ public static final BooleanFlag UNFOLDED_WIDGET_PICKER = getDebugFlag(301918659,
+ "UNFOLDED_WIDGET_PICKER", DISABLED, "Enable new widget picker that takes "
+ + "advantage of the unfolded foldable format");
public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220,
"MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode "
+ "for home screen");
+ public static final BooleanFlag SMARTSPACE_AS_A_WIDGET = getDebugFlag(299181941,
+ "SMARTSPACE_AS_A_WIDGET", DISABLED, "Enable SmartSpace as a widget");
+
+ public static boolean shouldShowFirstPageWidget() {
+ return SMARTSPACE_AS_A_WIDGET.get() && WIDGET_ON_FIRST_SCREEN;
+ }
+
+ public static final BooleanFlag ENABLE_SMARTSPACE_REMOVAL = getDebugFlag(290799975,
+ "ENABLE_SMARTSPACE_REMOVAL", DISABLED, "Enable SmartSpace removal for "
+ + "home screen");
+
// TODO(Block 10): Clean up flags
public static final BooleanFlag ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION = getDebugFlag(270614790,
"ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION", DISABLED,
@@ -190,6 +196,10 @@
"ENABLE_PARAMETRIZE_REORDER", DISABLED,
"Enables generating the reorder using a set of parameters");
+ public static final BooleanFlag ENABLE_NO_LONG_PRESS_DRAG = getDebugFlag(299748096,
+ "ENABLE_NO_LONG_PRESS_DRAG", DISABLED,
+ "Don't trigger the drag if we are still under long press");
+
// TODO(Block 12): Clean up flags
public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680,
"ENABLE_MULTI_INSTANCE", DISABLED,
@@ -207,6 +217,14 @@
public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(270395798,
"ENABLE_TRANSIENT_TASKBAR", ENABLED, "Enables transient taskbar.");
+ // Aconfig migration complete for ENABLE_TASKBAR_NO_RECREATION.
+ public static final BooleanFlag ENABLE_TASKBAR_NO_RECREATION = getDebugFlag(299193589,
+ "ENABLE_TASKBAR_NO_RECREATION", DISABLED,
+ "Enables taskbar with no recreation from lifecycle changes of TaskbarActivityContext.");
+ public static boolean enableTaskbarNoRecreate() {
+ return ENABLE_TASKBAR_NO_RECREATION.get() || Flags.enableTaskbarNoRecreate();
+ }
+
// TODO(Block 16): Clean up flags
// When enabled the promise icon is visible in all apps while installation an app.
public static final BooleanFlag PROMISE_APPS_IN_ALL_APPS = getDebugFlag(270390012,
@@ -222,6 +240,7 @@
public static final BooleanFlag ENABLE_HIDE_HEADER = getReleaseFlag(270390930,
"ENABLE_HIDE_HEADER", ENABLED, "Hide header on keyboard before typing in all apps");
+ // Aconfig migration complete for ENABLE_EXPANDING_PAUSE_WORK_BUTTON.
public static final BooleanFlag ENABLE_EXPANDING_PAUSE_WORK_BUTTON = getDebugFlag(270390779,
"ENABLE_EXPANDING_PAUSE_WORK_BUTTON", DISABLED,
"Expand and collapse pause work button while scrolling");
@@ -229,8 +248,12 @@
public static final BooleanFlag COLLECT_SEARCH_HISTORY = getReleaseFlag(270391455,
"COLLECT_SEARCH_HISTORY", DISABLED, "Allow launcher to collect search history for log");
+ // Aconfig migration complete for ENABLE_TWOLINE_ALLAPPS.
public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937,
- "ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps.");
+ "ENABLE_TWOLINE_ALLAPPS", ENABLED, "Enables two line label inside all apps.");
+ public static boolean enableTwolineAllapps() {
+ return ENABLE_TWOLINE_ALLAPPS.get() || Flags.enableTwolineAllapps();
+ }
public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693,
"IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps");
@@ -251,17 +274,30 @@
getReleaseFlag(282993230, "ENABLE_LONG_PRESS_NAV_HANDLE", TEAMFOOD,
"Enables long pressing on the bottom bar nav handle to trigger events.");
+ public static final BooleanFlag ENABLE_SEARCH_HAPTIC_HINT =
+ getReleaseFlag(303023676, "ENABLE_SEARCH_HAPTIC_HINT", ENABLED,
+ "Enables haptic hint when long pressing on the bottom bar nav handle.");
+
// TODO(Block 17): Clean up flags
public static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(270396583,
- "ENABLE_TASKBAR_PINNING", DISABLED,
+ "ENABLE_TASKBAR_PINNING", TEAMFOOD,
"Enables taskbar pinning to allow user to switch between transient and persistent "
+ "taskbar flavors");
- // TODO(Block 18): Clean up flags
+ public static final BooleanFlag MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE = getDebugFlag(
+ 251502424, "ENABLE_BOOT_AWARE_STARTUP_DATA", DISABLED,
+ "Marks LauncherPref data as (and allows it to) available while the device is"
+ + " locked. Enabling this causes a 1-time movement of certain SharedPreferences"
+ + " data. Improves startup latency.");
+
+ // Aconfig migration complete for ENABLE_APP_PAIRS.
public static final BooleanFlag ENABLE_APP_PAIRS = getDebugFlag(274189428,
"ENABLE_APP_PAIRS", DISABLED,
"Enables the ability to create and save app pairs on the Home screen for easy"
+ " split screen launching.");
+ public static boolean enableAppPairs() {
+ return ENABLE_APP_PAIRS.get() || com.android.wm.shell.Flags.enableAppPairs();
+ }
// TODO(Block 19): Clean up flags
public static final BooleanFlag SCROLL_TOP_TO_RESET = getReleaseFlag(270395177,
@@ -284,6 +320,15 @@
"ENABLE_DYNAMIC_TASKBAR_THRESHOLDS", ENABLED,
"Enables taskbar thresholds that scale based on screen size.");
+ // Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER.
+ public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414,
+ "ENABLE_HOME_TRANSITION_LISTENER", TEAMFOOD,
+ "Enables launcher to listen to all transitions that include home activity.");
+
+ public static boolean enableHomeTransitionListener() {
+ return ENABLE_HOME_TRANSITION_LISTENER.get() || Flags.enableHomeTransitionListener();
+ }
+
// TODO(Block 21): Clean up flags
public static final BooleanFlag ENABLE_APP_ICON_FOR_INLINE_SHORTCUTS = getDebugFlag(270395087,
"ENABLE_APP_ICON_IN_INLINE_SHORTCUTS", DISABLED, "Show app icon for inline shortcut");
@@ -299,15 +344,6 @@
+ "waiting for SystemUI and then merging the SystemUI progress whenever we "
+ "start receiving the events");
- // TODO(Block 23): Clean up flags
- public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
- "ENABLE_GRID_ONLY_OVERVIEW", TEAMFOOD,
- "Enable a grid-only overview without a focused task.");
-
- public static final BooleanFlag ENABLE_CURSOR_HOVER_STATES = getDebugFlag(243191650,
- "ENABLE_CURSOR_HOVER_STATES", TEAMFOOD,
- "Enables cursor hover states for certain elements.");
-
// TODO(Block 24): Clean up flags
public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(270393455,
"ENABLE_NEW_MIGRATION_LOGIC", ENABLED,
@@ -367,10 +403,10 @@
public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE = getDebugFlag(
270393453, "ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE", DISABLED,
"Enable initiating split screen from workspace to workspace.");
-
- public static final BooleanFlag ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE = getDebugFlag(
- 279586624, "ENABLE_SPLIT_FROM_DESKTOP_TO_WORKSPACE", DISABLED,
- "Enable initiating split screen from desktop mode to workspace.");
+ public static boolean enableSplitContextually() {
+ return ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get() ||
+ com.android.wm.shell.Flags.enableSplitContextual();
+ }
public static final BooleanFlag ENABLE_TRACKPAD_GESTURE = getDebugFlag(271010401,
"ENABLE_TRACKPAD_GESTURE", ENABLED, "Enables trackpad gesture.");
@@ -395,21 +431,32 @@
// TODO(Block 31): Clean up flags
// TODO(Block 32): Clean up flags
+ // Aconfig migration complete for ENABLE_RESPONSIVE_WORKSPACE.
+ @VisibleForTesting
public static final BooleanFlag ENABLE_RESPONSIVE_WORKSPACE = getDebugFlag(241386436,
- "ENABLE_RESPONSIVE_WORKSPACE", DISABLED,
+ "ENABLE_RESPONSIVE_WORKSPACE", TEAMFOOD,
"Enables new workspace grid calculations method.");
+ public static boolean enableResponsiveWorkspace() {
+ return ENABLE_RESPONSIVE_WORKSPACE.get() || Flags.enableResponsiveWorkspace();
+ }
// TODO(Block 33): Clean up flags
public static final BooleanFlag ENABLE_ALL_APPS_RV_PREINFLATION = getDebugFlag(288161355,
"ENABLE_ALL_APPS_RV_PREINFLATION", ENABLED,
"Enables preinflating all apps icons to avoid scrolling jank.");
-
- // TODO(Block 34): Clean up flags
public static final BooleanFlag ALL_APPS_GONE_VISIBILITY = getDebugFlag(291651514,
"ALL_APPS_GONE_VISIBILITY", ENABLED,
"Set all apps container view's hidden visibility to GONE instead of INVISIBLE.");
- // TODO(Block 35): Empty block
+ // TODO(Block 34): Empty block
+ // Please only add flags to your assigned block. If you do not have a block:
+ // 1. Assign yourself this block
+ // 2. Add your flag to this block
+ // 3. Add a new empty block below this one
+ // 4. Move this comment to that new empty block
+ // This is all to prevent merge conflicts in the future and help keep track of who owns which
+ // flags.
+ // List of assigned blocks can be found: http://go/gnl-flags-block-directory
public static class BooleanFlag {
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 0d51d48..777f4d5 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -17,6 +17,7 @@
package com.android.launcher3.dragndrop;
import static com.android.launcher3.Utilities.ATLEAST_Q;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_NO_LONG_PRESS_DRAG;
import android.graphics.Point;
import android.graphics.Rect;
@@ -87,6 +88,10 @@
private int mLastTouchClassification;
protected int mDistanceSinceScroll = 0;
+ /**
+ * This variable is to differentiate between a long press and a drag, if it's true that means
+ * it's a long press and when it's false means that we are no longer in a long press.
+ */
protected boolean mIsInPreDrag;
private final int DRAG_VIEW_SCALE_DURATION_MS = 500;
@@ -370,7 +375,7 @@
@Override
public void onDriverDragEnd(float x, float y) {
if (!endWithFlingAnimation()) {
- drop(findDropTarget((int) x, (int) y, mCoordinatesTemp), null);
+ drop(findDropTarget((int) x, (int) y), null);
}
endDrag();
}
@@ -432,13 +437,6 @@
protected void handleMoveEvent(int x, int y) {
mDragObject.dragView.move(x, y);
- // Drop on someone?
- final int[] coordinates = mCoordinatesTemp;
- DropTarget dropTarget = findDropTarget(x, y, coordinates);
- mDragObject.x = coordinates[0];
- mDragObject.y = coordinates[1];
- checkTouchMove(dropTarget);
-
// Check if we are hovering over the scroll areas
mDistanceSinceScroll += Math.hypot(mLastTouch.x - x, mLastTouch.y - y);
mLastTouch.set(x, y);
@@ -451,6 +449,9 @@
&& mOptions.preDragCondition.shouldStartDrag(distanceDragged)) {
callOnDragStart();
}
+
+ // Drop on someone?
+ checkTouchMove(x, y);
}
public float getDistanceDragged() {
@@ -458,14 +459,15 @@
}
public void forceTouchMove() {
- int[] placeholderCoordinates = mCoordinatesTemp;
- DropTarget dropTarget = findDropTarget(mLastTouch.x, mLastTouch.y, placeholderCoordinates);
- mDragObject.x = placeholderCoordinates[0];
- mDragObject.y = placeholderCoordinates[1];
- checkTouchMove(dropTarget);
+ checkTouchMove(mLastTouch.x, mLastTouch.y);
}
- private void checkTouchMove(DropTarget dropTarget) {
+ private DropTarget checkTouchMove(final int x, final int y) {
+ // If we are in predrag, don't trigger any other event until we get out of it
+ if (ENABLE_NO_LONG_PRESS_DRAG.get() && mIsInPreDrag) {
+ return mLastDropTarget;
+ }
+ DropTarget dropTarget = findDropTarget(x, y);
if (dropTarget != null) {
if (mLastDropTarget != dropTarget) {
if (mLastDropTarget != null) {
@@ -474,12 +476,11 @@
dropTarget.onDragEnter(mDragObject);
}
dropTarget.onDragOver(mDragObject);
- } else {
- if (mLastDropTarget != null) {
- mLastDropTarget.onDragExit(mDragObject);
- }
+ } else if (mLastDropTarget != null) {
+ mLastDropTarget.onDragExit(mDragObject);
}
mLastDropTarget = dropTarget;
+ return mLastDropTarget;
}
/**
@@ -487,13 +488,8 @@
* we manually ensure appropriate drag and drop events get emulated for accessible drag.
*/
public void completeAccessibleDrag(int[] location) {
- final int[] coordinates = mCoordinatesTemp;
-
// We make sure that we prime the target for drop.
- DropTarget dropTarget = findDropTarget(location[0], location[1], coordinates);
- mDragObject.x = coordinates[0];
- mDragObject.y = coordinates[1];
- checkTouchMove(dropTarget);
+ DropTarget dropTarget = checkTouchMove(location[0], location[1]);
dropTarget.prepareAccessibilityDrop();
// Perform the drop
@@ -502,10 +498,6 @@
}
protected void drop(DropTarget dropTarget, Runnable flingAnimation) {
- final int[] coordinates = mCoordinatesTemp;
- mDragObject.x = coordinates[0];
- mDragObject.y = coordinates[1];
-
// Move dragging to the final target.
if (dropTarget != mLastDropTarget) {
if (mLastDropTarget != null) {
@@ -542,9 +534,9 @@
dispatchDropComplete(dropTargetAsView, accepted);
}
- private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
- mDragObject.x = x;
- mDragObject.y = y;
+ private DropTarget findDropTarget(final int x, final int y) {
+ mCoordinatesTemp[0] = x;
+ mCoordinatesTemp[1] = y;
final Rect r = mRectTemp;
final ArrayList<DropTarget> dropTargets = mDropTargets;
@@ -556,17 +548,17 @@
target.getHitRectRelativeToDragLayer(r);
if (r.contains(x, y)) {
- dropCoordinates[0] = x;
- dropCoordinates[1] = y;
- mActivity.getDragLayer().mapCoordInSelfToDescendant((View) target, dropCoordinates);
+ mActivity.getDragLayer().mapCoordInSelfToDescendant((View) target,
+ mCoordinatesTemp);
+ mDragObject.x = mCoordinatesTemp[0];
+ mDragObject.y = mCoordinatesTemp[1];
return target;
}
}
- // Pass all unhandled drag to workspace. Workspace finds the correct
- // cell layout to drop to in the existing drag/drop logic.
- dropCoordinates[0] = x;
- dropCoordinates[1] = y;
- return getDefaultDropTarget(dropCoordinates);
+ DropTarget dropTarget = getDefaultDropTarget(mCoordinatesTemp);
+ mDragObject.x = mCoordinatesTemp[0];
+ mDragObject.y = mCoordinatesTemp[1];
+ return dropTarget;
}
protected abstract DropTarget getDefaultDropTarget(int[] dropCoordinates);
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index adfdc89..c2d9e02 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -20,7 +20,6 @@
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
-import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -45,6 +44,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -244,13 +244,12 @@
public void setItemInfo(final ItemInfo info) {
// Load the adaptive icon on a background thread and add the view in ui thread.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
- Object[] outObj = new Object[1];
- boolean[] outIsIconThemed = new boolean[1];
int w = mWidth;
int h = mHeight;
- Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h,
- true /* shouldThemeIcon */, outObj, outIsIconThemed);
- if (dr instanceof AdaptiveIconDrawable) {
+ Pair<AdaptiveIconDrawable, Drawable> fullDrawable = Utilities.getFullDrawable(
+ mActivity, info, w, h, true /* shouldThemeIcon */);
+ if (fullDrawable != null) {
+ AdaptiveIconDrawable adaptiveIcon = fullDrawable.first;
int blurMargin = (int) mActivity.getResources()
.getDimension(R.dimen.blur_size_medium_outline) / 2;
@@ -258,24 +257,15 @@
bounds.inset(blurMargin, blurMargin);
// Badge is applied after icon normalization so the bounds for badge should not
// be scaled down due to icon normalization.
- mBadge = getBadge(mActivity, info, outObj[0], outIsIconThemed[0]);
+ mBadge = fullDrawable.second;
FastBitmapDrawable.setBadgeBounds(mBadge, bounds);
- // Do not draw the background in case of folder as its translucent
- final boolean shouldDrawBackground = !(dr instanceof FolderAdaptiveIcon);
-
try (LauncherIcons li = LauncherIcons.obtain(mActivity)) {
- Drawable nDr; // drawable to be normalized
- if (shouldDrawBackground) {
- nDr = dr;
- } else {
- // Since we just want the scale, avoid heavy drawing operations
- nDr = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
- }
- Utilities.scaleRectAboutCenter(bounds,
- li.getNormalizer().getScale(nDr, null, null, null));
+ // Since we just want the scale, avoid heavy drawing operations
+ Utilities.scaleRectAboutCenter(bounds, li.getNormalizer().getScale(
+ new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null),
+ null, null, null));
}
- AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
// Shrink very tiny bit so that the clip path is smaller than the original bitmap
// that has anti aliased edges and shadows.
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 55a539a..57e1641 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
+import static com.android.launcher3.testing.shared.TestProtocol.FOLDER_OPENED_MESSAGE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import android.animation.Animator;
@@ -644,6 +645,11 @@
* is played.
*/
private void animateOpen(List<WorkspaceItemInfo> items, int pageNo) {
+ if (items == null || items.size() <= 1) {
+ Log.d(TAG, "Couldn't animate folder open because items is: " + items);
+ return;
+ }
+
Folder openFolder = getOpen(mActivityContext);
if (openFolder != null && openFolder != this) {
// Close any open folder before opening a folder.
@@ -692,7 +698,8 @@
public void onAnimationEnd(Animator animation) {
setState(STATE_OPEN);
announceAccessibilityChanges();
- AccessibilityManagerCompat.sendFolderOpenedEventToTest(getContext());
+ AccessibilityManagerCompat.sendTestProtocolEventToTest(getContext(),
+ FOLDER_OPENED_MESSAGE);
mContent.setFocusOnFirstChild();
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 53d0efb..cb1dc4f 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -16,7 +16,7 @@
package com.android.launcher3.folder;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
+import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
@@ -805,7 +805,7 @@
@Override
public void onHoverChanged(boolean hovered) {
super.onHoverChanged(hovered);
- if (ENABLE_CURSOR_HOVER_STATES.get()) {
+ if (enableCursorHoverStates()) {
mBackground.setHovered(hovered);
}
}
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index ae5d8d4..69fa673 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.launcher3.graphics;
import static com.android.launcher3.LauncherPrefs.THEMED_ICONS;
@@ -21,6 +36,7 @@
import android.os.Messenger;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Pair;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.GridOption;
@@ -70,7 +86,11 @@
private static final int MESSAGE_ID_UPDATE_PREVIEW = 1337;
- private final ArrayMap<IBinder, PreviewLifecycleObserver> mActivePreviews = new ArrayMap<>();
+ /**
+ * Here we use the IBinder and the screen ID as the key of the active previews.
+ */
+ private final ArrayMap<Pair<IBinder, Integer>, PreviewLifecycleObserver> mActivePreviews =
+ new ArrayMap<>();
@Override
public boolean onCreate() {
@@ -149,6 +169,9 @@
LauncherPrefs.get(getContext())
.put(THEMED_ICONS, values.getAsBoolean(BOOLEAN_VALUE));
getContext().getContentResolver().notifyChange(uri, null);
+ mActivePreviews.values().forEach(observer ->
+ observer.renderer.refreshIcons()
+ );
return 1;
}
default:
@@ -176,11 +199,10 @@
try {
PreviewSurfaceRenderer renderer = new PreviewSurfaceRenderer(getContext(), request);
- // Destroy previous
- destroyObserver(mActivePreviews.get(renderer.getHostToken()));
-
observer = new PreviewLifecycleObserver(renderer);
- mActivePreviews.put(renderer.getHostToken(), observer);
+ // Destroy previous
+ destroyObserver(mActivePreviews.get(observer.getIdentifier()));
+ mActivePreviews.put(observer.getIdentifier(), observer);
renderer.loadAsync();
renderer.getHostToken().linkToDeath(observer, 0);
@@ -210,9 +232,9 @@
observer.destroyed = true;
observer.renderer.getHostToken().unlinkToDeath(observer, 0);
Executors.MAIN_EXECUTOR.execute(observer.renderer::destroy);
- PreviewLifecycleObserver cached = mActivePreviews.get(observer.renderer.getHostToken());
+ PreviewLifecycleObserver cached = mActivePreviews.get(observer.getIdentifier());
if (cached == observer) {
- mActivePreviews.remove(observer.renderer.getHostToken());
+ mActivePreviews.remove(observer.getIdentifier());
}
}
@@ -242,5 +264,14 @@
public void binderDied() {
destroyObserver(this);
}
+
+ /**
+ * Returns a key that should make the PreviewSurfaceRenderer unique and if two of them have
+ * the same key they will be treated as the same PreviewSurfaceRenderer. Primary this is
+ * used to prevent memory leaks by removing the old PreviewSurfaceRenderer.
+ */
+ public Pair<IBinder, Integer> getIdentifier() {
+ return new Pair<>(renderer.getHostToken(), renderer.getDisplayId());
+ }
}
}
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index ae44f0a..346f644 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.DeviceProfile.DEFAULT_SCALE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
@@ -34,9 +35,12 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
import android.content.res.TypedArray;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -75,6 +79,7 @@
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -82,6 +87,7 @@
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -187,6 +193,8 @@
private final SparseIntArray mWallpaperColorResources;
private final SparseArray<Size> mLauncherWidgetSpanInfo;
+ private final Map<BubbleTextView, WorkspaceItemInfo> mIcons = new HashMap<>();
+
public LauncherPreviewRenderer(Context context,
InvariantDeviceProfile idp,
WallpaperColors wallpaperColorsOverride,
@@ -365,11 +373,43 @@
return CellPosMapper.DEFAULT;
}
+ /**
+ * Refreshes icon to update based on resource changes.
+ */
+ public void refreshIcons() {
+ mUiHandler.post(() -> {
+ IconProvider iconProvider = null;
+ int iconDpi = -1;
+ for (Map.Entry<BubbleTextView, WorkspaceItemInfo> entry : mIcons.entrySet()) {
+ BubbleTextView icon = entry.getKey();
+ ItemInfoWithIcon info = entry.getValue();
+ // get monochrome themed icon if it was not initially cached
+ if (info.bitmap.getMono() == null) {
+ if (iconProvider == null || iconDpi == -1) {
+ LauncherAppState appState = LauncherAppState.getInstance(mContext);
+ iconProvider = appState.getIconProvider();
+ iconDpi = appState.getInvariantDeviceProfile().fillResIconDpi;
+ }
+ LauncherActivityInfo activityInfo = mContext.getSystemService(
+ LauncherApps.class)
+ .resolveActivity(info.getIntent(), info.user);
+ Drawable iconDrawable = iconProvider.getIcon(activityInfo, iconDpi);
+ LauncherIcons iconFactory = LauncherIcons.obtain(mContext);
+ info.bitmap = iconFactory.createBadgedIconBitmap(iconDrawable);
+ }
+ // update icon based on whether themed icon is enabled
+ icon.reapplyItemInfo(info);
+ }
+ }
+ );
+ }
+
private void inflateAndAddIcon(WorkspaceItemInfo info) {
CellLayout screen = mWorkspaceScreens.get(info.screenId);
BubbleTextView icon = (BubbleTextView) mHomeElementInflater.inflate(
R.layout.app_icon, screen, false);
icon.applyFromWorkspaceItem(info);
+ mIcons.put(icon, info);
addInScreenFromBind(icon, info);
}
@@ -476,6 +516,8 @@
currentWorkspaceItems, otherWorkspaceItems);
filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets,
otherAppWidgets);
+
+ mIcons.clear();
for (ItemInfo itemInfo : currentWorkspaceItems) {
switch (itemInfo.itemType) {
case Favorites.ITEM_TYPE_APPLICATION:
@@ -526,7 +568,8 @@
}
// Add first page QSB
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN && dataModel.isFirstPagePinnedItemEnabled
+ && !shouldShowFirstPageWidget()) {
CellLayout firstScreen = mWorkspaceScreens.get(FIRST_SCREEN_ID);
View qsb = mHomeElementInflater.inflate(R.layout.qsb_preview, firstScreen, false);
CellLayoutLayoutParams lp = new CellLayoutLayoutParams(
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index 307052a..3e77c78 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -19,8 +19,6 @@
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V3;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -76,10 +74,8 @@
// Duration = COMPLETE_ANIM_FRACTION * DURATION_SCALE
private static final float COMPLETE_ANIM_FRACTION = 1f;
- private static final float SMALL_SCALE = ENABLE_DOWNLOAD_APP_UX_V3.get() ? 0.8f : 0.7f;
- private static final float PROGRESS_STROKE_SCALE = ENABLE_DOWNLOAD_APP_UX_V2.get()
- ? 0.055f
- : 0.075f;
+ private static final float SMALL_SCALE = 0.8f;
+ private static final float PROGRESS_STROKE_SCALE = 0.055f;
private static final float PROGRESS_BOUNDS_SCALE = 0.075f;
private static final int PRELOAD_ACCENT_COLOR_INDEX = 0;
private static final int PRELOAD_BACKGROUND_COLOR_INDEX = 1;
@@ -119,8 +115,6 @@
private ObjectAnimator mCurrentAnim;
- private boolean mIsStartable;
-
public PreloadIconDrawable(ItemInfoWithIcon info, Context context) {
this(
info,
@@ -144,9 +138,7 @@
mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
- if (ENABLE_DOWNLOAD_APP_UX_V3.get()) {
- mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
- }
+ mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
mIndicatorColor = indicatorColor;
// This is the color
@@ -181,9 +173,6 @@
mIconScaleMultiplier.updateValue(info.getProgressLevel() == 0 ? 0 : 1);
setLevel(info.getProgressLevel());
- if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
- setIsStartable(info.isAppStartable());
- }
}
@Override
@@ -212,54 +201,31 @@
return;
}
- if (mInternalStateProgress > 0
- && (ENABLE_DOWNLOAD_APP_UX_V3.get() || !ENABLE_DOWNLOAD_APP_UX_V2.get())) {
+ if (mInternalStateProgress > 0) {
// Draw background.
- mProgressPaint.setStyle(ENABLE_DOWNLOAD_APP_UX_V3.get()
- ? Paint.Style.FILL
- : Paint.Style.FILL_AND_STROKE);
- mProgressPaint.setColor(ENABLE_DOWNLOAD_APP_UX_V3.get()
- ? mPlateColor
- : mSystemBackgroundColor);
+ mProgressPaint.setStyle(Paint.Style.FILL);
+ mProgressPaint.setColor(mPlateColor);
canvas.drawPath(mScaledTrackPath, mProgressPaint);
}
- if (!ENABLE_DOWNLOAD_APP_UX_V2.get() || mInternalStateProgress > 0) {
+ if (mInternalStateProgress > 0) {
// Draw track and progress.
mProgressPaint.setStyle(Paint.Style.STROKE);
- mProgressPaint.setColor(ENABLE_DOWNLOAD_APP_UX_V3.get()
- ? mTrackColor
- : mSystemAccentColor);
- if (!ENABLE_DOWNLOAD_APP_UX_V3.get()) {
- mProgressPaint.setAlpha(TRACK_ALPHA);
- }
+ mProgressPaint.setColor(mTrackColor);
canvas.drawPath(mScaledTrackPath, mProgressPaint);
mProgressPaint.setAlpha(MAX_PAINT_ALPHA);
- if (ENABLE_DOWNLOAD_APP_UX_V3.get()) {
- mProgressPaint.setColor(mProgressColor);
- }
+ mProgressPaint.setColor(mProgressColor);
canvas.drawPath(mScaledProgressPath, mProgressPaint);
}
int saveCount = canvas.save();
- float scale = ENABLE_DOWNLOAD_APP_UX_V2.get()
- ? 1 - mIconScaleMultiplier.value * (1 - SMALL_SCALE)
- : SMALL_SCALE;
+ float scale = 1 - mIconScaleMultiplier.value * (1 - SMALL_SCALE);
canvas.scale(scale, scale, bounds.exactCenterX(), bounds.exactCenterY());
super.drawInternal(canvas, bounds);
canvas.restoreToCount(saveCount);
}
- @Override
- protected void updateFilter() {
- if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
- setAlpha(mIsDisabled ? DISABLED_ICON_ALPHA : MAX_PAINT_ALPHA);
- } else {
- super.updateFilter();
- }
- }
-
/**
* Updates the install progress based on the level
*/
@@ -296,14 +262,6 @@
return !mRanFinishAnimation;
}
- /** Sets whether this icon should display the startable app UI. */
- public void setIsStartable(boolean isStartable) {
- if (mIsStartable != isStartable) {
- mIsStartable = isStartable;
- setIsDisabled(!isStartable);
- }
- }
-
private void updateInternalState(
float finalProgress, boolean isFinish, Runnable onFinishCallback) {
if (mCurrentAnim != null) {
@@ -355,7 +313,7 @@
*/
private void setInternalProgress(float progress) {
// Animate scale and alpha from pending to downloading state.
- if (ENABLE_DOWNLOAD_APP_UX_V2.get() && progress > 0 && mInternalStateProgress == 0) {
+ if (progress > 0 && mInternalStateProgress == 0) {
// Progress is changing for the first time, animate the icon scale
Animator iconScaleAnimator = mIconScaleMultiplier.animateToValue(1);
iconScaleAnimator.setDuration(SCALE_AND_ALPHA_ANIM_DURATION);
@@ -365,14 +323,11 @@
mInternalStateProgress = progress;
if (progress <= 0) {
- if (!ENABLE_DOWNLOAD_APP_UX_V2.get()) {
- mScaledTrackPath.reset();
- }
mIconScaleMultiplier.updateValue(0);
} else {
mPathMeasure.getSegment(
0, Math.min(progress, 1) * mTrackLength, mScaledProgressPath, true);
- if (progress > 1 && ENABLE_DOWNLOAD_APP_UX_V2.get()) {
+ if (progress > 1) {
// map the scale back to original value
mIconScaleMultiplier.updateValue(Utilities.mapBoundToRange(
progress - 1, 0, COMPLETE_ANIM_FRACTION, 1, 0, EMPHASIZED));
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index aebcdd4..1bac765 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -114,12 +114,17 @@
mDisplay = context.getSystemService(DisplayManager.class)
.getDisplay(bundle.getInt(KEY_DISPLAY_ID));
- mSurfaceControlViewHost = MAIN_EXECUTOR.submit(() -> new SurfaceControlViewHost(mContext,
- context.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY),
- mHostToken)).get(5, TimeUnit.SECONDS);
+ mSurfaceControlViewHost = MAIN_EXECUTOR.submit(() ->
+ new SurfaceControlViewHost(mContext, context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY), mHostToken)
+ ).get(5, TimeUnit.SECONDS);
mOnDestroyCallbacks.add(mSurfaceControlViewHost::release);
}
+ public int getDisplayId() {
+ return mDisplay.getDisplayId();
+ }
+
public IBinder getHostToken() {
return mHostToken;
}
@@ -196,6 +201,13 @@
}
}
+ /**
+ * Refreshes icon to update based on resource changes.
+ */
+ public void refreshIcons() {
+ mRenderer.refreshIcons();
+ }
+
/***
* Generates a new context overriding the theme color and the display size without affecting the
* main application context
@@ -225,7 +237,7 @@
PreviewContext previewContext = new PreviewContext(inflationContext, idp);
// Copy existing data to preview DB
LauncherDbUtils.copyTable(LauncherAppState.getInstance(mContext)
- .getModel().getModelDbController().getDb(),
+ .getModel().getModelDbController().getDb(),
TABLE_NAME,
LauncherAppState.getInstance(previewContext)
.getModel().getModelDbController().getDb(),
diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java
index 57fa8a2..a15348b 100644
--- a/src/com/android/launcher3/icons/LauncherIcons.java
+++ b/src/com/android/launcher3/icons/LauncherIcons.java
@@ -20,11 +20,16 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.LauncherPreviewRenderer;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.UserIconInfo;
/**
* Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
@@ -107,6 +112,12 @@
return mMonochromeIconFactory.wrap(base);
}
+ @NonNull
+ @Override
+ protected UserIconInfo getUserInfo(@NonNull UserHandle user) {
+ return UserCache.INSTANCE.get(mContext).getUserInfo(user);
+ }
+
@Override
public void close() {
recycle();
diff --git a/src/com/android/launcher3/logging/StartupLatencyLogger.kt b/src/com/android/launcher3/logging/StartupLatencyLogger.kt
index 93e9de5..7d7564b 100644
--- a/src/com/android/launcher3/logging/StartupLatencyLogger.kt
+++ b/src/com/android/launcher3/logging/StartupLatencyLogger.kt
@@ -30,6 +30,11 @@
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
var workspaceLoadStartTime: Long = UNSET_LONG
+ // StartupLatencyLogger should only send launcher startup logs once in each launcher activity
+ // lifecycle. After launcher activity startup is completed, the logger should be torn down and
+ // reject all logging calls. This flag should be checked at all APIs to prevent logging invalid
+ // startup metrics (such as loading workspace in screen rotation).
+ var isTornDown = false
private var isInTest = false
/** Subclass can override this method to handle collected latency metrics. */
@@ -45,6 +50,9 @@
@MainThread
fun logWorkspaceLoadStartTime(startTimeMs: Long): StartupLatencyLogger {
Preconditions.assertUIThread()
+ if (isTornDown) {
+ return this
+ }
workspaceLoadStartTime = startTimeMs
return this
}
@@ -56,6 +64,9 @@
@MainThread
fun logCardinality(cardinality: Int): StartupLatencyLogger {
Preconditions.assertUIThread()
+ if (isTornDown) {
+ return this
+ }
this.cardinality = cardinality
return this
}
@@ -67,6 +78,9 @@
fun logStart(event: LauncherLatencyEvent, startTimeMs: Long): StartupLatencyLogger {
// In unit test no looper is attached to current thread
Preconditions.assertUIThread()
+ if (isTornDown) {
+ return this
+ }
if (validateLoggingEventAtStart(event)) {
startTimeByEvent.put(event.id, startTimeMs)
}
@@ -80,6 +94,9 @@
fun logEnd(event: LauncherLatencyEvent, endTimeMs: Long): StartupLatencyLogger {
// In unit test no looper is attached to current thread
Preconditions.assertUIThread()
+ if (isTornDown) {
+ return this
+ }
maybeLogStartOfWorkspaceLoadTime(event)
if (validateLoggingEventAtEnd(event)) {
endTimeByEvent.put(event.id, endTimeMs)
@@ -96,6 +113,7 @@
endTimeByEvent.clear()
cardinality = UNSET_INT
workspaceLoadStartTime = UNSET_LONG
+ isTornDown = true
}
@MainThread
@@ -181,6 +199,15 @@
"Cannot end ${event.name} event after ${LauncherLatencyEvent.LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION.name}",
)
return false
+ } else if (
+ latencyType == LatencyType.COLD_DEVICE_REBOOTING &&
+ event == LauncherLatencyEvent.LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_SYNC
+ ) {
+ Log.e(
+ TAG,
+ "Cannot have ${LauncherLatencyEvent.LAUNCHER_LATENCY_STARTUP_WORKSPACE_LOADER_SYNC.name} in ${LatencyType.COLD_DEVICE_REBOOTING.name} startup type"
+ )
+ return false
}
return true
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 265378c..632ca24 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -654,7 +654,19 @@
LAUNCHER_APP_PAIR_SAVE(1456),
@UiEvent(doc = "App launched through pending intent")
- LAUNCHER_APP_LAUNCH_PENDING_INTENT(1394)
+ LAUNCHER_APP_LAUNCH_PENDING_INTENT(1394),
+
+ @UiEvent(doc = "User long pressed on taskbar divider icon to open popup menu")
+ LAUNCHER_TASKBAR_DIVIDER_MENU_OPEN(1488),
+
+ @UiEvent(doc = "User long pressed on taskbar divider icon to close popup menu")
+ LAUNCHER_TASKBAR_DIVIDER_MENU_CLOSE(1489),
+
+ @UiEvent(doc = "User has pinned taskbar using taskbar divider menu")
+ LAUNCHER_TASKBAR_PINNED(1490),
+
+ @UiEvent(doc = "User has unpinned taskbar using taskbar divider menu")
+ LAUNCHER_TASKBAR_UNPINNED(1491)
// ADD MORE
;
@@ -823,6 +835,13 @@
}
/**
+ * Set the features of the log message.
+ */
+ default StatsLogger withFeatures(int feature) {
+ return this;
+ }
+
+ /**
* Builds the final message and logs it as {@link EventEnum}.
*/
default void log(EventEnum event) {
diff --git a/src/com/android/launcher3/model/BaseLauncherBinder.java b/src/com/android/launcher3/model/BaseLauncherBinder.java
index dbb29b8..9b2344d 100644
--- a/src/com/android/launcher3/model/BaseLauncherBinder.java
+++ b/src/com/android/launcher3/model/BaseLauncherBinder.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -172,6 +173,11 @@
public abstract void bindWidgets();
/**
+ * bindWidgets is abstract because it is a no-op for the go launcher.
+ */
+ public abstract void bindSmartspaceWidget();
+
+ /**
* Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right)
*/
protected void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile,
@@ -288,6 +294,10 @@
executeCallbacksTask(c -> {
c.clearPendingBinds();
c.startBinding();
+ if (ENABLE_SMARTSPACE_REMOVAL.get()) {
+ c.setIsFirstPagePinnedItemEnabled(
+ mBgDataModel.isFirstPagePinnedItemEnabled);
+ }
}, mUiExecutor);
// Bind workspace screens
@@ -305,6 +315,10 @@
Executor pendingExecutor = pendingTasks::add;
bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
bindAppWidgets(otherAppWidgets, pendingExecutor);
+
+ StringCache cacheClone = mBgDataModel.stringCache.clone();
+ executeCallbacksTask(c -> c.bindStringCache(cacheClone), pendingExecutor);
+
executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
pendingExecutor.execute(
() -> {
@@ -319,9 +333,6 @@
c.onInitialBindComplete(
currentScreenIds, pendingTasks, workspaceItemCount, isBindSync);
}, mUiExecutor);
-
- StringCache cacheClone = mBgDataModel.stringCache.clone();
- executeCallbacksTask(c -> c.bindStringCache(cacheClone), pendingExecutor);
}
private void bindWorkspaceItems(
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 7bcd038..54ecc00 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -17,6 +17,9 @@
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY;
+import static com.android.launcher3.BuildConfig.QSB_ON_FIRST_SCREEN;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
import static com.android.launcher3.shortcuts.ShortcutRequest.PINNED;
@@ -129,6 +132,8 @@
* Load id for which the callbacks were successfully bound
*/
public int lastLoadId = -1;
+ public boolean isFirstPagePinnedItemEnabled = QSB_ON_FIRST_SCREEN
+ && !ENABLE_SMARTSPACE_REMOVAL.get();
/**
* Clears all the data
@@ -152,7 +157,9 @@
screenSet.add(item.screenId);
}
}
- if (FeatureFlags.QSB_ON_FIRST_SCREEN || screenSet.isEmpty()) {
+ if ((FeatureFlags.QSB_ON_FIRST_SCREEN
+ && !shouldShowFirstPageWidget())
+ || screenSet.isEmpty()) {
screenSet.add(Workspace.FIRST_SCREEN_ID);
}
return screenSet.getArray();
@@ -170,11 +177,15 @@
writer.println(prefix + '\t' + appWidgets.get(i).toString());
}
writer.println(prefix + " ---- folder items ");
- for (int i = 0; i< folders.size(); i++) {
+ for (int i = 0; i < folders.size(); i++) {
writer.println(prefix + '\t' + folders.valueAt(i).toString());
}
+ writer.println(prefix + " ---- extra items ");
+ for (int i = 0; i < extraItems.size(); i++) {
+ writer.println(prefix + '\t' + extraItems.valueAt(i).toString());
+ }
writer.println(prefix + " ---- items id map ");
- for (int i = 0; i< itemsIdMap.size(); i++) {
+ for (int i = 0; i < itemsIdMap.size(); i++) {
writer.println(prefix + '\t' + itemsIdMap.valueAt(i).toString());
}
@@ -442,6 +453,20 @@
this.containerId = containerId;
this.items = Collections.unmodifiableList(items);
}
+
+ @Override
+ @NonNull
+ public final String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("FixedContainerItems:");
+ s.append(" id=").append(containerId);
+ s.append(" itemCount=").append(items.size());
+ for (int i = 0; i < items.size(); i++) {
+ s.append(" item #").append(i).append(": ").append(items.get(i).toString());
+ }
+ return s.toString();
+ }
+
}
@@ -468,6 +493,7 @@
default void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
default void bindScreens(IntArray orderedScreenIds) { }
+ default void setIsFirstPagePinnedItemEnabled(boolean isFirstPagePinnedItemEnabled) { }
default void finishBindingItems(IntSet pagesBoundFirst) { }
default void preAddApps() { }
default void bindAppsAdded(IntArray newScreens,
@@ -487,6 +513,7 @@
default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
default void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) { }
default void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
+ default void bindSmartspaceWidget() { }
/** Called when workspace has been bound. */
default void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks,
diff --git a/src/com/android/launcher3/model/DatabaseHelper.java b/src/com/android/launcher3/model/DatabaseHelper.java
index ecf5f67..1360510 100644
--- a/src/com/android/launcher3/model/DatabaseHelper.java
+++ b/src/com/android/launcher3/model/DatabaseHelper.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
import static com.android.launcher3.LauncherSettings.Favorites.addTableToDb;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import android.content.ContentValues;
@@ -257,7 +258,8 @@
Favorites.SCREEN, IntArray.wrap(-777, -778)), null);
}
case 30: {
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && !shouldShowFirstPageWidget()) {
// Clean up first row in screen 0 as it might contain junk data.
Log.d(TAG, "Cleaning up first row");
db.delete(Favorites.TABLE_NAME,
@@ -267,7 +269,6 @@
Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP,
Favorites.CELLY, 0), null);
}
- return;
}
case 31: {
LauncherDbUtils.migrateLegacyShortcuts(mContext, db);
diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
index c233872..efd5574 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
@@ -18,6 +18,9 @@
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
import static com.android.launcher3.LauncherSettings.Favorites.TMP_TABLE;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
+import static com.android.launcher3.model.LoaderTask.SMARTSPACE_ON_HOME_SCREEN;
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
@@ -37,6 +40,7 @@
import androidx.annotation.NonNull;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -327,7 +331,11 @@
@NonNull final List<DbEntry> sortedItemsToPlace, final boolean matchingScreenIdOnly) {
final GridOccupancy occupied = new GridOccupancy(trgX, trgY);
final Point trg = new Point(trgX, trgY);
- final Point next = new Point(0, screenId == 0 && FeatureFlags.QSB_ON_FIRST_SCREEN
+ final Point next = new Point(0, screenId == 0
+ && (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && (!ENABLE_SMARTSPACE_REMOVAL.get() || LauncherPrefs.getPrefs(destReader.mContext)
+ .getBoolean(SMARTSPACE_ON_HOME_SCREEN, true))
+ && !shouldShowFirstPageWidget())
? 1 /* smartspace */ : 0);
List<DbEntry> existedEntries = destReader.mWorkspaceEntriesByScreenId.get(screenId);
if (existedEntries != null) {
@@ -465,6 +473,13 @@
}
break;
}
+ case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR: {
+ int total = getFolderItemsCount(entry);
+ if (total != 2) {
+ throw new Exception("App pair contains fewer or more than 2 items");
+ }
+ break;
+ }
default:
throw new Exception("Invalid item type");
}
@@ -539,8 +554,8 @@
verifyPackage(cn.getPackageName());
int widgetId = c.getInt(indexAppWidgetId);
- LauncherAppWidgetProviderInfo pInfo =
- widgetManagerHelper.getLauncherAppWidgetInfo(widgetId);
+ LauncherAppWidgetProviderInfo pInfo = widgetManagerHelper
+ .getLauncherAppWidgetInfo(widgetId, cn);
Point spans = null;
if (pInfo != null) {
spans = pInfo.getMinSpans();
@@ -562,6 +577,13 @@
}
break;
}
+ case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR: {
+ int total = getFolderItemsCount(entry);
+ if (total != 2) {
+ throw new Exception("App pair contains fewer or more than 2 items");
+ }
+ break;
+ }
default:
throw new Exception("Invalid item type");
}
@@ -679,6 +701,7 @@
public String getEntryMigrationId() {
switch (itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
+ case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
return getFolderMigrationId();
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
return mProvider;
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 33332f0..4370043 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -17,6 +17,7 @@
package com.android.launcher3.model;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import android.content.ComponentName;
import android.content.ContentValues;
@@ -470,7 +471,7 @@
// cause the item loading to get skipped
ShortcutKey.fromItemInfo(info);
}
- if (checkItemPlacement(info)) {
+ if (checkItemPlacement(info, dataModel.isFirstPagePinnedItemEnabled)) {
dataModel.addItem(mContext, info, false, logger);
} else {
markDeleted("Item position overlap");
@@ -480,7 +481,7 @@
/**
* check & update map of what's occupied; used to discard overlapping/invalid items
*/
- protected boolean checkItemPlacement(ItemInfo item) {
+ protected boolean checkItemPlacement(ItemInfo item, boolean isFirstPagePinnedItemEnabled) {
int containerIndex = item.screenId;
if (item.container == Favorites.CONTAINER_HOTSEAT) {
final GridOccupancy hotseatOccupancy =
@@ -528,7 +529,8 @@
if (!mOccupied.containsKey(item.screenId)) {
GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);
- if (item.screenId == Workspace.FIRST_SCREEN_ID && FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (item.screenId == Workspace.FIRST_SCREEN_ID && (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && !shouldShowFirstPageWidget() && isFirstPagePinnedItemEnabled)) {
// Mark the first X columns (X is width of the search container) in the first row as
// occupied (if the feature is enabled) in order to account for the search
// container.
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 0e68db2..1ab0355 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -16,7 +16,12 @@
package com.android.launcher3.model;
+import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
+import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
+import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
@@ -57,6 +62,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -95,6 +101,7 @@
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
+import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
import java.util.Collections;
@@ -114,6 +121,7 @@
*/
public class LoaderTask implements Runnable {
private static final String TAG = "LoaderTask";
+ public static final String SMARTSPACE_ON_HOME_SCREEN = "pref_smartspace_home_screen";
private static final boolean DEBUG = true;
@@ -295,6 +303,19 @@
logASplit("bindWidgets");
verifyNotStopped();
+ LauncherPrefs prefs = LauncherPrefs.get(mApp.getContext());
+ if (SMARTSPACE_AS_A_WIDGET.get() && prefs.get(SHOULD_SHOW_SMARTSPACE)) {
+ mLauncherBinder.bindSmartspaceWidget();
+ // Turn off pref.
+ prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(false));
+ logASplit("bindSmartspaceWidget");
+ verifyNotStopped();
+ } else if (!SMARTSPACE_AS_A_WIDGET.get() && WIDGET_ON_FIRST_SCREEN
+ && !prefs.get(LauncherPrefs.SHOULD_SHOW_SMARTSPACE)) {
+ // Turn on pref.
+ prefs.putSync(SHOULD_SHOW_SMARTSPACE.to(true));
+ }
+
if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
mModelDelegate.loadAndBindOtherItems(mLauncherBinder.mCallbacksList);
logASplit("otherDelegateItems");
@@ -350,6 +371,9 @@
mModelDelegate.markActive();
logASplit("workspaceDelegateItems");
}
+ mBgDataModel.isFirstPagePinnedItemEnabled = FeatureFlags.QSB_ON_FIRST_SCREEN
+ && (!ENABLE_SMARTSPACE_REMOVAL.get() || LauncherPrefs.getPrefs(
+ mApp.getContext()).getBoolean(SMARTSPACE_ON_HOME_SCREEN, true));
}
private void loadWorkspaceImpl(
@@ -457,7 +481,10 @@
// for now. Database will be updated once user manually modifies folder.
for (int rank = 0; rank < size; ++rank) {
WorkspaceItemInfo info = folder.contents.get(rank);
- info.rank = rank;
+ // rank is used differently in app pairs, so don't reset
+ if (folder.itemType != ITEM_TYPE_APP_PAIR) {
+ info.rank = rank;
+ }
if (info.usingLowResIcon()
&& info.itemType == Favorites.ITEM_TYPE_APPLICATION
@@ -740,8 +767,13 @@
ComponentKey providerKey = new ComponentKey(component, c.user);
if (!mWidgetProvidersMap.containsKey(providerKey)) {
- mWidgetProvidersMap.put(providerKey,
- widgetHelper.findProvider(component, c.user));
+ if (customWidget) {
+ mWidgetProvidersMap.put(providerKey, CustomWidgetManager.INSTANCE
+ .get(mApp.getContext()).getWidgetProvider(component));
+ } else {
+ mWidgetProvidersMap.put(providerKey,
+ widgetHelper.findProvider(component, c.user));
+ }
}
final AppWidgetProviderInfo provider = mWidgetProvidersMap.get(providerKey);
@@ -814,7 +846,8 @@
return;
}
LauncherAppWidgetProviderInfo widgetProviderInfo =
- widgetHelper.getLauncherAppWidgetInfo(appWidgetId);
+ widgetHelper.getLauncherAppWidgetInfo(appWidgetId,
+ appWidgetInfo.getTargetComponent());
if (widgetProviderInfo != null
&& (appWidgetInfo.spanX < widgetProviderInfo.minSpanX
|| appWidgetInfo.spanY < widgetProviderInfo.minSpanY)) {
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index e10e72d..139efc3 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -54,6 +54,7 @@
import com.android.launcher3.AutoInstallsLayout.SourceResources;
import com.android.launcher3.ConstantItem;
import com.android.launcher3.DefaultLayoutParser;
+import com.android.launcher3.EncryptionType;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherFiles;
@@ -499,11 +500,11 @@
private ConstantItem<Boolean> getEmptyDbCreatedKey(String dbName) {
if (mContext instanceof SandboxContext) {
return LauncherPrefs.nonRestorableItem(EMPTY_DATABASE_CREATED,
- false /* default value */, false /* boot aware */);
+ false /* default value */, EncryptionType.ENCRYPTED);
}
String key = TextUtils.equals(dbName, LauncherFiles.LAUNCHER_DB)
? EMPTY_DATABASE_CREATED : EMPTY_DATABASE_CREATED + "@" + dbName;
- return LauncherPrefs.backedUpItem(key, false /* default value */, false /* boot aware */);
+ return LauncherPrefs.backedUpItem(key, false /* default value */, EncryptionType.ENCRYPTED);
}
/**
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 2591550..37a7171 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -44,7 +44,6 @@
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -68,7 +67,8 @@
*/
public class PackageUpdatedTask extends BaseModelUpdateTask {
- private static boolean DEBUG = false;
+ // TODO(b/290090023): Set to false after root causing is done.
+ private static final boolean DEBUG = true;
private static final String TAG = "PackageUpdatedTask";
public static final int OP_NONE = 0;
@@ -148,7 +148,7 @@
break;
case OP_REMOVE: {
for (int i = 0; i < N; i++) {
- FileLog.d(TAG, "Removing app icon" + packages[i]);
+ FileLog.d(TAG, "Removing app icon: " + packages[i]);
iconCache.removeIconsForPkg(packages[i], mUser);
}
// Fall through
diff --git a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
index 1fc8a03..929f698 100644
--- a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
+++ b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
import android.util.LongSparseArray;
@@ -66,7 +67,8 @@
int screenCount = workspaceScreens.size();
// First check the preferred screen.
IntSet screensToExclude = new IntSet();
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN
+ && !shouldShowFirstPageWidget()) {
screensToExclude.add(FIRST_SCREEN_ID);
}
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 7e6cbef..6c2f589 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -23,8 +23,6 @@
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
-import android.os.Build;
-import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
@@ -177,12 +175,6 @@
info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
- if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O
- && Process.myUserHandle().equals(lai.getUser())) {
- // The icon for a non-primary user is badged, hence it's not exactly an adaptive icon.
- info.runtimeStatusFlags |= FLAG_ADAPTIVE_ICON;
- }
-
// Sets the progress level, installation and incremental download flags.
info.setProgressLevel(
PackageManagerHelper.getLoadingProgress(lai),
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index b4a935a..dc180d8 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -83,17 +83,6 @@
public static final int FLAG_SYSTEM_MASK = FLAG_SYSTEM_YES | FLAG_SYSTEM_NO;
/**
- * Flag indicating that the icon is an {@link android.graphics.drawable.AdaptiveIconDrawable}
- * that can be optimized in various way.
- */
- public static final int FLAG_ADAPTIVE_ICON = 1 << 8;
-
- /**
- * Flag indicating that the icon is badged.
- */
- public static final int FLAG_ICON_BADGED = 1 << 9;
-
- /**
* The icon is being installed. If {@link WorkspaceItemInfo#FLAG_RESTORED_ICON} or
* {@link WorkspaceItemInfo#FLAG_AUTOINSTALL_ICON} is set, then the icon is either being
* installed or is in a broken state.
diff --git a/src/com/android/launcher3/pageindicators/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicator.java
index 4ab2037..30156c8 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicator.java
@@ -30,7 +30,7 @@
* Sets flag to indicate when the screens are in the process of binding so that we don't animate
* during that period.
*/
- default void setAreScreensBinding(boolean areScreensBinding) {
+ default void setAreScreensBinding(boolean areScreensBinding, boolean isTwoPanels) {
// No-op by default
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index ce71275..fd1b64f 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -16,7 +16,7 @@
package com.android.launcher3.pageindicators;
-import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION;
+import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -69,7 +69,7 @@
private static final int PAGE_INDICATOR_ALPHA = 255;
private static final int DOT_ALPHA = 128;
private static final float DOT_ALPHA_FRACTION = 0.5f;
- private static final int DOT_GAP_FACTOR = SHOW_DOT_PAGINATION.get() ? 4 : 3;
+ private static final int DOT_GAP_FACTOR = 4;
private static final int VISIBLE_ALPHA = 255;
private static final int INVISIBLE_ALPHA = 0;
private Paint mPaginationPaint;
@@ -131,6 +131,7 @@
private float mCurrentPosition;
private float mFinalPosition;
private boolean mAreScreensBinding;
+ private boolean mIsTwoPanels;
private ObjectAnimator mAnimator;
private @Nullable ObjectAnimator mAlphaAnimator;
@@ -153,10 +154,7 @@
mPaginationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaginationPaint.setStyle(Style.FILL);
mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
- mDotRadius = (SHOW_DOT_PAGINATION.get()
- ? getResources().getDimension(R.dimen.page_indicator_dot_size_v2)
- : getResources().getDimension(R.dimen.page_indicator_dot_size))
- / 2;
+ mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
mCircleGap = DOT_GAP_FACTOR * mDotRadius;
setOutlineProvider(new MyOutlineProver());
mIsRtl = Utilities.isRtl(getResources());
@@ -164,7 +162,7 @@
@Override
public void setScroll(int currentScroll, int totalScroll) {
- if (SHOW_DOT_PAGINATION.get() && currentScroll == 0 && totalScroll == 0) {
+ if (currentScroll == 0 && totalScroll == 0) {
CURRENT_POSITION.set(this, (float) mActivePage);
return;
}
@@ -217,7 +215,7 @@
@Override
public void setShouldAutoHide(boolean shouldAutoHide) {
- mShouldAutoHide = shouldAutoHide && SHOW_DOT_PAGINATION.get();
+ mShouldAutoHide = shouldAutoHide;
if (shouldAutoHide && mPaginationPaint.getAlpha() > INVISIBLE_ALPHA) {
hideAfterDelay();
} else if (!shouldAutoHide) {
@@ -353,6 +351,12 @@
@Override
public void setActiveMarker(int activePage) {
+ // In unfolded foldables, every page has two CellLayouts, so we need to halve the active
+ // page for it to be accurate.
+ if (mIsTwoPanels && !FOLDABLE_SINGLE_PAGE.get()) {
+ activePage = activePage / 2;
+ }
+
if (mActivePage != activePage) {
mActivePage = activePage;
}
@@ -365,7 +369,9 @@
}
@Override
- public void setAreScreensBinding(boolean areScreensBinding) {
+ public void setAreScreensBinding(boolean areScreensBinding, boolean isTwoPanels) {
+ mIsTwoPanels = isTwoPanels;
+
// Reapply correct current position which was skipped during setScroll.
if (mAreScreensBinding && !areScreensBinding) {
CURRENT_POSITION.set(this, (float) mActivePage);
@@ -420,16 +426,14 @@
int alpha = mPaginationPaint.getAlpha();
// Here we draw the dots
- mPaginationPaint.setAlpha(SHOW_DOT_PAGINATION.get()
- ? ((int) (alpha * DOT_ALPHA_FRACTION))
- : DOT_ALPHA);
+ mPaginationPaint.setAlpha((int) (alpha * DOT_ALPHA_FRACTION));
for (int i = 0; i < mNumPages; i++) {
canvas.drawCircle(x, y, mDotRadius, mPaginationPaint);
x += circleGap;
}
// Here we draw the current page indicator
- mPaginationPaint.setAlpha(SHOW_DOT_PAGINATION.get() ? alpha : PAGE_INDICATOR_ALPHA);
+ mPaginationPaint.setAlpha(alpha);
canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint);
}
}
@@ -498,7 +502,7 @@
@Override
public void onAnimationEnd(Animator animation) {
if (!mCancelled) {
- if (mShouldAutoHide && SHOW_DOT_PAGINATION.get()) {
+ if (mShouldAutoHide) {
hideAfterDelay();
}
mAnimator = null;
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 92822ab..e2b1286 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -17,6 +17,7 @@
package com.android.launcher3.pm;
import static com.android.launcher3.Utilities.ATLEAST_U;
+import static com.android.launcher3.uioverrides.ApiWrapper.queryAllUsers;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
@@ -24,7 +25,6 @@
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.ArrayMap;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
@@ -33,6 +33,7 @@
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.launcher3.util.UserIconInfo;
import java.util.ArrayList;
import java.util.Collections;
@@ -65,7 +66,7 @@
private final Context mContext;
@NonNull
- private Map<UserHandle, Long> mUserToSerialMap;
+ private Map<UserHandle, UserIconInfo> mUserToSerialMap;
private UserCache(Context context) {
mContext = context;
@@ -103,7 +104,7 @@
@WorkerThread
private void updateCache() {
- mUserToSerialMap = queryAllUsers(mContext.getSystemService(UserManager.class));
+ mUserToSerialMap = queryAllUsers(mContext);
}
/**
@@ -118,19 +119,26 @@
* @see UserManager#getSerialNumberForUser(UserHandle)
*/
public long getSerialNumberForUser(UserHandle user) {
- Long serial = mUserToSerialMap.get(user);
- return serial == null ? 0 : serial;
+ return getUserInfo(user).userSerial;
+ }
+
+ /**
+ * Returns the user properties for the provided user or default values
+ */
+ @NonNull
+ public UserIconInfo getUserInfo(UserHandle user) {
+ UserIconInfo info = mUserToSerialMap.get(user);
+ return info == null ? new UserIconInfo(user, UserIconInfo.TYPE_MAIN) : info;
}
/**
* @see UserManager#getUserForSerialNumber(long)
*/
public UserHandle getUserForSerialNumber(long serialNumber) {
- Long value = serialNumber;
return mUserToSerialMap
.entrySet()
.stream()
- .filter(entry -> value.equals(entry.getValue()))
+ .filter(entry -> serialNumber == entry.getValue().userSerial)
.findFirst()
.map(Map.Entry::getKey)
.orElse(Process.myUserHandle());
@@ -142,16 +150,4 @@
public List<UserHandle> getUserProfiles() {
return List.copyOf(mUserToSerialMap.keySet());
}
-
- private static Map<UserHandle, Long> queryAllUsers(UserManager userManager) {
- Map<UserHandle, Long> users = new ArrayMap<>();
- List<UserHandle> usersActual = userManager.getUserProfiles();
- if (usersActual != null) {
- for (UserHandle user : usersActual) {
- long serial = userManager.getSerialNumberForUser(user);
- users.put(user, serial);
- }
- }
- return users;
- }
}
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index e0f245f..685e4f1 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -18,12 +18,9 @@
import static androidx.core.content.ContextCompat.getColorStateList;
-import static com.android.app.animation.Interpolators.ACCELERATED_EASE;
-import static com.android.app.animation.Interpolators.DECELERATED_EASE;
import static com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -170,7 +167,7 @@
mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children);
- if (!ENABLE_MATERIAL_U_POPUP.get() && mActivityContext.canUseMultipleShadesForPopup()) {
+ if (mActivityContext.canUseMultipleShadesForPopup()) {
mColorIds = new int[]{R.color.popup_shade_first, R.color.popup_shade_second,
R.color.popup_shade_third};
} else {
@@ -241,7 +238,6 @@
}
}
- int numVisibleChild = 0;
int numVisibleShortcut = 0;
View lastView = null;
AnimatorSet colorAnimator = new AnimatorSet();
@@ -256,26 +252,13 @@
MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams();
mlp.bottomMargin = 0;
- if (colors != null) {
- if (!ENABLE_MATERIAL_U_POPUP.get()) {
- backgroundColor = colors[numVisibleChild % colors.length];
- }
-
- if (ENABLE_MATERIAL_U_POPUP.get() && isShortcutContainer(view)) {
- setChildColor(view, colors[0], colorAnimator);
- mArrowColor = colors[0];
- }
- }
-
- // Arrow color matches the first child or the last child.
- if (!ENABLE_MATERIAL_U_POPUP.get()
- && (mIsAboveIcon || (numVisibleChild == 0 && viewGroup == this))) {
- mArrowColor = backgroundColor;
+ if (colors != null && isShortcutContainer(view)) {
+ setChildColor(view, colors[0], colorAnimator);
+ mArrowColor = colors[0];
}
if (view instanceof ViewGroup && isShortcutContainer(view)) {
assignMarginsAndBackgrounds((ViewGroup) view, backgroundColor);
- numVisibleChild++;
continue;
}
@@ -295,7 +278,6 @@
}
setChildColor(view, backgroundColor, colorAnimator);
- numVisibleChild++;
}
}
@@ -433,8 +415,7 @@
private void orientAboutObject(boolean allowAlignLeft, boolean allowAlignRight) {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
- int extraVerticalSpace = mArrowHeight + mArrowOffsetVertical
- + getResources().getDimensionPixelSize(R.dimen.popup_vertical_padding);
+ int extraVerticalSpace = mArrowHeight + mArrowOffsetVertical + getExtraVerticalOffset();
// The margins are added after we call this method, so we need to account for them here.
int numVisibleChildren = 0;
for (int i = getChildCount() - 1; i >= 0; --i) {
@@ -573,23 +554,14 @@
protected void animateOpen() {
setVisibility(View.VISIBLE);
- mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
- ? getMaterialUOpenCloseAnimator(
+ mOpenCloseAnimator = getOpenCloseAnimator(
true,
OPEN_DURATION_U,
OPEN_FADE_START_DELAY_U,
OPEN_FADE_DURATION_U,
OPEN_CHILD_FADE_START_DELAY_U,
OPEN_CHILD_FADE_DURATION_U,
- EMPHASIZED_DECELERATE)
- : getOpenCloseAnimator(
- true,
- mOpenDuration,
- mOpenFadeStartDelay,
- mOpenFadeDuration,
- mOpenChildFadeStartDelay,
- mOpenChildFadeDuration,
- DECELERATED_EASE);
+ EMPHASIZED_DECELERATE);
onCreateOpenAnimation(mOpenCloseAnimator);
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@@ -603,44 +575,6 @@
mOpenCloseAnimator.start();
}
- private AnimatorSet getOpenCloseAnimator(boolean isOpening, int totalDuration,
- int fadeStartDelay, int fadeDuration, int childFadeStartDelay,
- int childFadeDuration, Interpolator interpolator) {
- final AnimatorSet animatorSet = new AnimatorSet();
- float[] alphaValues = isOpening ? new float[] {0, 1} : new float[] {1, 0};
- float[] scaleValues = isOpening ? new float[] {0.5f, 1} : new float[] {1, 0.5f};
-
- ValueAnimator fade = ValueAnimator.ofFloat(alphaValues);
- fade.setStartDelay(fadeStartDelay);
- fade.setDuration(fadeDuration);
- fade.setInterpolator(LINEAR);
- fade.addUpdateListener(anim -> {
- float alpha = (float) anim.getAnimatedValue();
- mArrow.setAlpha(alpha);
- setAlpha(alpha);
- });
- animatorSet.play(fade);
-
- setPivotX(mIsLeftAligned ? 0 : getMeasuredWidth());
- setPivotY(mIsAboveIcon ? getMeasuredHeight() : 0);
- Animator scale = ObjectAnimator.ofFloat(this, View.SCALE_Y, scaleValues);
- scale.setDuration(totalDuration);
- scale.setInterpolator(interpolator);
- animatorSet.play(scale);
-
- if (shouldScaleArrow) {
- Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
- scaleValues);
- arrowScaleAnimator.setDuration(totalDuration);
- arrowScaleAnimator.setInterpolator(interpolator);
- animatorSet.play(arrowScaleAnimator);
- }
-
- fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
-
- return animatorSet;
- }
-
private void fadeInChildViews(ViewGroup group, float[] alphaValues, long startDelay,
long duration, AnimatorSet out) {
for (int i = group.getChildCount() - 1; i >= 0; --i) {
@@ -673,22 +607,14 @@
}
mIsOpen = false;
- mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
- ? getMaterialUOpenCloseAnimator(
+ mOpenCloseAnimator = getOpenCloseAnimator(
false,
CLOSE_DURATION_U,
CLOSE_FADE_START_DELAY_U,
CLOSE_FADE_DURATION_U,
CLOSE_CHILD_FADE_START_DELAY_U,
CLOSE_CHILD_FADE_DURATION_U,
- EMPHASIZED_ACCELERATE)
- : getOpenCloseAnimator(false,
- mCloseDuration,
- mCloseFadeStartDelay,
- mCloseFadeDuration,
- mCloseChildFadeStartDelay,
- mCloseChildFadeDuration,
- ACCELERATED_EASE);
+ EMPHASIZED_ACCELERATE);
onCreateCloseAnimation(mOpenCloseAnimator);
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@@ -705,7 +631,11 @@
mOpenCloseAnimator.start();
}
- protected AnimatorSet getMaterialUOpenCloseAnimator(boolean isOpening, int scaleDuration,
+ public int getExtraVerticalOffset() {
+ return getResources().getDimensionPixelSize(R.dimen.popup_vertical_padding);
+ }
+
+ protected AnimatorSet getOpenCloseAnimator(boolean isOpening, int scaleDuration,
int fadeStartDelay, int fadeDuration, int childFadeStartDelay, int childFadeDuration,
Interpolator interpolator) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 1f26bab..934d43b 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -20,21 +20,15 @@
import static com.android.launcher3.Utilities.ATLEAST_P;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
-import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static java.util.Collections.emptyList;
-
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
-import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
@@ -55,17 +49,12 @@
import com.android.launcher3.R;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
-import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
-import com.android.launcher3.notification.NotificationInfo;
-import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.launcher3.touch.ItemLongClickListener;
@@ -81,7 +70,7 @@
import java.util.stream.Collectors;
/**
- * A container for shortcuts to deep links and notifications associated with an app.
+ * A container for shortcuts to deep links associated with an app.
*
* @param <T> The activity on with the popup shows
*/
@@ -98,8 +87,6 @@
private final float mShortcutHeight;
private BubbleTextView mOriginalIcon;
- private int mNumNotifications;
- private NotificationContainer mNotificationContainer;
private int mContainerWidth;
private ViewGroup mWidgetContainer;
@@ -142,24 +129,12 @@
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mInterceptTouchDown.set(ev.getX(), ev.getY());
}
- if (mNotificationContainer != null
- && mNotificationContainer.onInterceptSwipeEvent(ev)) {
- return true;
- }
// Stop sending touch events to deep shortcut views if user moved beyond touch slop.
return squaredHypot(mInterceptTouchDown.x - ev.getX(), mInterceptTouchDown.y - ev.getY())
> squaredTouchSlop(getContext());
}
@Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mNotificationContainer != null) {
- return mNotificationContainer.onSwipeEvent(ev) || super.onTouchEvent(ev);
- }
- return super.onTouchEvent(ev);
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ACTION_POPUP) != 0;
}
@@ -194,14 +169,6 @@
return false;
}
- @Override
- protected void setChildColor(View view, int color, AnimatorSet animatorSetOut) {
- super.setChildColor(view, color, animatorSetOut);
- if (view.getId() == R.id.notification_container && mNotificationContainer != null) {
- mNotificationContainer.updateBackgroundColor(color, animatorSetOut);
- }
- }
-
/**
* Returns true if we can show the container.
*
@@ -213,7 +180,8 @@
}
/**
- * Shows the notifications and deep shortcuts associated with a Launcher {@param icon}.
+ * Shows a popup with shortcuts associated with a Launcher icon
+ * @param icon the app icon to show the popup for
* @return the container if shown or null.
*/
public static PopupContainerWithArrow<Launcher> showForIcon(BubbleTextView icon) {
@@ -235,21 +203,10 @@
.map(s -> s.getShortcut(launcher, item, icon))
.filter(Objects::nonNull)
.collect(Collectors.toList());
- if (ENABLE_MATERIAL_U_POPUP.get()) {
- container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
- R.layout.popup_container_material_u, launcher.getDragLayer(), false);
- container.configureForLauncher(launcher);
- container.populateAndShowRowsMaterialU(icon, deepShortcutCount, systemShortcuts);
- } else {
- container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
- R.layout.popup_container, launcher.getDragLayer(), false);
- container.configureForLauncher(launcher);
- container.populateAndShow(
- icon,
- deepShortcutCount,
- popupDataProvider.getNotificationKeysForItem(item),
- systemShortcuts);
- }
+ container = (PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
+ R.layout.popup_container, launcher.getDragLayer(), false);
+ container.configureForLauncher(launcher);
+ container.populateAndShowRows(icon, deepShortcutCount, systemShortcuts);
launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
container.requestFocus();
return container;
@@ -263,91 +220,6 @@
launcher.getDragController().addDragListener(this);
}
- private void initializeSystemShortcuts(List<SystemShortcut> shortcuts) {
- if (shortcuts.isEmpty()) {
- return;
- }
- // If there is only 1 shortcut, add it to its own container so it can show text and icon
- if (shortcuts.size() == 1) {
- mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
- this, 0);
- initializeSystemShortcut(R.layout.system_shortcut, mSystemShortcutContainer,
- shortcuts.get(0), false);
- return;
- }
- addSystemShortcutsIconsOnly(shortcuts);
- }
-
- @TargetApi(Build.VERSION_CODES.P)
- public void populateAndShow(final BubbleTextView originalIcon, int shortcutCount,
- final List<NotificationKeyData> notificationKeys, List<SystemShortcut> shortcuts) {
- mNumNotifications = notificationKeys.size();
- mOriginalIcon = originalIcon;
-
- boolean hasDeepShortcuts = shortcutCount > 0;
- mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
-
- // Add views
- if (mNumNotifications > 0) {
- // Add notification entries
- if (mNotificationContainer == null) {
- mNotificationContainer = findViewById(R.id.notification_container);
- mNotificationContainer.setVisibility(VISIBLE);
- mNotificationContainer.setPopupView(this);
- } else {
- mNotificationContainer.setVisibility(GONE);
- }
- updateNotificationHeader();
- }
- mSystemShortcutContainer = this;
- if (mDeepShortcutContainer == null) {
- mDeepShortcutContainer = findViewById(R.id.deep_shortcuts_container);
- }
- if (hasDeepShortcuts) {
- List<SystemShortcut> systemShortcuts = getNonWidgetSystemShortcuts(shortcuts);
- // if there are deep shortcuts, we might want to increase the width of shortcuts to fit
- // horizontally laid out system shortcuts.
- mContainerWidth = Math.max(mContainerWidth,
- systemShortcuts.size() * getResources()
- .getDimensionPixelSize(R.dimen.system_shortcut_header_icon_touch_size)
- );
-
- mDeepShortcutContainer.setVisibility(View.VISIBLE);
-
- for (int i = shortcutCount; i > 0; i--) {
- DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, mDeepShortcutContainer);
- v.getLayoutParams().width = mContainerWidth;
- mDeepShortcuts.add(v);
- }
- updateHiddenShortcuts();
- Optional<SystemShortcut.Widgets> widgetShortcutOpt = getWidgetShortcut(shortcuts);
- if (widgetShortcutOpt.isPresent()) {
- if (mWidgetContainer == null) {
- mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container, this, 0);
- }
- initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
- }
-
- initializeSystemShortcuts(systemShortcuts);
- } else {
- mDeepShortcutContainer.setVisibility(View.GONE);
- mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_rows_container,
- this, 0);
- mWidgetContainer = mSystemShortcutContainer;
- if (!shortcuts.isEmpty()) {
- for (int i = 0; i < shortcuts.size(); i++) {
- initializeSystemShortcut(
- R.layout.system_shortcut,
- mSystemShortcutContainer,
- shortcuts.get(i),
- i < shortcuts.size() - 1);
- }
- }
- }
- show();
- loadAppShortcuts((ItemInfo) originalIcon.getTag(), notificationKeys);
- }
-
/**
* Populate and show shortcuts for the Launcher U app shortcut design.
* Will inflate the container and shortcut View instances for the popup container.
@@ -355,28 +227,27 @@
* @param deepShortcutCount Number of DeepShortcutView instances to add to container
* @param systemShortcuts List of SystemShortcuts to add to container
*/
- public void populateAndShowRowsMaterialU(final BubbleTextView originalIcon,
+ public void populateAndShowRows(final BubbleTextView originalIcon,
int deepShortcutCount, List<SystemShortcut> systemShortcuts) {
mOriginalIcon = originalIcon;
mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
if (deepShortcutCount > 0) {
- addAllShortcutsMaterialU(deepShortcutCount, systemShortcuts);
+ addAllShortcuts(deepShortcutCount, systemShortcuts);
} else if (!systemShortcuts.isEmpty()) {
- addSystemShortcutsMaterialU(systemShortcuts,
- R.layout.system_shortcut_rows_container_material_u,
+ addSystemShortcuts(systemShortcuts,
+ R.layout.system_shortcut_rows_container,
R.layout.system_shortcut);
}
show();
- loadAppShortcuts((ItemInfo) originalIcon.getTag(), /* notificationKeys= */ emptyList());
+ loadAppShortcuts((ItemInfo) originalIcon.getTag());
}
/**
* Animates and loads shortcuts on background thread for this popup container
*/
- private void loadAppShortcuts(ItemInfo originalItemInfo,
- List<NotificationKeyData> notificationKeys) {
+ private void loadAppShortcuts(ItemInfo originalItemInfo) {
if (ATLEAST_P) {
setAccessibilityPaneTitle(getTitleForAccessibility());
@@ -387,7 +258,7 @@
// Load the shortcuts on a background thread and update the container as it animates.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
mActivityContext, originalItemInfo, new Handler(Looper.getMainLooper()),
- this, mDeepShortcuts, notificationKeys));
+ this, mDeepShortcuts));
}
/**
@@ -396,16 +267,16 @@
* @param deepShortcutCount number of DeepShortcutView instances
* @param systemShortcuts List of SystemShortcuts
*/
- private void addAllShortcutsMaterialU(int deepShortcutCount,
+ private void addAllShortcuts(int deepShortcutCount,
List<SystemShortcut> systemShortcuts) {
if (deepShortcutCount + systemShortcuts.size() <= SHORTCUT_COLLAPSE_THRESHOLD) {
// add all system shortcuts including widgets shortcut to same container
- addSystemShortcutsMaterialU(systemShortcuts,
- R.layout.system_shortcut_rows_container_material_u,
+ addSystemShortcuts(systemShortcuts,
+ R.layout.system_shortcut_rows_container,
R.layout.system_shortcut);
float currentHeight = (mShortcutHeight * systemShortcuts.size())
+ mChildContainerMargin;
- addDeepShortcutsMaterialU(deepShortcutCount, currentHeight);
+ addDeepShortcuts(deepShortcutCount, currentHeight);
return;
}
@@ -426,7 +297,7 @@
initializeWidgetShortcut(mWidgetContainer, widgetShortcutOpt.get());
currentHeight += mShortcutHeight + mChildContainerMargin;
}
- addDeepShortcutsMaterialU(deepShortcutCount, currentHeight);
+ addDeepShortcuts(deepShortcutCount, currentHeight);
}
/**
@@ -464,7 +335,7 @@
* @param systemShortcutContainerLayout Layout Resource for the Container of shortcut Views
* @param systemShortcutLayout Layout Resource for the individual shortcut Views
*/
- private void addSystemShortcutsMaterialU(List<SystemShortcut> systemShortcuts,
+ private void addSystemShortcuts(List<SystemShortcut> systemShortcuts,
@LayoutRes int systemShortcutContainerLayout, @LayoutRes int systemShortcutLayout) {
if (systemShortcuts.size() == 0) {
@@ -486,9 +357,7 @@
return;
}
- mSystemShortcutContainer = ENABLE_MATERIAL_U_POPUP.get()
- ? inflateAndAdd(R.layout.system_shortcut_icons_container_material_u, this)
- : inflateAndAdd(R.layout.system_shortcut_icons_container, this, 0);
+ mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons_container, this);
for (int i = 0; i < systemShortcuts.size(); i++) {
@LayoutRes int shortcutIconLayout = R.layout.system_shortcut_icon_only;
@@ -513,13 +382,13 @@
* @param deepShortcutCount number of DeepShortcutView instances to add
* @param currentHeight height of popup before adding deep shortcuts
*/
- private void addDeepShortcutsMaterialU(int deepShortcutCount, float currentHeight) {
+ private void addDeepShortcuts(int deepShortcutCount, float currentHeight) {
mDeepShortcutContainer = inflateAndAdd(R.layout.deep_shortcut_container, this);
for (int i = deepShortcutCount; i > 0; i--) {
currentHeight += mShortcutHeight;
// when there is limited vertical screen space, limit total popup rows to fit
if (currentHeight >= mActivityContext.getDeviceProfile().availableHeightPx) break;
- DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut_material_u,
+ DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut,
mDeepShortcutContainer);
v.getLayoutParams().width = mContainerWidth;
mDeepShortcuts.add(v);
@@ -527,10 +396,6 @@
updateHiddenShortcuts();
}
- protected NotificationContainer getNotificationContainer() {
- return mNotificationContainer;
- }
-
protected BubbleTextView getOriginalIcon() {
return mOriginalIcon;
}
@@ -548,9 +413,7 @@
}
private String getTitleForAccessibility() {
- return getContext().getString(mNumNotifications == 0 ?
- R.string.action_deep_shortcut :
- R.string.shortcuts_menu_with_notifications_description);
+ return getContext().getString(R.string.action_deep_shortcut);
}
@Override
@@ -564,20 +427,11 @@
: mOriginalIcon.getHeight());
}
- public void applyNotificationInfos(List<NotificationInfo> notificationInfos) {
- if (mNotificationContainer != null) {
- mNotificationContainer.applyNotificationInfos(notificationInfos);
- }
- }
-
protected void updateHiddenShortcuts() {
- int allowedCount = mNotificationContainer != null
- ? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS;
-
int total = mDeepShortcuts.size();
for (int i = 0; i < total; i++) {
DeepShortcutView view = mDeepShortcuts.get(i);
- view.setVisibility(i >= allowedCount ? GONE : VISIBLE);
+ view.setVisibility(i >= MAX_SHORTCUTS ? GONE : VISIBLE);
}
}
@@ -666,14 +520,6 @@
};
}
- protected void updateNotificationHeader() {
- ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
- DotInfo dotInfo = mActivityContext.getDotInfoForItem(itemInfo);
- if (mNotificationContainer != null && dotInfo != null) {
- mNotificationContainer.updateHeader(dotInfo.getNotificationCount());
- }
- }
-
@Override
public void onDropCompleted(View target, DragObject d, boolean success) { }
diff --git a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
index c5d5452..9d6f2a5 100644
--- a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
+++ b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
@@ -15,22 +15,12 @@
*/
package com.android.launcher3.popup;
-import static android.view.View.GONE;
-
import android.content.Context;
import android.view.View;
import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
-import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.views.ActivityContext;
-import java.util.Map;
-import java.util.function.Predicate;
-
/**
* Utility class to handle updates while the popup is visible (like widgets and
* notification changes)
@@ -67,40 +57,6 @@
}
}
- /**
- * Updates the notification header if the original icon's dot updated.
- */
- @Override
- public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
- ItemInfo itemInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
- PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
- if (updatedDots.test(packageUser)) {
- mPopupContainerWithArrow.updateNotificationHeader();
- }
- }
-
-
- @Override
- public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
- NotificationContainer notificationContainer =
- mPopupContainerWithArrow.getNotificationContainer();
- if (notificationContainer == null) {
- return;
- }
- ItemInfo originalInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
- DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
- if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
- // No more notifications, remove the notification views and expand all shortcuts.
- notificationContainer.setVisibility(GONE);
- mPopupContainerWithArrow.updateHiddenShortcuts();
- mPopupContainerWithArrow.assignMarginsAndBackgrounds(mPopupContainerWithArrow);
- mPopupContainerWithArrow.updateArrowColor();
- } else {
- notificationContainer.trimNotifications(
- NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
- }
- }
-
@Override
public void onSystemShortcutsUpdated() {
mPopupContainerWithArrow.close(true);
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index 8be4e6c..aa24f60 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -24,26 +24,19 @@
import android.os.Handler;
import android.os.UserHandle;
-import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationInfo;
-import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.List;
-import java.util.stream.Collectors;
/**
* Contains logic relevant to populating a {@link PopupContainerWithArrow}. In particular,
@@ -52,24 +45,20 @@
public class PopupPopulator {
public static final int MAX_SHORTCUTS = 4;
- @VisibleForTesting static final int NUM_DYNAMIC = 2;
- public static final int MAX_SHORTCUTS_IF_NOTIFICATIONS = 2;
+ @VisibleForTesting
+ static final int NUM_DYNAMIC = 2;
/**
* Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts.
*/
- private static final Comparator<ShortcutInfo> SHORTCUT_RANK_COMPARATOR
- = new Comparator<ShortcutInfo>() {
- @Override
- public int compare(ShortcutInfo a, ShortcutInfo b) {
- if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
- return -1;
- }
- if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
- return 1;
- }
- return Integer.compare(a.getRank(), b.getRank());
+ private static final Comparator<ShortcutInfo> SHORTCUT_RANK_COMPARATOR = (a, b) -> {
+ if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
+ return -1;
}
+ if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
+ return 1;
+ }
+ return Integer.compare(a.getRank(), b.getRank());
};
/**
@@ -77,23 +66,10 @@
* We want the filter to include both static and dynamic shortcuts, so we always
* include NUM_DYNAMIC dynamic shortcuts, if at least that many are present.
*
- * @param shortcutIdToRemoveFirst An id that should be filtered out first, if any.
* @return a subset of shortcuts, in sorted order, with size <= MAX_SHORTCUTS.
*/
- public static List<ShortcutInfo> sortAndFilterShortcuts(
- List<ShortcutInfo> shortcuts, @Nullable String shortcutIdToRemoveFirst) {
- // Remove up to one specific shortcut before sorting and doing somewhat fancy filtering.
- if (shortcutIdToRemoveFirst != null) {
- Iterator<ShortcutInfo> shortcutIterator = shortcuts.iterator();
- while (shortcutIterator.hasNext()) {
- if (shortcutIterator.next().getId().equals(shortcutIdToRemoveFirst)) {
- shortcutIterator.remove();
- break;
- }
- }
- }
-
- Collections.sort(shortcuts, SHORTCUT_RANK_COMPARATOR);
+ public static List<ShortcutInfo> sortAndFilterShortcuts(List<ShortcutInfo> shortcuts) {
+ shortcuts.sort(SHORTCUT_RANK_COMPARATOR);
if (shortcuts.size() <= MAX_SHORTCUTS) {
return shortcuts;
}
@@ -127,37 +103,20 @@
}
/**
- * Returns a runnable to update the provided shortcuts and notifications
+ * Returns a runnable to update the provided shortcuts
*/
public static <T extends Context & ActivityContext> Runnable createUpdateRunnable(
final T context,
final ItemInfo originalInfo,
final Handler uiHandler, final PopupContainerWithArrow container,
- final List<DeepShortcutView> shortcutViews,
- final List<NotificationKeyData> notificationKeys) {
+ final List<DeepShortcutView> shortcutViews) {
final ComponentName activity = originalInfo.getTargetComponent();
final UserHandle user = originalInfo.user;
return () -> {
- if (!notificationKeys.isEmpty()) {
- NotificationListener notificationListener =
- NotificationListener.getInstanceIfConnected();
- final List<NotificationInfo> infos;
- if (notificationListener == null) {
- infos = Collections.emptyList();
- } else {
- infos = notificationListener.getNotificationsForKeys(notificationKeys).stream()
- .map(sbn -> new NotificationInfo(context, sbn, originalInfo))
- .collect(Collectors.toList());
- }
- uiHandler.post(() -> container.applyNotificationInfos(infos));
- }
-
List<ShortcutInfo> shortcuts = new ShortcutRequest(context, user)
.withContainer(activity)
.query(ShortcutRequest.PUBLISHED);
- String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
- : notificationKeys.get(0).shortcutId;
- shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
+ shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts);
IconCache cache = LauncherAppState.getInstance(context).getIconCache();
for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
final ShortcutInfo shortcut = shortcuts.get(i);
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 575551b..30958d9 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -16,6 +16,7 @@
package com.android.launcher3.provider;
+import static com.android.launcher3.LauncherSettings.Favorites.getColumns;
import static com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE;
import android.content.ContentValues;
@@ -48,7 +49,6 @@
* A set of utility methods for Launcher DB used for DB updates and migration.
*/
public class LauncherDbUtils {
-
/**
* Returns a string which can be used as a where clause for DB query to match the given itemId
*/
@@ -90,10 +90,12 @@
if (fromDb != toDb) {
toDb.execSQL("ATTACH DATABASE '" + fromDb.getPath() + "' AS from_db");
toDb.execSQL(
- "INSERT INTO " + toTable + " SELECT * FROM from_db." + fromTable);
+ "INSERT INTO " + toTable + " SELECT " + getColumns(userSerial)
+ + " FROM from_db." + fromTable);
toDb.execSQL("DETACH DATABASE 'from_db'");
} else {
- toDb.execSQL("INSERT INTO " + toTable + " SELECT * FROM " + fromTable);
+ toDb.execSQL("INSERT INTO " + toTable + " SELECT " + getColumns(userSerial) + " FROM "
+ + fromTable);
}
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 4725dd1..dbd13b3 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -28,6 +28,8 @@
import android.app.backup.BackupManager;
import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -42,20 +44,26 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
-import com.android.launcher3.AppWidgetsRestoredReceiver;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherPrefs;
+import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
+import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelDbController;
+import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LogConfig;
@@ -377,11 +385,13 @@
.putSync(RESTORE_DEVICE.to(new DeviceGridState(context).getDeviceType()));
}
- private void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) {
+ @WorkerThread
+ @VisibleForTesting
+ void restoreAppWidgetIdsIfExists(Context context, ModelDbController controller) {
LauncherPrefs lp = LauncherPrefs.get(context);
if (lp.has(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS)) {
AppWidgetHost host = new AppWidgetHost(context, APPWIDGET_HOST_ID);
- AppWidgetsRestoredReceiver.restoreAppWidgetIds(context, controller,
+ restoreAppWidgetIds(context, controller,
IntArray.fromConcatString(lp.get(OLD_APP_WIDGET_IDS)).toArray(),
IntArray.fromConcatString(lp.get(APP_WIDGET_IDS)).toArray(),
host);
@@ -392,11 +402,131 @@
lp.remove(APP_WIDGET_IDS, OLD_APP_WIDGET_IDS);
}
- public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds,
- @NonNull int[] newIds) {
- LauncherPrefs.get(context).putSync(
- OLD_APP_WIDGET_IDS.to(IntArray.wrap(oldIds).toConcatString()),
- APP_WIDGET_IDS.to(IntArray.wrap(newIds).toConcatString()));
+ /**
+ * Updates the app widgets whose id has changed during the restore process.
+ */
+ @WorkerThread
+ private void restoreAppWidgetIds(Context context, ModelDbController controller,
+ int[] oldWidgetIds, int[] newWidgetIds, @NonNull AppWidgetHost host) {
+ if (WidgetsModel.GO_DISABLE_WIDGETS) {
+ Log.e(TAG, "Skipping widget ID remap as widgets not supported");
+ host.deleteHost();
+ return;
+ }
+ if (!RestoreDbTask.isPending(context)) {
+ // Someone has already gone through our DB once, probably LoaderTask. Skip any further
+ // modifications of the DB.
+ Log.e(TAG, "Skipping widget ID remap as DB already in use");
+ for (int widgetId : newWidgetIds) {
+ Log.d(TAG, "Deleting widgetId: " + widgetId);
+ host.deleteAppWidgetId(widgetId);
+ }
+ return;
+ }
+
+ final AppWidgetManager widgets = AppWidgetManager.getInstance(context);
+
+ Log.d(TAG, "restoreAppWidgetIds: "
+ + "oldWidgetIds=" + IntArray.wrap(oldWidgetIds).toConcatString()
+ + ", newWidgetIds=" + IntArray.wrap(newWidgetIds).toConcatString());
+
+ // TODO(b/234700507): Remove the logs after the bug is fixed
+ logDatabaseWidgetInfo(controller);
+
+ for (int i = 0; i < oldWidgetIds.length; i++) {
+ Log.i(TAG, "Widget state restore id " + oldWidgetIds[i] + " => " + newWidgetIds[i]);
+
+ final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
+ final int state;
+ if (LoaderTask.isValidProvider(provider)) {
+ // This will ensure that we show 'Click to setup' UI if required.
+ state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
+ } else {
+ state = LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
+ }
+
+ // b/135926478: Work profile widget restore is broken in platform. This forces us to
+ // recreate the widget during loading with the correct host provider.
+ long mainProfileId = UserCache.INSTANCE.get(context)
+ .getSerialNumberForUser(myUserHandle());
+ long controllerProfileId = controller.getSerialNumberForUser(myUserHandle());
+ String oldWidgetId = Integer.toString(oldWidgetIds[i]);
+ final String where = "appWidgetId=? and (restored & 1) = 1 and profileId=?";
+ String profileId = Long.toString(mainProfileId);
+ final String[] args = new String[] { oldWidgetId, profileId };
+ Log.d(TAG, "restoreAppWidgetIds: querying profile id=" + profileId
+ + " with controller profile ID=" + controllerProfileId);
+ int result = new ContentWriter(context,
+ new ContentWriter.CommitParams(controller, where, args))
+ .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
+ .put(LauncherSettings.Favorites.RESTORED, state)
+ .commit();
+ if (result == 0) {
+ // TODO(b/234700507): Remove the logs after the bug is fixed
+ Log.e(TAG, "restoreAppWidgetIds: remapping failed since the widget is not in"
+ + " the database anymore");
+ try (Cursor cursor = controller.getDb().query(
+ Favorites.TABLE_NAME,
+ new String[]{Favorites.APPWIDGET_ID},
+ "appWidgetId=?", new String[]{oldWidgetId}, null, null, null)) {
+ if (!cursor.moveToFirst()) {
+ // The widget no long exists.
+ Log.d(TAG, "Deleting widgetId: " + newWidgetIds[i] + " with old id: "
+ + oldWidgetId);
+ host.deleteAppWidgetId(newWidgetIds[i]);
+ }
+ }
+ }
+ }
+
+ LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+ if (app != null) {
+ app.getModel().forceReload();
+ }
+ }
+
+ private static void logDatabaseWidgetInfo(ModelDbController controller) {
+ try (Cursor cursor = controller.getDb().query(Favorites.TABLE_NAME,
+ new String[]{Favorites.APPWIDGET_ID, Favorites.RESTORED, Favorites.PROFILE_ID},
+ Favorites.APPWIDGET_ID + "!=" + LauncherAppWidgetInfo.NO_ID, null,
+ null, null, null)) {
+ IntArray widgetIdList = new IntArray();
+ IntArray widgetRestoreList = new IntArray();
+ IntArray widgetProfileIdList = new IntArray();
+
+ if (cursor.moveToFirst()) {
+ final int widgetIdColumnIndex = cursor.getColumnIndex(Favorites.APPWIDGET_ID);
+ final int widgetRestoredColumnIndex = cursor.getColumnIndex(Favorites.RESTORED);
+ final int widgetProfileIdIndex = cursor.getColumnIndex(Favorites.PROFILE_ID);
+ while (!cursor.isAfterLast()) {
+ int widgetId = cursor.getInt(widgetIdColumnIndex);
+ int widgetRestoredFlag = cursor.getInt(widgetRestoredColumnIndex);
+ int widgetProfileId = cursor.getInt(widgetProfileIdIndex);
+
+ widgetIdList.add(widgetId);
+ widgetRestoreList.add(widgetRestoredFlag);
+ widgetProfileIdList.add(widgetProfileId);
+ cursor.moveToNext();
+ }
+ }
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("[");
+ for (int i = 0; i < widgetIdList.size(); i++) {
+ builder.append("[")
+ .append(widgetIdList.get(i))
+ .append(", ")
+ .append(widgetRestoreList.get(i))
+ .append(", ")
+ .append(widgetProfileIdList.get(i))
+ .append("]");
+ }
+ builder.append("]");
+ Log.d(TAG, "restoreAppWidgetIds: all widget ids in database: "
+ + builder.toString());
+ } catch (Exception ex) {
+ Log.e(TAG, "Getting widget ids from the database failed", ex);
+ }
}
protected static void maybeOverrideShortcuts(Context context, ModelDbController controller,
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 1e3be27..f0f376f 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -20,6 +20,8 @@
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_PROVIDER;
+import static com.android.launcher3.config.FeatureFlags.shouldShowFirstPageWidget;
+
import android.app.Activity;
import android.app.Fragment;
import android.app.SearchManager;
@@ -290,7 +292,7 @@
}
public boolean isQsbEnabled() {
- return FeatureFlags.QSB_ON_FIRST_SCREEN;
+ return FeatureFlags.QSB_ON_FIRST_SCREEN && !shouldShowFirstPageWidget();
}
protected Bundle createBindOptions() {
diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
index 3c59c1d..45174a7 100644
--- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
+++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt
@@ -40,6 +40,8 @@
private var future: Future<Void>? = null
+ var hasWorkProfile = false
+
/**
* Preinflate app icons. If all apps RV cannot be scrolled down, we don't need to preinflate.
*/
@@ -93,9 +95,10 @@
EXTRA_ICONS_COUNT
if (FeatureFlags.ALL_APPS_GONE_VISIBILITY.get()) {
val grid = ActivityContext.lookupContext<T>(context).deviceProfile
- val approxRows =
- Math.ceil((grid.availableHeightPx / grid.allAppsIconSizePx).toDouble()).toInt()
- targetPreinflateCount += (approxRows + 1) * grid.numShownAllAppsColumns
+ targetPreinflateCount += grid.maxAllAppsRowCount * grid.numShownAllAppsColumns
+ }
+ if (hasWorkProfile) {
+ targetPreinflateCount *= 2
}
val existingPreinflateCount = getRecycledViewCount(BaseAllAppsAdapter.VIEW_TYPE_ICON)
return targetPreinflateCount - existingPreinflateCount
diff --git a/src/com/android/launcher3/responsive/HotseatSpecs.kt b/src/com/android/launcher3/responsive/HotseatSpecs.kt
index 482508d..37a682f 100644
--- a/src/com/android/launcher3/responsive/HotseatSpecs.kt
+++ b/src/com/android/launcher3/responsive/HotseatSpecs.kt
@@ -21,14 +21,28 @@
import com.android.launcher3.R
import com.android.launcher3.util.ResourceHelper
-class HotseatSpecs(val specs: List<HotseatSpec>) {
+class HotseatSpecs(widthSpecs: List<HotseatSpec>, heightSpecs: List<HotseatSpec>) {
+
+ val widthSpecs: List<HotseatSpec>
+ val heightSpecs: List<HotseatSpec>
+
+ init {
+ this.widthSpecs = widthSpecs.sortedBy { it.maxAvailableSize }
+ this.heightSpecs = heightSpecs.sortedBy { it.maxAvailableSize }
+ }
fun getCalculatedHeightSpec(availableHeight: Int): CalculatedHotseatSpec {
- val spec = specs.firstOrNull { availableHeight <= it.maxAvailableSize }
+ val spec = heightSpecs.firstOrNull { availableHeight <= it.maxAvailableSize }
check(spec != null) { "No available height spec found within $availableHeight." }
return CalculatedHotseatSpec(availableHeight, spec)
}
+ fun getCalculatedWidthSpec(availableWidth: Int): CalculatedHotseatSpec {
+ val spec = widthSpecs.firstOrNull { availableWidth <= it.maxAvailableSize }
+ check(spec != null) { "No available width spec found within $availableWidth." }
+ return CalculatedHotseatSpec(availableWidth, spec)
+ }
+
companion object {
private const val XML_HOTSEAT_SPEC = "hotseatSpec"
@@ -36,7 +50,9 @@
fun create(resourceHelper: ResourceHelper): HotseatSpecs {
val parser = ResponsiveSpecsParser(resourceHelper)
val specs = parser.parseXML(XML_HOTSEAT_SPEC, ::HotseatSpec)
- return HotseatSpecs(specs.filter { it.specType == ResponsiveSpec.SpecType.HEIGHT })
+ val (widthSpecs, heightSpecs) =
+ specs.partition { it.specType == ResponsiveSpec.SpecType.WIDTH }
+ return HotseatSpecs(widthSpecs, heightSpecs)
}
}
}
@@ -44,7 +60,8 @@
data class HotseatSpec(
val maxAvailableSize: Int,
val specType: ResponsiveSpec.SpecType,
- val hotseatQsbSpace: SizeSpec
+ val hotseatQsbSpace: SizeSpec,
+ val edgePadding: SizeSpec
) {
init {
@@ -63,7 +80,8 @@
R.styleable.ResponsiveSpec_specType,
ResponsiveSpec.SpecType.HEIGHT.ordinal
)],
- hotseatQsbSpace = specs.getOrError(SizeSpec.XmlTags.HOTSEAT_QSB_SPACE)
+ hotseatQsbSpace = specs.getOrError(SizeSpec.XmlTags.HOTSEAT_QSB_SPACE),
+ edgePadding = specs.getOrError(SizeSpec.XmlTags.EDGE_PADDING)
)
fun isValid(): Boolean {
@@ -82,7 +100,10 @@
}
private fun allSpecsAreValid(): Boolean {
- return hotseatQsbSpace.isValid() && hotseatQsbSpace.onlyFixedSize()
+ return hotseatQsbSpace.isValid() &&
+ hotseatQsbSpace.onlyFixedSize() &&
+ edgePadding.isValid() &&
+ edgePadding.onlyFixedSize()
}
companion object {
@@ -95,13 +116,18 @@
var hotseatQsbSpace: Int = 0
private set
+ var edgePadding: Int = 0
+ private set
+
init {
hotseatQsbSpace = spec.hotseatQsbSpace.getCalculatedValue(availableSpace)
+ edgePadding = spec.edgePadding.getCalculatedValue(availableSpace)
}
override fun hashCode(): Int {
var result = availableSpace.hashCode()
result = 31 * result + hotseatQsbSpace.hashCode()
+ result = 31 * result + edgePadding.hashCode()
result = 31 * result + spec.hashCode()
return result
}
@@ -110,12 +136,14 @@
return other is CalculatedHotseatSpec &&
availableSpace == other.availableSpace &&
hotseatQsbSpace == other.hotseatQsbSpace &&
+ edgePadding == other.edgePadding &&
spec == other.spec
}
override fun toString(): String {
return "${this::class.simpleName}(" +
"availableSpace=$availableSpace, hotseatQsbSpace=$hotseatQsbSpace, " +
+ "edgePadding=$edgePadding, " +
"${spec::class.simpleName}.maxAvailableSize=${spec.maxAvailableSize}" +
")"
}
diff --git a/src/com/android/launcher3/responsive/ResponsiveSpecs.kt b/src/com/android/launcher3/responsive/ResponsiveSpecs.kt
index 72a0ea4..a43c44a 100644
--- a/src/com/android/launcher3/responsive/ResponsiveSpecs.kt
+++ b/src/com/android/launcher3/responsive/ResponsiveSpecs.kt
@@ -24,10 +24,9 @@
* @param widthSpecs List of width responsive specifications
* @param heightSpecs List of height responsive specifications
*/
-abstract class ResponsiveSpecs<T : ResponsiveSpec>(
- val widthSpecs: List<T>,
+abstract class ResponsiveSpecs<T : ResponsiveSpec>(widthSpecs: List<T>, heightSpecs: List<T>) {
+ val widthSpecs: List<T>
val heightSpecs: List<T>
-) {
init {
check(widthSpecs.isNotEmpty() && heightSpecs.isNotEmpty()) {
@@ -35,6 +34,9 @@
"width list size = ${widthSpecs.size}; " +
"height list size = ${heightSpecs.size}."
}
+
+ this.widthSpecs = widthSpecs.sortedBy { it.maxAvailableSize }
+ this.heightSpecs = heightSpecs.sortedBy { it.maxAvailableSize }
}
/**
diff --git a/src/com/android/launcher3/responsive/SizeSpec.kt b/src/com/android/launcher3/responsive/SizeSpec.kt
index c868c9f..2db843b 100644
--- a/src/com/android/launcher3/responsive/SizeSpec.kt
+++ b/src/com/android/launcher3/responsive/SizeSpec.kt
@@ -121,6 +121,7 @@
const val GUTTER = "gutter"
const val CELL_SIZE = "cellSize"
const val HOTSEAT_QSB_SPACE = "hotseatQsbSpace"
+ const val EDGE_PADDING = "edgePadding"
}
companion object {
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index a10c0ad..910b029 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -36,7 +36,6 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
@@ -56,7 +55,6 @@
import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Themes;
@@ -82,7 +80,6 @@
private boolean mAppDrawerShown = false;
private StringCache mStringCache;
- private OnboardingPrefs<?> mOnboardingPrefs;
private boolean mBindingItems = false;
private SecondaryDisplayPredictions mSecondaryDisplayPredictions;
@@ -93,7 +90,6 @@
super.onCreate(savedInstanceState);
mModel = LauncherAppState.getInstance(this).getModel();
mDragController = new SecondaryDragController(this);
- mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
if (getWindow().getDecorView().isAttachedToWindow()) {
initUi();
@@ -272,11 +268,6 @@
}
@Override
- public OnboardingPrefs<?> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
- @Override
public void startBinding() {
mBindingItems = true;
mDragController.cancelDrag();
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index e8be12c..6e697d9 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -18,7 +18,6 @@
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import android.content.Context;
@@ -45,7 +44,6 @@
import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
@@ -203,20 +201,10 @@
}
int deepShortcutCount = popupDataProvider.getShortcutCountForItem(item);
final PopupContainerWithArrow<SecondaryDisplayLauncher> container;
- if (ENABLE_MATERIAL_U_POPUP.get()) {
- container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
- R.layout.popup_container_material_u, mActivity.getDragLayer(), false);
- container.populateAndShowRowsMaterialU((BubbleTextView) v, deepShortcutCount,
- systemShortcuts);
- } else {
- container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
- R.layout.popup_container, mActivity.getDragLayer(), false);
- container.populateAndShow(
- (BubbleTextView) v,
- deepShortcutCount,
- Collections.emptyList(),
- systemShortcuts);
- }
+ container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
+ R.layout.popup_container, mActivity.getDragLayer(), false);
+ container.populateAndShowRows((BubbleTextView) v, deepShortcutCount,
+ systemShortcuts);
container.requestFocus();
if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) {
diff --git a/src/com/android/launcher3/settings/NotificationDotsPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java
index 1816e7b..ac5571f 100644
--- a/src/com/android/launcher3/settings/NotificationDotsPreference.java
+++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java
@@ -15,8 +15,7 @@
*/
package com.android.launcher3.settings;
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGS;
+import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@@ -51,6 +50,7 @@
/** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
+ private static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
private final ContentObserver mListenerListObserver =
new ContentObserver(MAIN_EXECUTOR.getHandler()) {
@@ -88,7 +88,7 @@
// Update intent
Bundle extras = new Bundle();
- extras.putString(EXTRA_FRAGMENT_ARG_KEY, "notification_badging");
+ extras.putString(EXTRA_FRAGMENT_HIGHLIGHT_KEY, "notification_badging");
setIntent(new Intent("android.settings.NOTIFICATION_SETTINGS")
.putExtra(EXTRA_SHOW_FRAGMENT_ARGS, extras));
@@ -169,11 +169,11 @@
public void onClick(DialogInterface dialogInterface, int i) {
ComponentName cn = new ComponentName(getActivity(), NotificationListener.class);
Bundle showFragmentArgs = new Bundle();
- showFragmentArgs.putString(EXTRA_FRAGMENT_ARG_KEY, cn.flattenToString());
+ showFragmentArgs.putString(EXTRA_FRAGMENT_HIGHLIGHT_KEY, cn.flattenToString());
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(EXTRA_FRAGMENT_ARG_KEY, cn.flattenToString())
+ .putExtra(EXTRA_FRAGMENT_HIGHLIGHT_KEY, cn.flattenToString())
.putExtra(EXTRA_SHOW_FRAGMENT_ARGS, showFragmentArgs);
getActivity().startActivity(intent);
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 623b557..650fbcc 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -16,19 +16,24 @@
package com.android.launcher3.settings;
-import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
+import static android.provider.Settings.Global.DEVELOPMENT_SETTINGS_ENABLED;
-import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD;
+import static androidx.preference.PreferenceFragmentCompat.ARG_PREFERENCE_ROOT;
+
+import static com.android.launcher3.BuildConfig.IS_DEBUG_DEVICE;
+import static com.android.launcher3.BuildConfig.IS_STUDIO_BUILD;
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
+import android.app.Activity;
import android.content.Intent;
-import android.content.SharedPreferences;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.Settings;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
-import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.view.WindowCompat;
import androidx.fragment.app.DialogFragment;
@@ -36,6 +41,7 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback;
import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback;
@@ -43,59 +49,51 @@
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.BuildConfig;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.states.RotationHelper;
-import com.android.launcher3.uioverrides.flags.DeveloperOptionsFragment;
-import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.launcher3.uioverrides.flags.DeveloperOptionsUI;
import com.android.launcher3.util.DisplayController;
-
-import java.util.Collections;
-import java.util.List;
+import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.SettingsCache;
/**
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
*/
public class SettingsActivity extends FragmentActivity
- implements OnPreferenceStartFragmentCallback, OnPreferenceStartScreenCallback,
- SharedPreferences.OnSharedPreferenceChangeListener{
+ implements OnPreferenceStartFragmentCallback, OnPreferenceStartScreenCallback {
- /** List of fragments that can be hosted by this activity. */
- private static final List<String> VALID_PREFERENCE_FRAGMENTS =
- !Utilities.IS_DEBUG_DEVICE ? Collections.emptyList()
- : Collections.singletonList(DeveloperOptionsFragment.class.getName());
-
- private static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
- private static final String FLAGS_PREFERENCE_KEY = "flag_toggler";
+ @VisibleForTesting
+ static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
private static final String NOTIFICATION_DOTS_PREFERENCE_KEY = "pref_icon_badging";
- public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
- public static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args";
+ public static final String EXTRA_FRAGMENT_ARGS = ":settings:fragment_args";
+
+ // Intent extra to indicate the pref-key to highlighted when opening the settings activity
+ public static final String EXTRA_FRAGMENT_HIGHLIGHT_KEY = ":settings:fragment_args_key";
+ // Intent extra to indicate the pref-key of the root screen when opening the settings activity
+ public static final String EXTRA_FRAGMENT_ROOT_KEY = ARG_PREFERENCE_ROOT;
+
private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
public static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
- @VisibleForTesting
- static final String EXTRA_FRAGMENT = ":settings:fragment";
- @VisibleForTesting
- static final String EXTRA_FRAGMENT_ARGS = ":settings:fragment_args";
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
+
setActionBar(findViewById(R.id.action_bar));
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
Intent intent = getIntent();
- if (intent.hasExtra(EXTRA_FRAGMENT) || intent.hasExtra(EXTRA_FRAGMENT_ARGS)
- || intent.hasExtra(EXTRA_FRAGMENT_ARG_KEY)) {
+ if (intent.hasExtra(EXTRA_FRAGMENT_ROOT_KEY) || intent.hasExtra(EXTRA_FRAGMENT_ARGS)
+ || intent.hasExtra(EXTRA_FRAGMENT_HIGHLIGHT_KEY)) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@@ -105,46 +103,24 @@
args = new Bundle();
}
- String prefKey = intent.getStringExtra(EXTRA_FRAGMENT_ARG_KEY);
- if (!TextUtils.isEmpty(prefKey)) {
- args.putString(EXTRA_FRAGMENT_ARG_KEY, prefKey);
+ String highlight = intent.getStringExtra(EXTRA_FRAGMENT_HIGHLIGHT_KEY);
+ if (!TextUtils.isEmpty(highlight)) {
+ args.putString(EXTRA_FRAGMENT_HIGHLIGHT_KEY, highlight);
+ }
+ String root = intent.getStringExtra(EXTRA_FRAGMENT_ROOT_KEY);
+ if (!TextUtils.isEmpty(root)) {
+ args.putString(EXTRA_FRAGMENT_ROOT_KEY, root);
}
final FragmentManager fm = getSupportFragmentManager();
final Fragment f = fm.getFragmentFactory().instantiate(getClassLoader(),
- getPreferenceFragment());
+ getString(R.string.settings_fragment_name));
f.setArguments(args);
// Display the fragment as the main content.
fm.beginTransaction().replace(R.id.content_frame, f).commit();
}
- LauncherPrefs.getPrefs(getApplicationContext())
- .registerOnSharedPreferenceChangeListener(this);
}
- /**
- * Obtains the preference fragment to instantiate in this activity.
- *
- * @return the preference fragment class
- * @throws IllegalArgumentException if the fragment is unknown to this activity
- */
- private String getPreferenceFragment() {
- String preferenceFragment = getIntent().getStringExtra(EXTRA_FRAGMENT);
- String defaultFragment = getString(R.string.settings_fragment_name);
-
- if (TextUtils.isEmpty(preferenceFragment)) {
- return defaultFragment;
- } else if (!preferenceFragment.equals(defaultFragment)
- && !VALID_PREFERENCE_FRAGMENTS.contains(preferenceFragment)) {
- throw new IllegalArgumentException(
- "Invalid fragment for this activity: " + preferenceFragment);
- } else {
- return preferenceFragment;
- }
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { }
-
private boolean startPreference(String fragment, Bundle args, String key) {
if (Utilities.ATLEAST_P && getSupportFragmentManager().isStateSaved()) {
// Sometimes onClick can come after onPause because of being posted on the handler.
@@ -158,7 +134,6 @@
((DialogFragment) f).show(fm, key);
} else {
startActivity(new Intent(this, SettingsActivity.class)
- .putExtra(EXTRA_FRAGMENT, fragment)
.putExtra(EXTRA_FRAGMENT_ARGS, args));
}
return true;
@@ -173,7 +148,7 @@
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) {
Bundle args = new Bundle();
- args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, pref.getKey());
+ args.putString(ARG_PREFERENCE_ROOT, pref.getKey());
return startPreference(getString(R.string.settings_fragment_name), args, pref.getKey());
}
@@ -189,19 +164,31 @@
/**
* This fragment shows the launcher preferences.
*/
- public static class LauncherSettingsFragment extends PreferenceFragmentCompat {
+ public static class LauncherSettingsFragment extends PreferenceFragmentCompat implements
+ SettingsCache.OnChangeListener {
+
+ protected boolean mDeveloperOptionsEnabled = false;
+
+ private boolean mRestartOnResume = false;
private String mHighLightKey;
private boolean mPreferenceHighlighted = false;
- private Preference mDeveloperOptionPref;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ if (BuildConfig.IS_DEBUG_DEVICE) {
+ Uri devUri = Settings.Global.getUriFor(DEVELOPMENT_SETTINGS_ENABLED);
+ SettingsCache settingsCache = SettingsCache.INSTANCE.get(getContext());
+ mDeveloperOptionsEnabled = settingsCache.getValue(devUri);
+ settingsCache.register(devUri, this);
+ }
+ super.onCreate(savedInstanceState);
+ }
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final Bundle args = getArguments();
- mHighLightKey = args == null ? null : args.getString(EXTRA_FRAGMENT_ARG_KEY);
- if (rootKey == null && !TextUtils.isEmpty(mHighLightKey)) {
- rootKey = getParentKeyForPref(mHighLightKey);
- }
+ mHighLightKey = args == null ? null : args.getString(EXTRA_FRAGMENT_HIGHLIGHT_KEY);
if (savedInstanceState != null) {
mPreferenceHighlighted = savedInstanceState.getBoolean(SAVE_HIGHLIGHTED_KEY);
@@ -213,11 +200,7 @@
PreferenceScreen screen = getPreferenceScreen();
for (int i = screen.getPreferenceCount() - 1; i >= 0; i--) {
Preference preference = screen.getPreference(i);
- if (initPreference(preference)) {
- if (IS_STUDIO_BUILD && preference == mDeveloperOptionPref) {
- preference.setOrder(0);
- }
- } else {
+ if (!initPreference(preference)) {
screen.removePreference(preference);
}
}
@@ -249,6 +232,7 @@
bottomPadding + insets.getSystemWindowInsetBottom());
return insets.consumeSystemWindowInsets();
});
+
// Overriding Text Direction in the Androidx preference library to support RTL
view.setTextDirection(View.TEXT_DIRECTION_LOCALE);
}
@@ -259,10 +243,6 @@
outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mPreferenceHighlighted);
}
- protected String getParentKeyForPref(String key) {
- return null;
- }
-
/**
* Initializes a preference. This is called for every preference. Returning false here
* will remove that preference from the list.
@@ -283,51 +263,70 @@
preference.setDefaultValue(RotationHelper.getAllowRotationDefaultValue(info));
return true;
- case FLAGS_PREFERENCE_KEY:
- // Only show flag toggler UI if this build variant implements that.
- return FeatureFlags.showFlagTogglerUi(getContext());
-
case DEVELOPER_OPTIONS_KEY:
- mDeveloperOptionPref = preference;
- return updateDeveloperOption();
+ if (IS_STUDIO_BUILD) {
+ preference.setOrder(0);
+ }
+ return mDeveloperOptionsEnabled;
+ case "pref_developer_flags":
+ if (mDeveloperOptionsEnabled && preference instanceof PreferenceCategory pc) {
+ Executors.MAIN_EXECUTOR.post(() -> new DeveloperOptionsUI(this, pc));
+ return true;
+ }
+ return false;
}
return true;
}
- /**
- * Show if plugins are enabled or flag UI is enabled.
- * @return True if we should show the preference option.
- */
- private boolean updateDeveloperOption() {
- boolean showPreference = FeatureFlags.showFlagTogglerUi(getContext())
- || PluginManagerWrapper.hasPlugins(getContext());
- if (mDeveloperOptionPref != null) {
- mDeveloperOptionPref.setEnabled(showPreference);
- if (showPreference) {
- getPreferenceScreen().addPreference(mDeveloperOptionPref);
- } else {
- getPreferenceScreen().removePreference(mDeveloperOptionPref);
- }
- }
- return showPreference;
- }
-
@Override
public void onResume() {
super.onResume();
- updateDeveloperOption();
-
if (isAdded() && !mPreferenceHighlighted) {
PreferenceHighlighter highlighter = createHighlighter();
if (highlighter != null) {
getView().postDelayed(highlighter, DELAY_HIGHLIGHT_DURATION_MILLIS);
mPreferenceHighlighted = true;
- } else {
- requestAccessibilityFocus(getListView());
}
}
+
+ if (mRestartOnResume) {
+ recreateActivityNow();
+ }
+ }
+
+ @Override
+ public void onSettingsChanged(boolean isEnabled) {
+ // Developer options changed, try recreate
+ tryRecreateActivity();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ if (IS_DEBUG_DEVICE) {
+ SettingsCache.INSTANCE.get(getContext())
+ .unregister(Settings.Global.getUriFor(DEVELOPMENT_SETTINGS_ENABLED), this);
+ }
+ }
+
+ /**
+ * Tries to recreate the preference
+ */
+ protected void tryRecreateActivity() {
+ if (isResumed()) {
+ recreateActivityNow();
+ } else {
+ mRestartOnResume = true;
+ }
+ }
+
+ private void recreateActivityNow() {
+ Activity activity = getActivity();
+ if (activity != null) {
+ activity.recreate();
+ }
}
private PreferenceHighlighter createHighlighter() {
@@ -347,14 +346,5 @@
list, position, screen.findPreference(mHighLightKey))
: null;
}
-
- private void requestAccessibilityFocus(@NonNull final RecyclerView rv) {
- rv.post(() -> {
- if (!rv.hasFocus() && rv.getChildCount() > 0) {
- rv.getChildAt(0)
- .performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS, null);
- }
- });
- }
}
}
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 360ff7e..9ac8f6b 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -27,7 +27,6 @@
import android.animation.AnimatorSet;
import android.os.Handler;
import android.os.Looper;
-import android.util.Log;
import androidx.annotation.FloatRange;
@@ -36,7 +35,6 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
-import com.android.launcher3.testing.shared.TestProtocol;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -227,7 +225,6 @@
private void goToState(
STATE_TYPE state, boolean animated, long delay, AnimatorListener listener) {
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "go to state " + state);
animated &= areAnimatorsEnabled();
if (mActivity.isInState(state)) {
@@ -383,8 +380,6 @@
mState = state;
mActivity.onStateSetStart(mState);
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "Notifying listeners for state transition start"
- + " to state: " + state.toString());
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onStateTransitionStart(state);
}
@@ -402,8 +397,6 @@
setRestState(null);
}
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "Notifying " + mListeners.size() + " listeners "
- + "for end transition for state: " + state.toString());
for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onStateTransitionComplete(state);
}
@@ -441,7 +434,6 @@
* Cancels the current animation.
*/
public void cancelAnimation() {
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "current animation cancelled");
mConfig.reset();
// It could happen that a new animation is set as a result of an endListener on the
// existing animation.
@@ -465,7 +457,6 @@
* @param toState The state we are animating towards.
*/
public void setCurrentAnimation(AnimatorSet anim, STATE_TYPE toState) {
- Log.d(TestProtocol.OVERVIEW_OVER_HOME, "setting animation to " + toState.toString());
cancelAnimation();
setCurrentAnimation(anim);
anim.addListener(createStateAnimationListener(toState));
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 7b4e248..6950fb5 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -25,14 +25,13 @@
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
-import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Handler;
import android.os.Message;
-import androidx.annotation.Nullable;
+import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseActivity;
@@ -62,8 +61,8 @@
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
- @Nullable
- private BaseActivity mActivity;
+ @NonNull
+ private final BaseActivity mActivity;
private final Handler mRequestOrientationHandler;
private boolean mIgnoreAutoRotateSettings;
@@ -92,14 +91,14 @@
// Initialize mLastActivityFlags to a value not used by SCREEN_ORIENTATION flags
private int mLastActivityFlags = -999;
- public RotationHelper(BaseActivity activity) {
+ public RotationHelper(@NonNull BaseActivity activity) {
mActivity = activity;
mRequestOrientationHandler =
new Handler(UI_HELPER_EXECUTOR.getLooper(), this::setOrientationAsync);
}
- private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings,
- DisplayController.Info info) {
+ private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings) {
+ if (mDestroyed) return;
// On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
if (!mIgnoreAutoRotateSettings) {
@@ -122,58 +121,54 @@
@Override
public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
+ if (mDestroyed) return;
boolean ignoreAutoRotateSettings = info.isTablet(info.realBounds);
if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
- setIgnoreAutoRotateSettings(ignoreAutoRotateSettings, info);
+ setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
notifyChange();
}
}
public void setStateHandlerRequest(int request) {
- if (mStateHandlerRequest != request) {
- mStateHandlerRequest = request;
- notifyChange();
- }
+ if (mDestroyed || mStateHandlerRequest == request) return;
+ mStateHandlerRequest = request;
+ notifyChange();
}
public void setCurrentTransitionRequest(int request) {
- if (mCurrentTransitionRequest != request) {
- mCurrentTransitionRequest = request;
- notifyChange();
- }
+ if (mDestroyed || mCurrentTransitionRequest == request) return;
+ mCurrentTransitionRequest = request;
+ notifyChange();
}
public void setCurrentStateRequest(int request) {
- if (mCurrentStateRequest != request) {
- mCurrentStateRequest = request;
- notifyChange();
- }
+ if (mDestroyed || mCurrentStateRequest == request) return;
+ mCurrentStateRequest = request;
+ notifyChange();
}
// Used by tests only.
public void forceAllowRotationForTesting(boolean allowRotation) {
+ if (mDestroyed) return;
mForceAllowRotationForTesting = allowRotation;
notifyChange();
}
public void initialize() {
- if (!mInitialized) {
- mInitialized = true;
- DisplayController displayController = DisplayController.INSTANCE.get(mActivity);
- DisplayController.Info info = displayController.getInfo();
- setIgnoreAutoRotateSettings(info.isTablet(info.realBounds), info);
- displayController.addChangeListener(this);
- notifyChange();
- }
+ if (mInitialized) return;
+ mInitialized = true;
+ DisplayController displayController = DisplayController.INSTANCE.get(mActivity);
+ DisplayController.Info info = displayController.getInfo();
+ setIgnoreAutoRotateSettings(info.isTablet(info.realBounds));
+ displayController.addChangeListener(this);
+ notifyChange();
}
public void destroy() {
- if (!mDestroyed) {
- mDestroyed = true;
- DisplayController.INSTANCE.get(mActivity).removeChangeListener(this);
- LauncherPrefs.get(mActivity).removeListener(this, ALLOW_ROTATION);
- mActivity = null;
- }
+ if (mDestroyed) return;
+ mDestroyed = true;
+ DisplayController.INSTANCE.get(mActivity).removeChangeListener(this);
+ LauncherPrefs.get(mActivity).removeListener(this, ALLOW_ROTATION);
}
private void notifyChange() {
@@ -206,10 +201,8 @@
@WorkerThread
private boolean setOrientationAsync(Message msg) {
- Activity activity = mActivity;
- if (activity != null) {
- activity.setRequestedOrientation(msg.what);
- }
+ if (mDestroyed) return true;
+ mActivity.setRequestedOrientation(msg.what);
return true;
}
@@ -228,8 +221,10 @@
public String toString() {
return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d, "
+ "mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, "
- + "mHomeRotationEnabled=%b, mForceAllowRotationForTesting=%b]",
+ + "mHomeRotationEnabled=%b, mForceAllowRotationForTesting=%b,"
+ + " mDestroyed=%b]",
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
- mIgnoreAutoRotateSettings, mHomeRotationEnabled, mForceAllowRotationForTesting);
+ mIgnoreAutoRotateSettings, mHomeRotationEnabled, mForceAllowRotationForTesting,
+ mDestroyed);
}
}
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 07a1b82..0438e57 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -16,7 +16,7 @@
package com.android.launcher3.testing;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.config.FeatureFlags.FOLDABLE_SINGLE_PAGE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -32,6 +32,7 @@
import android.view.WindowInsets;
import androidx.annotation.Nullable;
+import androidx.core.view.WindowInsetsCompat;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
@@ -142,6 +143,14 @@
}, this::getCurrentActivity);
}
+ case TestProtocol.REQUEST_IME_INSETS: {
+ return getUIProperty(Bundle::putParcelable, activity -> {
+ WindowInsetsCompat insets = WindowInsetsCompat.toWindowInsetsCompat(
+ activity.getWindow().getDecorView().getRootWindowInsets());
+ return insets.getInsets(WindowInsetsCompat.Type.ime()).toPlatformInsets();
+ }, this::getCurrentActivity);
+ }
+
case TestProtocol.REQUEST_ICON_HEIGHT: {
response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
mDeviceProfile.allAppsCellHeightPx);
@@ -156,6 +165,11 @@
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, mDeviceProfile.isTablet);
return response;
+ case TestProtocol.REQUEST_NUM_ALL_APPS_COLUMNS:
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ mDeviceProfile.numShownAllAppsColumns);
+ return response;
+
case TestProtocol.REQUEST_IS_TWO_PANELS:
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
FOLDABLE_SINGLE_PAGE.get() ? false : mDeviceProfile.isTwoPanels);
@@ -249,7 +263,7 @@
case TestProtocol.REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW: {
response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- ENABLE_GRID_ONLY_OVERVIEW.get());
+ enableGridOnlyOverview());
return response;
}
diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java
index 122b1e0..0c322cc 100644
--- a/src/com/android/launcher3/touch/ItemLongClickListener.java
+++ b/src/com/android/launcher3/touch/ItemLongClickListener.java
@@ -30,6 +30,7 @@
import com.android.launcher3.CellLayout;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
@@ -136,6 +137,10 @@
if (launcher.isWorkspaceLocked()) return false;
// Return early if an item is already being dragged (e.g. when long-pressing two shortcuts)
if (launcher.getDragController().isDragging()) return false;
+ // Return early if user is in the middle of selecting split-screen apps
+ if (FeatureFlags.enableSplitContextually() && launcher.isSplitSelectionEnabled()) {
+ return false;
+ }
return true;
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index c356da9..c80f243 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -27,6 +27,7 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
@@ -267,13 +268,19 @@
@Override
public float getTaskMenuX(float x, View thumbnailView,
- DeviceProfile deviceProfile, float taskInsetMargin) {
+ DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return x - (taskInsetMargin / 2f);
+ }
return thumbnailView.getMeasuredWidth() + x - taskInsetMargin;
}
@Override
public float getTaskMenuY(float y, View thumbnailView, int stagePosition,
- View taskMenuView, float taskInsetMargin) {
+ View taskMenuView, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return y - taskMenuView.getMeasuredHeight() - taskInsetMargin;
+ }
BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskMenuView.getLayoutParams();
int taskMenuWidth = lp.width;
if (stagePosition == STAGE_POSITION_UNDEFINED) {
@@ -537,14 +544,25 @@
}
@Override
+ public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
+ int thumbnailTopMargin) {
+ iconMenuParams.gravity = END | TOP;
+ iconMenuParams.setMarginStart(0);
+ iconMenuParams.topMargin = iconMenuParams.width + iconMenuMargin;
+ iconMenuParams.bottomMargin = 0;
+ iconMenuParams.setMarginEnd(iconMenuMargin);
+ }
+
+ @Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, SplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
- FrameLayout.LayoutParams secondaryIconParams =
- new FrameLayout.LayoutParams(primaryIconParams);
+ FrameLayout.LayoutParams secondaryIconParams = enableOverviewIconMenu()
+ ? (FrameLayout.LayoutParams) secondaryIconView.getLayoutParams()
+ : new FrameLayout.LayoutParams(primaryIconParams);
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
// This is the place where the thumbnail area splits by default, in a near-50/50 split.
@@ -560,11 +578,17 @@
int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
- primaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
- secondaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
+ primaryIconParams.gravity = enableOverviewIconMenu() ? TOP | (isRtl ? START : END)
+ : BOTTOM | (isRtl ? START : END);
+ secondaryIconParams.gravity = enableOverviewIconMenu() ? TOP | (isRtl ? START : END)
+ : BOTTOM | (isRtl ? START : END);
primaryIconView.setTranslationX(0);
secondaryIconView.setTranslationX(0);
- if (splitConfig.initiatedFromSeascape) {
+ if (enableOverviewIconMenu()) {
+ int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
+ splitConfig.visualDividerBounds.height());
+ secondaryIconView.setTranslationY(primarySnapshotHeight + dividerThickness);
+ } else if (splitConfig.initiatedFromSeascape) {
// if the split was initiated from seascape,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset);
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 39ef129..0069d9b 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -173,6 +173,8 @@
// Overview TaskMenuView methods
void setTaskIconParams(FrameLayout.LayoutParams iconParams,
int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
+ void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
+ int thumbnailTopMargin);
void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
@@ -185,9 +187,9 @@
* getTaskMenuWidth()), so we directly use that in the calculations.
*/
float getTaskMenuX(float x, View thumbnailView, DeviceProfile deviceProfile,
- float taskInsetMargin);
+ float taskInsetMargin, View taskViewIcon);
float getTaskMenuY(float y, View thumbnailView, int stagePosition,
- View taskMenuView, float taskInsetMargin);
+ View taskMenuView, float taskInsetMargin, View taskViewIcon);
int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile,
@StagePosition int stagePosition);
/**
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index dc4621e..62ef229 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -21,11 +21,13 @@
import static android.view.Gravity.END;
import static android.view.Gravity.START;
import static android.view.Gravity.TOP;
+import static android.view.View.LAYOUT_DIRECTION_RTL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
@@ -264,8 +266,11 @@
@Override
public float getTaskMenuX(float x, View thumbnailView,
- DeviceProfile deviceProfile, float taskInsetMargin) {
- if (deviceProfile.isLandscape) {
+ DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return x + (thumbnailView.getLayoutDirection() == LAYOUT_DIRECTION_RTL
+ ? -(taskViewIcon.getWidth() / 2f) : 0);
+ } else if (deviceProfile.isLandscape) {
return x + taskInsetMargin
+ (thumbnailView.getMeasuredWidth() - thumbnailView.getMeasuredHeight()) / 2f;
} else {
@@ -275,13 +280,22 @@
@Override
public float getTaskMenuY(float y, View thumbnailView, int stagePosition,
- View taskMenuView, float taskInsetMargin) {
+ View taskMenuView, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return y;
+ }
return y + taskInsetMargin;
}
@Override
public int getTaskMenuWidth(View thumbnailView, DeviceProfile deviceProfile,
@StagePosition int stagePosition) {
+ if (enableOverviewIconMenu()) {
+ int padding = thumbnailView.getResources().getDimensionPixelSize(
+ R.dimen.task_menu_vertical_padding);
+ return thumbnailView.getResources().getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_menu_max_width) + (2 * padding);
+ }
return deviceProfile.isLandscape && !deviceProfile.isTablet
? thumbnailView.getMeasuredHeight()
: thumbnailView.getMeasuredWidth();
@@ -689,16 +703,53 @@
}
@Override
+ public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
+ int thumbnailTopMargin) {
+ iconMenuParams.gravity = TOP | START;
+ iconMenuParams.setMarginStart(iconMenuMargin);
+ iconMenuParams.topMargin = iconMenuMargin;
+ iconMenuParams.bottomMargin = 0;
+ iconMenuParams.setMarginEnd(0);
+ }
+
+ @Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
DeviceProfile deviceProfile, SplitBounds splitConfig) {
FrameLayout.LayoutParams primaryIconParams =
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
- FrameLayout.LayoutParams secondaryIconParams =
- new FrameLayout.LayoutParams(primaryIconParams);
+ FrameLayout.LayoutParams secondaryIconParams = enableOverviewIconMenu()
+ ? (FrameLayout.LayoutParams) secondaryIconView.getLayoutParams()
+ : new FrameLayout.LayoutParams(primaryIconParams);
- if (deviceProfile.isLandscape) {
+ if (enableOverviewIconMenu()) {
+ primaryIconParams.gravity = TOP | START;
+ secondaryIconParams.gravity = TOP | START;
+ secondaryIconParams.topMargin = primaryIconParams.topMargin;
+ secondaryIconParams.setMarginStart(primaryIconParams.getMarginStart());
+ if (deviceProfile.isLandscape) {
+ int fullscreenInsetThickness = deviceProfile.isSeascape()
+ ? deviceProfile.getInsets().right
+ : deviceProfile.getInsets().left;
+ int fullscreenMidpointFromBottom = ((deviceProfile.widthPx
+ - fullscreenInsetThickness) / 2);
+ float midpointFromEndPct = (float) fullscreenMidpointFromBottom
+ / deviceProfile.widthPx;
+ int bottomToMidpointOffset = (int) (groupedTaskViewWidth * midpointFromEndPct);
+ if (isRtl) {
+ primaryIconView.setTranslationX(-bottomToMidpointOffset);
+ } else {
+ secondaryIconView.setTranslationX(bottomToMidpointOffset);
+ }
+ } else {
+ secondaryIconView.setTranslationX(0);
+ int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
+ splitConfig.visualDividerBounds.height());
+ secondaryIconView.setTranslationY(
+ primarySnapshotHeight + (deviceProfile.isTablet ? 0 : dividerThickness));
+ }
+ } else if (deviceProfile.isLandscape) {
// We calculate the "midpoint" of the thumbnail area, and place the icons there.
// This is the place where the thumbnail area splits by default, in a near-50/50 split.
// It is usually not exactly 50/50, due to insets/screen cutouts.
@@ -754,8 +805,10 @@
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
secondaryIconView.setTranslationX(taskIconHeight / 2f);
}
- primaryIconView.setTranslationY(0);
- secondaryIconView.setTranslationY(0);
+ if (!enableOverviewIconMenu()) {
+ primaryIconView.setTranslationY(0);
+ secondaryIconView.setTranslationY(0);
+ }
primaryIconView.setLayoutParams(primaryIconParams);
secondaryIconView.setLayoutParams(secondaryIconParams);
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index ec01231..4409572 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -22,6 +22,7 @@
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.START;
+import static com.android.launcher3.Flags.enableOverviewIconMenu;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
@@ -86,13 +87,19 @@
@Override
public float getTaskMenuX(float x, View thumbnailView,
- DeviceProfile deviceProfile, float taskInsetMargin) {
+ DeviceProfile deviceProfile, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return x + taskViewIcon.getHeight() + taskInsetMargin * 2;
+ }
return x + taskInsetMargin;
}
@Override
public float getTaskMenuY(float y, View thumbnailView, int stagePosition,
- View taskMenuView, float taskInsetMargin) {
+ View taskMenuView, float taskInsetMargin, View taskViewIcon) {
+ if (enableOverviewIconMenu()) {
+ return y + taskViewIcon.getWidth() - taskViewIcon.getHeight();
+ }
BaseDragLayer.LayoutParams lp = (BaseDragLayer.LayoutParams) taskMenuView.getLayoutParams();
int taskMenuWidth = lp.width;
if (stagePosition == STAGE_POSITION_UNDEFINED) {
@@ -208,13 +215,24 @@
public void setTaskIconParams(FrameLayout.LayoutParams iconParams,
int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
- iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
+ iconParams.leftMargin =
+ enableOverviewIconMenu() ? 0 : -taskIconHeight - taskIconMargin / 2;
iconParams.rightMargin = 0;
- iconParams.topMargin = thumbnailTopMargin / 2;
+ iconParams.topMargin = enableOverviewIconMenu() ? 0 : thumbnailTopMargin / 2;
iconParams.bottomMargin = 0;
}
@Override
+ public void setTaskIconMenuParams(FrameLayout.LayoutParams iconMenuParams, int iconMenuMargin,
+ int thumbnailTopMargin) {
+ iconMenuParams.gravity = BOTTOM | START;
+ iconMenuParams.setMarginStart(0);
+ iconMenuParams.topMargin = 0;
+ iconMenuParams.bottomMargin = 0;
+ iconMenuParams.setMarginEnd(0);
+ }
+
+ @Override
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
@@ -245,7 +263,11 @@
secondaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
primaryIconView.setTranslationX(0);
secondaryIconView.setTranslationX(0);
- if (splitConfig.initiatedFromSeascape) {
+ if (enableOverviewIconMenu()) {
+ int dividerThickness = Math.min(splitConfig.visualDividerBounds.width(),
+ splitConfig.visualDividerBounds.height());
+ secondaryIconView.setTranslationY(-primarySnapshotHeight - dividerThickness);
+ } else if (splitConfig.initiatedFromSeascape) {
// if the split was initiated from seascape,
// the task on the right (secondary) is slightly larger
primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index 96ae4a3..5b6c9e0 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -40,6 +40,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.testing.TestLogging;
@@ -205,6 +206,9 @@
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
mLauncher.getStatsLogManager().logger().log(LAUNCHER_WORKSPACE_LONGPRESS);
mLauncher.showDefaultOptions(mTouchDownPoint.x, mTouchDownPoint.y);
+ if (FeatureFlags.enableSplitContextually() && mLauncher.isSplitSelectionEnabled()) {
+ mLauncher.dismissSplitSelection();
+ }
} else {
cancelLongPress();
}
diff --git a/src/com/android/launcher3/util/BackPressHandler.java b/src/com/android/launcher3/util/BackPressHandler.java
new file mode 100644
index 0000000..b63f648
--- /dev/null
+++ b/src/com/android/launcher3/util/BackPressHandler.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.os.Build;
+import android.window.OnBackAnimationCallback;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Extension of {@link OnBackAnimationCallback} that allows a check to determine
+ * if this callback supports handling back or not
+ */
+@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+public interface BackPressHandler extends OnBackAnimationCallback {
+ boolean canHandleBack();
+}
diff --git a/src/com/android/launcher3/util/CellContentDimensions.kt b/src/com/android/launcher3/util/CellContentDimensions.kt
new file mode 100644
index 0000000..3c8e0c4
--- /dev/null
+++ b/src/com/android/launcher3/util/CellContentDimensions.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util
+
+import com.android.launcher3.Utilities
+import kotlin.math.max
+
+class CellContentDimensions(
+ var iconSizePx: Int,
+ var iconDrawablePaddingPx: Int,
+ var iconTextSizePx: Int
+) {
+ /**
+ * This method goes through some steps to reduce the padding between icon and label, icon size
+ * and then label size, until it can fit in the [cellHeightPx].
+ *
+ * @return the height of the content after being sized down.
+ */
+ fun resizeToFitCellHeight(cellHeightPx: Int, iconSizeSteps: IconSizeSteps): Int {
+ var cellContentHeight = getCellContentHeight()
+
+ // Step 1. Decrease drawable padding
+ if (cellContentHeight > cellHeightPx) {
+ val diff = cellContentHeight - cellHeightPx
+ iconDrawablePaddingPx = max(0, iconDrawablePaddingPx - diff)
+ cellContentHeight = getCellContentHeight()
+ }
+
+ while (
+ (iconTextSizePx > iconSizeSteps.minimumIconLabelSize ||
+ iconSizePx > iconSizeSteps.minimumIconSize()) && cellContentHeight > cellHeightPx
+ ) {
+ // Step 2. Decrease icon size
+ iconSizePx = iconSizeSteps.getNextLowerIconSize(iconSizePx)
+ cellContentHeight = getCellContentHeight()
+
+ // Step 3. Decrease label size
+ if (cellContentHeight > cellHeightPx) {
+ iconTextSizePx =
+ max(
+ iconSizeSteps.minimumIconLabelSize,
+ iconTextSizePx - IconSizeSteps.TEXT_STEP
+ )
+ cellContentHeight = getCellContentHeight()
+ }
+ }
+
+ return cellContentHeight
+ }
+
+ /** Calculate new cellContentHeight */
+ fun getCellContentHeight(): Int {
+ val iconTextHeight = Utilities.calculateTextHeight(iconTextSizePx.toFloat())
+ return iconSizePx + iconDrawablePaddingPx + iconTextHeight
+ }
+}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index a7c94bb..26ab5b4 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -20,6 +20,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING;
+import static com.android.launcher3.LauncherPrefs.TASKBAR_PINNING_KEY;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_PINNING;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRANSIENT_TASKBAR;
@@ -32,6 +33,7 @@
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
@@ -82,9 +84,11 @@
public static final int CHANGE_DENSITY = 1 << 2;
public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 3;
public static final int CHANGE_NAVIGATION_MODE = 1 << 4;
+ public static final int CHANGE_TASKBAR_PINNING = 1 << 5;
public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
- | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
+ | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE
+ | CHANGE_TASKBAR_PINNING;
private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
private static final String TARGET_OVERLAY_PACKAGE = "android";
@@ -104,13 +108,17 @@
private Info mInfo;
private boolean mDestroyed = false;
- private final LauncherPrefs mPrefs;
+ private SharedPreferences.OnSharedPreferenceChangeListener
+ mTaskbarPinningPreferenceChangeListener;
@VisibleForTesting
protected DisplayController(Context context) {
mContext = context;
mDM = context.getSystemService(DisplayManager.class);
- mPrefs = LauncherPrefs.get(context);
+
+ if (ENABLE_TASKBAR_PINNING.get()) {
+ attachTaskbarPinningSharedPreferenceChangeListener(mContext);
+ }
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (Utilities.ATLEAST_S) {
@@ -131,6 +139,21 @@
FileLog.i(TAG, "(CTOR) perDisplayBounds: " + mInfo.mPerDisplayBounds);
}
+ private void attachTaskbarPinningSharedPreferenceChangeListener(Context context) {
+ mTaskbarPinningPreferenceChangeListener =
+ (sharedPreferences, key) -> {
+ if (TASKBAR_PINNING_KEY.equals(key)
+ && mInfo.mIsTaskbarPinned != LauncherPrefs.get(mContext).get(
+ TASKBAR_PINNING)
+ ) {
+ handleInfoChange(mWindowContext.getDisplay());
+ }
+ };
+
+ LauncherPrefs.get(context).addListener(
+ mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING);
+ }
+
/**
* Returns the current navigation mode
*/
@@ -142,25 +165,7 @@
* Returns whether taskbar is transient.
*/
public static boolean isTransientTaskbar(Context context) {
- return INSTANCE.get(context).isTransientTaskbar();
- }
-
- /**
- * Returns whether taskbar is transient.
- */
- public boolean isTransientTaskbar() {
- // TODO(b/258604917): When running in test harness, use !sTransientTaskbarStatusForTests
- // once tests are updated to expect new persistent behavior such as not allowing long press
- // to stash.
- if (!Utilities.isRunningInTestHarness()
- && ENABLE_TASKBAR_PINNING.get()
- && mPrefs.get(TASKBAR_PINNING)) {
- return false;
- }
- return getInfo().navigationMode == NavigationMode.NO_BUTTON
- && (Utilities.isRunningInTestHarness()
- ? sTransientTaskbarStatusForTests
- : ENABLE_TRANSIENT_TASKBAR.get());
+ return INSTANCE.get(context).getInfo().isTransientTaskbar();
}
/**
@@ -174,6 +179,10 @@
@Override
public void close() {
mDestroyed = true;
+ if (ENABLE_TASKBAR_PINNING.get()) {
+ LauncherPrefs.get(mContext).removeListener(
+ mTaskbarPinningPreferenceChangeListener, TASKBAR_PINNING);
+ }
if (mWindowContext != null) {
mWindowContext.unregisterComponentCallbacks(this);
} else {
@@ -256,7 +265,8 @@
}
@AnyThread
- private void handleInfoChange(Display display) {
+ @VisibleForTesting
+ public void handleInfoChange(Display display) {
WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(mContext);
Info oldInfo = mInfo;
@@ -289,6 +299,9 @@
FileLog.w(TAG,
"(CHANGE_SUPPORTED_BOUNDS) perDisplayBounds: " + newInfo.mPerDisplayBounds);
}
+ if (newInfo.mIsTaskbarPinned != oldInfo.mIsTaskbarPinned) {
+ change |= CHANGE_TASKBAR_PINNING;
+ }
if (DEBUG) {
Log.d(TAG, "handleInfoChange - change: " + getChangeFlagsString(change));
}
@@ -331,6 +344,8 @@
private final ArrayMap<CachedDisplayInfo, List<WindowBounds>> mPerDisplayBounds =
new ArrayMap<>();
+ private final boolean mIsTaskbarPinned;
+
public Info(Context displayInfoContext) {
/* don't need system overrides for external displays */
this(displayInfoContext, new WindowManagerProxy(), new ArrayMap<>());
@@ -387,6 +402,26 @@
Log.d(TAG, "normalizedDisplayInfo: " + normalizedDisplayInfo);
Log.d(TAG, "perDisplayBounds: " + mPerDisplayBounds);
}
+
+ mIsTaskbarPinned = LauncherPrefs.get(displayInfoContext).get(TASKBAR_PINNING);
+ }
+
+ /**
+ * Returns whether taskbar is transient.
+ */
+ public boolean isTransientTaskbar() {
+ // TODO(b/258604917): Once ENABLE_TASKBAR_PINNING is enabled, remove usage of
+ // sTransientTaskbarStatusForTests and update test to directly
+ // toggle shred preference to switch transient taskbar on/of
+ if (!Utilities.isRunningInTestHarness()
+ && ENABLE_TASKBAR_PINNING.get()
+ && mIsTaskbarPinned) {
+ return false;
+ }
+ return navigationMode == NavigationMode.NO_BUTTON
+ && (Utilities.isRunningInTestHarness()
+ ? sTransientTaskbarStatusForTests
+ : ENABLE_TRANSIENT_TASKBAR.get() && !mIsTaskbarPinned);
}
/**
@@ -426,6 +461,7 @@
appendFlag(result, change, CHANGE_DENSITY, "CHANGE_DENSITY");
appendFlag(result, change, CHANGE_SUPPORTED_BOUNDS, "CHANGE_SUPPORTED_BOUNDS");
appendFlag(result, change, CHANGE_NAVIGATION_MODE, "CHANGE_NAVIGATION_MODE");
+ appendFlag(result, change, CHANGE_TASKBAR_PINNING, "CHANGE_TASKBAR_VARIANT");
return result.toString();
}
@@ -440,6 +476,7 @@
pw.println(" fontScale=" + info.fontScale);
pw.println(" densityDpi=" + info.densityDpi);
pw.println(" navigationMode=" + info.navigationMode.name());
+ pw.println(" isTaskbarPinned=" + info.mIsTaskbarPinned);
pw.println(" currentSize=" + info.currentSize);
info.mPerDisplayBounds.forEach((key, value) -> pw.println(
" perDisplayBounds - " + key + ": " + value));
diff --git a/src/com/android/launcher3/util/Executors.java b/src/com/android/launcher3/util/Executors.java
index dec4b5c..c622b71 100644
--- a/src/com/android/launcher3/util/Executors.java
+++ b/src/com/android/launcher3/util/Executors.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.util;
+import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
+
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
@@ -47,6 +49,12 @@
POOL_SIZE, POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
/**
+ * An {@link LooperExecutor} to be used with async task where order is important.
+ */
+ public static final LooperExecutor ORDERED_BG_EXECUTOR = new LooperExecutor(
+ createAndStartNewLooper("BackgroundExecutor", THREAD_PRIORITY_BACKGROUND));
+
+ /**
* Returns the executor for running tasks on the main thread.
*/
public static final LooperExecutor MAIN_EXECUTOR =
@@ -62,7 +70,9 @@
/** A background executor to preinflate views. */
public static final ExecutorService VIEW_PREINFLATION_EXECUTOR =
- java.util.concurrent.Executors.newSingleThreadExecutor();
+ java.util.concurrent.Executors.newSingleThreadExecutor(
+ new SimpleThreadFactory(
+ "preinflate-allapps-icons", THREAD_PRIORITY_BACKGROUND));
/**
* Utility method to get a started handler thread statically
diff --git a/src/com/android/launcher3/util/IconSizeSteps.kt b/src/com/android/launcher3/util/IconSizeSteps.kt
index 2a5afe0..aa644b0 100644
--- a/src/com/android/launcher3/util/IconSizeSteps.kt
+++ b/src/com/android/launcher3/util/IconSizeSteps.kt
@@ -23,12 +23,14 @@
class IconSizeSteps(res: Resources) {
private val steps: List<Int>
+ val minimumIconLabelSize: Int
init {
steps =
res.obtainTypedArray(R.array.icon_size_steps).use {
(0 until it.length()).map { step -> it.getDimensionOrThrow(step).toInt() }.sorted()
}
+ minimumIconLabelSize = res.getDimensionPixelSize(R.dimen.minimum_icon_label_size)
}
fun minimumIconSize(): Int = steps[0]
@@ -44,4 +46,8 @@
private fun getIndexForIconSize(iconSizePx: Int): Int {
return max(0, steps.indexOfFirst { iconSizePx <= it })
}
+
+ companion object {
+ internal const val TEXT_STEP = 1
+ }
}
diff --git a/src/com/android/launcher3/util/KeyboardShortcutsDelegate.java b/src/com/android/launcher3/util/KeyboardShortcutsDelegate.java
new file mode 100644
index 0000000..3ec339d
--- /dev/null
+++ b/src/com/android/launcher3/util/KeyboardShortcutsDelegate.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
+
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.KeyboardShortcutInfo;
+import android.view.Menu;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.accessibility.BaseAccessibilityDelegate;
+import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.views.OptionsPopupView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Delegate to define the keyboard shortcuts.
+ */
+public class KeyboardShortcutsDelegate {
+
+ Launcher mLauncher;
+
+ public KeyboardShortcutsDelegate(Launcher launcher) {
+ mLauncher = launcher;
+ }
+
+ /**
+ * Populates the list of shortcuts.
+ */
+ public void onProvideKeyboardShortcuts(
+ List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
+ ArrayList<KeyboardShortcutInfo> shortcutInfos = new ArrayList<>();
+ if (mLauncher.isInState(NORMAL)) {
+ shortcutInfos.add(
+ new KeyboardShortcutInfo(mLauncher.getString(R.string.all_apps_button_label),
+ KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON));
+ shortcutInfos.add(
+ new KeyboardShortcutInfo(mLauncher.getString(R.string.widget_button_text),
+ KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON));
+ }
+ getSupportedActions(mLauncher, mLauncher.getCurrentFocus()).forEach(la ->
+ shortcutInfos.add(new KeyboardShortcutInfo(
+ la.accessibilityAction.getLabel(), la.keyCode, KeyEvent.META_CTRL_ON)));
+ if (!shortcutInfos.isEmpty()) {
+ data.add(new KeyboardShortcutGroup(mLauncher.getString(R.string.home_screen),
+ shortcutInfos));
+ }
+ }
+
+ /**
+ * Handles combinations of keys like ctrl+s or ctrl+c and runs before onKeyDown.
+ * @param keyCode code of the key being pressed.
+ * @see android.view.KeyEvent
+ * @return weather the event is already handled and if it should be passed to other components.
+ */
+ public Boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ if (event.hasModifiers(KeyEvent.META_CTRL_ON)) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_A:
+ if (mLauncher.isInState(NORMAL)) {
+ mLauncher.getStateManager().goToState(ALL_APPS);
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_W:
+ if (mLauncher.isInState(NORMAL)) {
+ OptionsPopupView.openWidgets(mLauncher);
+ return true;
+ }
+ break;
+ default:
+ for (BaseAccessibilityDelegate.LauncherAction la : getSupportedActions(
+ mLauncher, mLauncher.getCurrentFocus())) {
+ if (la.keyCode == keyCode) {
+ return la.invokeFromKeyboard(mLauncher.getCurrentFocus());
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Handle key down event.
+ * @param keyCode code of the key being pressed.
+ * @see android.view.KeyEvent
+ */
+ public Boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
+ // Close any open floating views.
+ mLauncher.closeOpenViews();
+ return true;
+ }
+ return null;
+ }
+
+ /**
+ * Handle key up event.
+ * @param keyCode code of the key being pressed.
+ * @see android.view.KeyEvent
+ */
+ public Boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_MENU) {
+ // KEYCODE_MENU is sent by some tests, for example
+ // LauncherJankTests#testWidgetsContainerFling. Don't just remove its handling.
+ if (!mLauncher.getDragController().isDragging()
+ && !mLauncher.getWorkspace().isSwitchingState()
+ && mLauncher.isInState(NORMAL)) {
+ // Close any open floating views.
+ mLauncher.closeOpenViews();
+
+ // Setting the touch point to (-1, -1) will show the options popup in the center of
+ // the screen.
+ if (Utilities.isRunningInTestHarness()) {
+ Log.d(TestProtocol.PERMANENT_DIAG_TAG, "Opening options popup on key up");
+ }
+ mLauncher.showDefaultOptions(-1, -1);
+ }
+ return true;
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java
index 1cb9994..b966d8e 100644
--- a/src/com/android/launcher3/util/MainThreadInitializedObject.java
+++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java
@@ -93,7 +93,7 @@
* Abstract Context which allows custom implementations for
* {@link MainThreadInitializedObject} providers
*/
- public static abstract class SandboxContext extends ContextWrapper {
+ public static class SandboxContext extends ContextWrapper {
private static final String TAG = "SandboxContext";
@@ -165,5 +165,14 @@
protected <T> T createObject(MainThreadInitializedObject<T> object) {
return object.mProvider.get(this);
}
+
+ /**
+ * Put a value into mObjectMap, can be used to put mocked MainThreadInitializedObject
+ * instances into SandboxContext.
+ */
+ @VisibleForTesting
+ public <T> void putObject(MainThreadInitializedObject<T> object, T value) {
+ mObjectMap.put(object, value);
+ }
}
}
diff --git a/src/com/android/launcher3/util/MultiTranslateDelegate.java b/src/com/android/launcher3/util/MultiTranslateDelegate.java
index 1cb7a45..84ef445 100644
--- a/src/com/android/launcher3/util/MultiTranslateDelegate.java
+++ b/src/com/android/launcher3/util/MultiTranslateDelegate.java
@@ -36,11 +36,18 @@
// Specific for items in taskbar (icons, folders, qsb)
public static final int INDEX_TASKBAR_ALIGNMENT_ANIM = 3;
public static final int INDEX_TASKBAR_REVEAL_ANIM = 4;
+ public static final int INDEX_TASKBAR_PINNING_ANIM = 5;
+
+ // Affect all items inside of a MultipageCellLayout
+ public static final int INDEX_CELLAYOUT_MULTIPAGE_SPACING = 3;
// Specific for widgets
- public static final int INDEX_WIDGET_CENTERING = 3;
+ public static final int INDEX_WIDGET_CENTERING = 4;
- public static final int COUNT = 5;
+ // Specific for hotseat items when adjusting for bubbles
+ public static final int INDEX_BUBBLE_ADJUSTMENT_ANIM = 3;
+
+ public static final int COUNT = 6;
private final MultiPropertyFactory<View> mTranslationX;
private final MultiPropertyFactory<View> mTranslationY;
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
deleted file mode 100644
index f8f4b5f..0000000
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.launcher3.util;
-
-import android.content.SharedPreferences;
-import android.util.ArrayMap;
-
-import androidx.annotation.StringDef;
-
-import com.android.launcher3.views.ActivityContext;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Stores and retrieves onboarding-related data via SharedPreferences.
- *
- * @param <T> Context which owns these preferences.
- */
-public class OnboardingPrefs<T extends ActivityContext> {
-
- public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown";
- public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
- public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
- public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
- public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
- public static final String TASKBAR_EDU_TOOLTIP_STEP = "launcher.taskbar_edu_tooltip_step";
- // When adding a new key, add it here as well, to be able to reset it from Developer Options.
- public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
- "All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
- "Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
- HOTSEAT_LONGPRESS_TIP_SEEN },
- "Taskbar Education", new String[] { TASKBAR_EDU_TOOLTIP_STEP },
- "All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
- );
-
- /**
- * Events that either have happened or have not (booleans).
- */
- @StringDef(value = {
- HOME_BOUNCE_SEEN,
- HOTSEAT_LONGPRESS_TIP_SEEN,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EventBoolKey {}
-
- /**
- * Events that occur multiple times, which we count up to a max defined in {@link #MAX_COUNTS}.
- */
- @StringDef(value = {
- HOME_BOUNCE_COUNT,
- HOTSEAT_DISCOVERY_TIP_COUNT,
- ALL_APPS_VISITED_COUNT,
- TASKBAR_EDU_TOOLTIP_STEP,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface EventCountKey {}
-
- private static final Map<String, Integer> MAX_COUNTS;
-
- static {
- Map<String, Integer> maxCounts = new ArrayMap<>(5);
- maxCounts.put(HOME_BOUNCE_COUNT, 3);
- maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
- maxCounts.put(ALL_APPS_VISITED_COUNT, 20);
- maxCounts.put(TASKBAR_EDU_TOOLTIP_STEP, 2);
- MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
- }
-
- protected final T mLauncher;
- protected final SharedPreferences mSharedPrefs;
-
- public OnboardingPrefs(T launcher, SharedPreferences sharedPrefs) {
- mLauncher = launcher;
- mSharedPrefs = sharedPrefs;
- }
-
- /** @return The number of times we have seen the given event. */
- public int getCount(@EventCountKey String key) {
- return mSharedPrefs.getInt(key, 0);
- }
-
- /** @return Whether we have seen this event enough times, as defined by {@link #MAX_COUNTS}. */
- public boolean hasReachedMaxCount(@EventCountKey String eventKey) {
- return hasReachedMaxCount(getCount(eventKey), eventKey);
- }
-
- private boolean hasReachedMaxCount(int count, @EventCountKey String eventKey) {
- return count >= MAX_COUNTS.get(eventKey);
- }
-
- /** @return Whether we have seen the given event. */
- public boolean getBoolean(@EventBoolKey String key) {
- return mSharedPrefs.getBoolean(key, false);
- }
-
- /**
- * Marks on-boarding preference boolean at true
- */
- public void markChecked(String flag) {
- mSharedPrefs.edit().putBoolean(flag, true).apply();
- }
-
- /**
- * Add 1 to the given event count, if we haven't already reached the max count.
- *
- * @return Whether we have now reached the max count.
- */
- public boolean incrementEventCount(@EventCountKey String eventKey) {
- int count = getCount(eventKey);
- if (hasReachedMaxCount(count, eventKey)) {
- return true;
- }
- count++;
- mSharedPrefs.edit().putInt(eventKey, count).apply();
- return hasReachedMaxCount(count, eventKey);
- }
-
- /**
- * Sets the event count to the given value.
- *
- * @return Whether we have now reached the max count.
- */
- public boolean setEventCount(int count, @EventCountKey String eventKey) {
- mSharedPrefs.edit().putInt(eventKey, count).apply();
- return hasReachedMaxCount(count, eventKey);
- }
-}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.kt b/src/com/android/launcher3/util/OnboardingPrefs.kt
new file mode 100644
index 0000000..8586c43
--- /dev/null
+++ b/src/com/android/launcher3/util/OnboardingPrefs.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.launcher3.util
+
+import android.content.Context
+import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.LauncherPrefs.Companion.backedUpItem
+
+/** Stores and retrieves onboarding-related data via SharedPreferences. */
+object OnboardingPrefs {
+
+ data class CountedItem(
+ val sharedPrefKey: String,
+ val maxCount: Int,
+ ) {
+ private val prefItem = backedUpItem(sharedPrefKey, 0)
+
+ /** @return The number of times we have seen the given event. */
+ fun get(c: Context): Int {
+ return prefItem.get(c)
+ }
+
+ /** @return Whether we have seen this event enough times, as defined by [.MAX_COUNTS]. */
+ fun hasReachedMax(c: Context): Boolean {
+ return get(c) >= maxCount
+ }
+
+ /**
+ * Add 1 to the given event count, if we haven't already reached the max count.
+ *
+ * @return Whether we have now reached the max count.
+ */
+ fun increment(c: Context): Boolean {
+ val count = get(c)
+ if (count >= maxCount) {
+ return true
+ }
+ return set(count + 1, c)
+ }
+
+ /**
+ * Sets the event count to the given value.
+ *
+ * @return Whether we have now reached the max count.
+ */
+ fun set(count: Int, c: Context): Boolean {
+ LauncherPrefs.get(c).put(prefItem, count)
+ return count >= maxCount
+ }
+ }
+
+ @JvmField val TASKBAR_EDU_TOOLTIP_STEP = CountedItem("launcher.taskbar_edu_tooltip_step", 2)
+
+ @JvmField val HOME_BOUNCE_COUNT = CountedItem("launcher.home_bounce_count", 3)
+
+ @JvmField
+ val HOTSEAT_DISCOVERY_TIP_COUNT = CountedItem("launcher.hotseat_discovery_tip_count", 5)
+
+ @JvmField val ALL_APPS_VISITED_COUNT = CountedItem("launcher.all_apps_visited_count", 20)
+
+ @JvmField val HOME_BOUNCE_SEEN = backedUpItem("launcher.apps_view_shown", false)
+
+ @JvmField
+ val HOTSEAT_LONGPRESS_TIP_SEEN = backedUpItem("launcher.hotseat_longpress_tip_seen", false)
+}
diff --git a/src/com/android/launcher3/util/RunnableList.java b/src/com/android/launcher3/util/RunnableList.java
index 644537b..f6e0c57 100644
--- a/src/com/android/launcher3/util/RunnableList.java
+++ b/src/com/android/launcher3/util/RunnableList.java
@@ -25,9 +25,7 @@
private ArrayList<Runnable> mList = null;
private boolean mDestroyed = false;
- /**
- * Ads a runnable to this list
- */
+ /** Adds a runnable to this list */
public void add(Runnable runnable) {
if (runnable == null) {
return;
@@ -42,6 +40,13 @@
mList.add(runnable);
}
+ /** Removes a previously added runnable */
+ public void remove(Runnable runnable) {
+ if (mList != null) {
+ mList.remove(runnable);
+ }
+ }
+
/**
* Destroys the list, executing any pending callbacks. All new callbacks are
* immediately executed
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 06cb00e..29ec5ab 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -25,8 +25,6 @@
import android.os.Handler;
import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
-
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -61,6 +59,7 @@
Settings.System.getUriFor(ACCELEROMETER_ROTATION);
private static final String SYSTEM_URI_PREFIX = Settings.System.CONTENT_URI.toString();
+ private static final String GLOBAL_URI_PREFIX = Settings.Global.CONTENT_URI.toString();
/**
* Caches the last seen value for registered keys.
@@ -139,6 +138,8 @@
boolean newVal;
if (keyUri.toString().startsWith(SYSTEM_URI_PREFIX)) {
newVal = Settings.System.getInt(mResolver, key, defaultValue) == 1;
+ } else if (keyUri.toString().startsWith(GLOBAL_URI_PREFIX)) {
+ newVal = Settings.Global.getInt(mResolver, key, defaultValue) == 1;
} else { // SETTING_SECURE
newVal = Settings.Secure.getInt(mResolver, key, defaultValue) == 1;
}
@@ -154,23 +155,9 @@
*/
public void unregister(Uri uri, OnChangeListener listener) {
List<OnChangeListener> listenersToRemoveFrom = mListenerMap.get(uri);
- if (listenersToRemoveFrom == null) {
- return;
+ if (listenersToRemoveFrom != null) {
+ listenersToRemoveFrom.remove(listener);
}
-
- listenersToRemoveFrom.remove(listener);
- if (listenersToRemoveFrom.isEmpty()) {
- mListenerMap.remove(uri);
- }
- }
-
- /**
- * Don't use this. Ever.
- * @param keyCache Cache to replace {@link #mKeyCache}
- */
- @VisibleForTesting
- void setKeyCache(Map<Uri, Boolean> keyCache) {
- mKeyCache = keyCache;
}
public interface OnChangeListener {
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 1ae43d0..f4a0225 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -77,11 +77,6 @@
public @interface StageType {}
///////////////////////////////////
- /**
- * Default split ratio for launching app pair from overview.
- */
- public static final float DEFAULT_SPLIT_RATIO = 0.5f;
-
public static class SplitPositionOption {
public final int iconResId;
public final int textResId;
@@ -116,6 +111,8 @@
public final float leftTaskPercent;
public final float dividerWidthPercent;
public final float dividerHeightPercent;
+ public final int snapPosition;
+
/**
* If {@code true}, that means at the time of creation of this object, the
* split-screened apps were vertically stacked. This is useful in scenarios like
@@ -135,11 +132,12 @@
public final int rightBottomTaskId;
public SplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId,
- int rightBottomTaskId) {
+ int rightBottomTaskId, int snapPosition) {
this.leftTopBounds = leftTopBounds;
this.rightBottomBounds = rightBottomBounds;
this.leftTopTaskId = leftTopTaskId;
this.rightBottomTaskId = rightBottomTaskId;
+ this.snapPosition = snapPosition;
if (rightBottomBounds.top > leftTopBounds.top) {
// vertical apps, horizontal divider
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index 91945ca..80a9bae 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -18,6 +18,10 @@
import static android.os.VibrationEffect.createPredefined;
import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -35,10 +39,9 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.PendingAnimation;
-
-import java.util.function.Consumer;
+import com.android.launcher3.config.FeatureFlags;
/**
* Wrapper around {@link Vibrator} to easily perform haptic feedback where necessary.
@@ -70,7 +73,7 @@
private final VibrationEffect mBumpEffect;
@Nullable
- private final VibrationEffect mAssistEffect;
+ private final VibrationEffect mSearchEffect;
private long mLastDragTime;
private final int mThresholdUntilNextDragCallMillis;
@@ -80,12 +83,14 @@
*/
public static final VibrationEffect OVERVIEW_HAPTIC = EFFECT_CLICK;
+ private final Context mContext;
private final Vibrator mVibrator;
private final boolean mHasVibrator;
private boolean mIsHapticFeedbackEnabled;
private VibratorWrapper(Context context) {
+ mContext = context;
mVibrator = context.getSystemService(Vibrator.class);
mHasVibrator = mVibrator.hasVibrator();
if (mHasVibrator) {
@@ -133,14 +138,20 @@
if (Utilities.ATLEAST_R && mVibrator.areAllPrimitivesSupported(
VibrationEffect.Composition.PRIMITIVE_QUICK_RISE,
VibrationEffect.Composition.PRIMITIVE_TICK)) {
- // quiet ramp, short pause, then sharp tick
- mAssistEffect = VibrationEffect.startComposition()
- .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f)
- .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f, 50)
- .compose();
+ if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
+ mSearchEffect = VibrationEffect.startComposition()
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f)
+ .compose();
+ } else {
+ // quiet ramp, short pause, then sharp tick
+ mSearchEffect = VibrationEffect.startComposition()
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f)
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f, 50)
+ .compose();
+ }
} else {
// fallback for devices without composition support
- mAssistEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
+ mSearchEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
}
}
@@ -184,20 +195,10 @@
}
/**
- * The assist haptic is used to be called when an assistant is invoked
- */
- public void vibrateForAssist() {
- if (mAssistEffect != null) {
- vibrate(mAssistEffect);
- }
- }
-
- /**
* This should be used to cancel a haptic in case where the haptic shouldn't be vibrating. For
- * example, when no animation is happening but a vibrator happens to be vibrating still. Need
- * boolean parameter for {@link PendingAnimation#addEndListener(Consumer)}.
+ * example, when no animation is happening but a vibrator happens to be vibrating still.
*/
- public void cancelVibrate(boolean unused) {
+ public void cancelVibrate() {
UI_HELPER_EXECUTOR.execute(mVibrator::cancel);
// reset dragTexture timestamp to be able to play dragTexture again whenever cancelled
mLastDragTime = 0;
@@ -233,4 +234,37 @@
});
}
}
+
+ /** Indicates that search has been invoked. */
+ public void vibrateForSearch() {
+ if (mSearchEffect != null) {
+ vibrate(mSearchEffect);
+ }
+ }
+
+ /** Indicates that search will be invoked if the current gesture is maintained. */
+ public void vibrateForSearchHint() {
+ if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get() && Utilities.ATLEAST_S
+ && mVibrator.areAllPrimitivesSupported(
+ VibrationEffect.Composition.PRIMITIVE_LOW_TICK)) {
+ float startScale = LauncherPrefs.get(mContext).get(
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT) / 100f;
+ float endScale = LauncherPrefs.get(mContext).get(
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT) / 100f;
+ int scaleExponent = LauncherPrefs.get(mContext).get(
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
+ int iterations = LauncherPrefs.get(mContext).get(
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
+
+ VibrationEffect.Composition composition = VibrationEffect.startComposition();
+ for (int i = 0; i < iterations; i++) {
+ float t = i / (iterations - 1f);
+ float scale = (float) Math.pow((1 - t) * startScale + t * endScale,
+ scaleExponent);
+ composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_LOW_TICK, scale);
+ }
+
+ vibrate(composition.compose());
+ }
+ }
}
diff --git a/src/com/android/launcher3/util/WindowBounds.java b/src/com/android/launcher3/util/WindowBounds.java
index 91480e1..ec3b642 100644
--- a/src/com/android/launcher3/util/WindowBounds.java
+++ b/src/com/android/launcher3/util/WindowBounds.java
@@ -67,7 +67,8 @@
return false;
}
WindowBounds other = (WindowBounds) obj;
- return other.bounds.equals(bounds) && other.insets.equals(insets);
+ return other.bounds.equals(bounds) && other.insets.equals(insets)
+ && other.rotationHint == rotationHint;
}
@Override
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 84ea871..3921e12 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -74,7 +74,6 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RunnableList;
@@ -146,6 +145,15 @@
}
/**
+ * @return {@code true} if user has selected the first split app and is in the process of
+ * selecting the second
+ */
+ default boolean isSplitSelectionEnabled() {
+ // Overridden
+ return false;
+ }
+
+ /**
* The root view to support drag-and-drop and popup support.
*/
BaseDragLayer getDragLayer();
@@ -222,12 +230,6 @@
*/
default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
- /** Onboarding preferences for any onboarding data within this context. */
- @Nullable
- default OnboardingPrefs<?> getOnboardingPrefs() {
- return null;
- }
-
/** Returns {@code true} if items are currently being bound within this context. */
default boolean isBindingItems() {
return false;
@@ -273,13 +275,19 @@
final WindowInsetsController wic = root.getWindowInsetsController();
WindowInsets insets = root.getRootWindowInsets();
boolean isImeShown = insets != null && insets.isVisible(WindowInsets.Type.ime());
- if (wic != null && isImeShown) {
- StatsLogManager slm = getStatsLogManager();
- slm.keyboardStateManager().setKeyboardState(HIDE);
+ if (wic != null) {
+ // Only hide the keyboard if it is actually showing.
+ if (isImeShown) {
+ StatsLogManager slm = getStatsLogManager();
+ slm.keyboardStateManager().setKeyboardState(HIDE);
- // this method cannot be called cross threads
- wic.hide(WindowInsets.Type.ime());
- slm.logger().log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
+ // this method cannot be called cross threads
+ wic.hide(WindowInsets.Type.ime());
+ slm.logger().log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
+ }
+
+ // If the WindowInsetsController is not null, we end here regardless of whether we
+ // hid the keyboard or not.
return;
}
}
@@ -442,6 +450,16 @@
return CellPosMapper.DEFAULT;
}
+ /** Whether bubbles are enabled. */
+ default boolean isBubbleBarEnabled() {
+ return false;
+ }
+
+ /** Whether the bubble bar has bubbles. */
+ default boolean hasBubbles() {
+ return false;
+ }
+
/**
* Returns the ActivityContext associated with the given Context, or throws an exception if
* the Context is not associated with any ActivityContext.
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index b44dbeb..2f0da03 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -155,7 +155,7 @@
setOrientation(LinearLayout.VERTICAL);
mArrowView = findViewById(R.id.arrow);
- updateArrowTipInView();
+ updateArrowTipInView(mIsPointingUp);
setAlpha(0);
// Create default open animator.
@@ -364,17 +364,18 @@
// Adjust the tooltip vertically.
@Px int viewHeight = getHeight();
+ boolean isPointingUp = mIsPointingUp;
if (mIsPointingUp
? (yCoordUpPointingTip + viewHeight > parentViewHeight)
: (yCoordDownPointingTip - viewHeight < 0)) {
// Flip the view if it exceeds the vertical bounds of screen.
- mIsPointingUp = !mIsPointingUp;
- updateArrowTipInView();
+ isPointingUp = !mIsPointingUp;
}
+ updateArrowTipInView(isPointingUp);
// Place the tooltip such that its top is at yCoordUpPointingTip if arrow is displayed
// pointing upwards, otherwise place it such that its bottom is at
// yCoordDownPointingTip.
- setY(mIsPointingUp ? yCoordUpPointingTip : yCoordDownPointingTip - viewHeight);
+ setY(isPointingUp ? yCoordUpPointingTip : yCoordDownPointingTip - viewHeight);
// Adjust the arrow's relative position on tooltip to make sure the actual position of
// arrow's pointed tip is always at arrowXCoord.
@@ -391,10 +392,10 @@
return this;
}
- private void updateArrowTipInView() {
+ private void updateArrowTipInView(boolean isPointingUp) {
ViewGroup.LayoutParams arrowLp = mArrowView.getLayoutParams();
ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
- arrowLp.width, arrowLp.height, mIsPointingUp));
+ arrowLp.width, arrowLp.height, isPointingUp));
Paint arrowPaint = arrowDrawable.getPaint();
@Px int arrowTipRadius = getContext().getResources()
.getDimensionPixelSize(R.dimen.arrow_toast_corner_radius);
@@ -403,7 +404,7 @@
mArrowView.setBackground(arrowDrawable);
// Add negative margin so that the rounded corners on base of arrow are not visible.
removeView(mArrowView);
- if (mIsPointingUp) {
+ if (isPointingUp) {
addView(mArrowView, 0);
((ViewGroup.MarginLayoutParams) arrowLp).setMargins(0, 0, 0, -1 * arrowTipRadius);
} else {
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 41b98c7..32c70a3 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -18,7 +18,6 @@
import static android.view.Gravity.LEFT;
import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -36,6 +35,7 @@
import android.os.CancellationSignal;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -288,28 +288,20 @@
} else {
int width = (int) pos.width();
int height = (int) pos.height();
- Object[] tmpObjArray = new Object[1];
- boolean[] outIsIconThemed = new boolean[1];
+ Pair<AdaptiveIconDrawable, Drawable> fullIcon = null;
if (supportsAdaptiveIcons) {
- boolean shouldThemeIcon = btvIcon instanceof FastBitmapDrawable
- && ((FastBitmapDrawable) btvIcon).isThemed();
- drawable = getFullDrawable(
- l, info, width, height, shouldThemeIcon, tmpObjArray, outIsIconThemed);
- if (drawable instanceof AdaptiveIconDrawable) {
- badge = getBadge(l, info, tmpObjArray[0], outIsIconThemed[0]);
- } else {
- // The drawable we get back is not an adaptive icon, so we need to use the
- // BubbleTextView icon that is already legacy treated.
- drawable = btvIcon;
- }
+ boolean shouldThemeIcon = (btvIcon instanceof FastBitmapDrawable fbd)
+ && fbd.isCreatedForTheme();
+ fullIcon = getFullDrawable(l, info, width, height, shouldThemeIcon);
+ } else if (!(originalView instanceof BubbleTextView)) {
+ fullIcon = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */);
+ }
+
+ if (fullIcon != null) {
+ drawable = fullIcon.first;
+ badge = fullIcon.second;
} else {
- if (originalView instanceof BubbleTextView) {
- // Similar to DragView, we simply use the BubbleTextView icon here.
- drawable = btvIcon;
- } else {
- drawable = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */,
- tmpObjArray, outIsIconThemed);
- }
+ drawable = btvIcon;
}
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index b62f60d..cf59085 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -18,7 +18,6 @@
import static androidx.core.content.ContextCompat.getColorStateList;
import static com.android.launcher3.LauncherState.EDIT_MODE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;
import static com.android.launcher3.config.FeatureFlags.MULTI_SELECT_EDIT_MODE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS;
@@ -26,7 +25,6 @@
import android.content.Context;
import android.content.Intent;
-import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -149,12 +147,8 @@
@Override
public void assignMarginsAndBackgrounds(ViewGroup viewGroup) {
- if (ENABLE_MATERIAL_U_POPUP.get()) {
- assignMarginsAndBackgrounds(viewGroup,
- getColorStateList(getContext(), mColorIds[0]).getDefaultColor());
- } else {
- assignMarginsAndBackgrounds(viewGroup, Color.TRANSPARENT);
- }
+ assignMarginsAndBackgrounds(viewGroup,
+ getColorStateList(getContext(), mColorIds[0]).getDefaultColor());
}
public static <T extends Context & ActivityContext> OptionsPopupView<T> show(
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index dcc86a1..fc9c774 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,7 +16,7 @@
package com.android.launcher3.widget;
import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.config.FeatureFlags.LARGE_SCREEN_WIDGET_PICKER;
+import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_TIP_SEEN;
import android.content.Context;
import android.graphics.Canvas;
@@ -41,6 +41,7 @@
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragOptions;
@@ -64,8 +65,6 @@
/** The default number of cells that can fit horizontally in a widget sheet. */
public static final int DEFAULT_MAX_HORIZONTAL_SPANS = 4;
- protected static final String KEY_WIDGETS_EDUCATION_TIP_SEEN =
- "launcher.widgets_education_tip_seen";
protected final Rect mInsets = new Rect();
/* Touch handling related member variables. */
@@ -194,9 +193,7 @@
int widthUsed;
if (deviceProfile.isTablet) {
int margin = deviceProfile.allAppsLeftRightMargin;
- if (deviceProfile.isLandscape
- && LARGE_SCREEN_WIDGET_PICKER.get()
- && !deviceProfile.isTwoPanels) {
+ if (deviceProfile.isLandscape && !deviceProfile.isTwoPanels) {
margin = getResources().getDimensionPixelSize(
R.dimen.widget_picker_landscape_tablet_left_right_margin);
}
@@ -333,15 +330,14 @@
/* arrowXCoord= */coords[0] + view.getWidth() / 2,
/* yCoord= */coords[1]);
if (arrowTipView != null) {
- mActivityContext.getSharedPrefs().edit()
- .putBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, true).apply();
+ LauncherPrefs.get(getContext()).put(WIDGETS_EDUCATION_TIP_SEEN, true);
}
return arrowTipView;
}
/** Returns {@code true} if tip has previously been shown on any of {@link BaseWidgetSheet}. */
protected boolean hasSeenEducationTip() {
- return mActivityContext.getSharedPrefs().getBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, false)
+ return LauncherPrefs.get(getContext()).get(WIDGETS_EDUCATION_TIP_SEEN)
|| Utilities.isRunningInTestHarness();
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 340a61e..1aa49c7 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -23,9 +23,11 @@
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
+import android.os.Parcelable;
import android.os.SystemClock;
import android.os.Trace;
import android.util.Log;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.view.MotionEvent;
@@ -37,6 +39,7 @@
import android.widget.Advanceable;
import android.widget.RemoteViews;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.CheckLongPressHelper;
@@ -63,6 +66,8 @@
private static final long ADVANCE_INTERVAL = 20000;
private static final long ADVANCE_STAGGER = 250;
+ private @Nullable CellChildViewPreLayoutListener mCellChildViewPreLayoutListener;
+
// Maintains a list of widget ids which are supposed to be auto advanced.
private static final SparseBooleanArray sAutoAdvanceWidgetIds = new SparseBooleanArray();
// Maximum duration for which updates can be deferred.
@@ -335,6 +340,26 @@
requestLayout();
}
+ /**
+ * Set the pre-layout listener
+ * @param listener The listener to be notified when {@code CellLayout} is to layout this view
+ */
+ public void setCellChildViewPreLayoutListener(
+ @NonNull CellChildViewPreLayoutListener listener) {
+ mCellChildViewPreLayoutListener = listener;
+ }
+
+ /** @return The current cell layout listener */
+ @Nullable
+ public CellChildViewPreLayoutListener getCellChildViewPreLayoutListener() {
+ return mCellChildViewPreLayoutListener;
+ }
+
+ /** Clear the listener for the pre-layout in CellLayout */
+ public void clearCellChildViewPreLayoutListener() {
+ mCellChildViewPreLayoutListener = null;
+ }
+
@Override
public void onColorsChanged(SparseIntArray colors) {
if (isDeferringUpdates()) {
@@ -460,4 +485,28 @@
}
return false;
}
+
+ /**
+ * Listener interface to be called when {@code CellLayout} is about to layout this child view
+ */
+ public interface CellChildViewPreLayoutListener {
+ /**
+ * Notify the bound changes to this view on pre-layout
+ * @param v The view which the listener is set for
+ * @param left The new left coordinate of this view
+ * @param top The new top coordinate of this view
+ * @param right The new right coordinate of this view
+ * @param bottom The new bottom coordinate of this view
+ */
+ void notifyBoundChangeOnPreLayout(View v, int left, int top, int right, int bottom);
+ }
+
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+ try {
+ super.dispatchRestoreInstanceState(container);
+ } catch (Exception e) {
+ Log.i(TAG, "Exception: " + e);
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index 10aef9a..ef51d15 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -67,7 +67,7 @@
*/
public int maxSpanY;
- private boolean mIsMinSizeFulfilled;
+ protected boolean mIsMinSizeFulfilled;
public static LauncherAppWidgetProviderInfo fromProviderInfo(Context context,
AppWidgetProviderInfo info) {
diff --git a/src/com/android/launcher3/widget/WidgetManagerHelper.java b/src/com/android/launcher3/widget/WidgetManagerHelper.java
index 737cdbd..0860e72 100644
--- a/src/com/android/launcher3/widget/WidgetManagerHelper.java
+++ b/src/com/android/launcher3/widget/WidgetManagerHelper.java
@@ -57,10 +57,15 @@
/**
* @see AppWidgetManager#getAppWidgetInfo(int)
*/
- public LauncherAppWidgetProviderInfo getLauncherAppWidgetInfo(int appWidgetId) {
- if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID) {
- return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(appWidgetId);
+ public LauncherAppWidgetProviderInfo getLauncherAppWidgetInfo(
+ int appWidgetId, ComponentName componentName) {
+
+ // For custom widgets.
+ if (appWidgetId <= LauncherAppWidgetInfo.CUSTOM_WIDGET_ID && !CustomWidgetManager
+ .INSTANCE.get(mContext).getWidgetIdForCustomProvider(componentName).equals("")) {
+ return CustomWidgetManager.INSTANCE.get(mContext).getWidgetProvider(componentName);
}
+
AppWidgetProviderInfo info = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
return info == null ? null : LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
}
diff --git a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
index 8b3bbce..44571a6 100644
--- a/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/custom/CustomAppWidgetProviderInfo.java
@@ -33,14 +33,15 @@
public class CustomAppWidgetProviderInfo extends LauncherAppWidgetProviderInfo
implements Parcelable {
- public final int providerId;
+ public final String providerId;
- protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf, int providerId) {
+ protected CustomAppWidgetProviderInfo(Parcel parcel, boolean readSelf, String providerId) {
super(parcel);
if (readSelf) {
- this.providerId = parcel.readInt();
+ this.providerId = parcel.readString();
- provider = new ComponentName(parcel.readString(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
+ provider = new ComponentName(parcel.readString(),
+ CLS_CUSTOM_WIDGET_PREFIX + parcel.readString());
label = parcel.readString();
initialLayout = parcel.readInt();
@@ -58,7 +59,10 @@
}
@Override
- public void initSpans(Context context, InvariantDeviceProfile idp) { }
+ public void initSpans(Context context, InvariantDeviceProfile idp) {
+ mIsMinSizeFulfilled = Math.min(spanX, minSpanX) <= idp.numColumns
+ && Math.min(spanY, minSpanY) <= idp.numRows;
+ }
@Override
public String getLabel(PackageManager packageManager) {
@@ -73,8 +77,9 @@
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
- out.writeInt(providerId);
+ out.writeString(providerId);
out.writeString(provider.getPackageName());
+ out.writeString(provider.getClassName());
out.writeString(label);
out.writeInt(initialLayout);
@@ -93,7 +98,7 @@
@Override
public CustomAppWidgetProviderInfo createFromParcel(Parcel parcel) {
- return new CustomAppWidgetProviderInfo(parcel, true, 0);
+ return new CustomAppWidgetProviderInfo(parcel, true, "");
}
@Override
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 2e2a968..7cf0221 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -16,7 +16,8 @@
package com.android.launcher3.widget.custom;
-import static com.android.launcher3.widget.LauncherAppWidgetProviderInfo.CLS_CUSTOM_WIDGET_PREFIX;
+import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
+import static com.android.launcher3.model.data.LauncherAppWidgetInfo.CUSTOM_WIDGET_ID;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -24,12 +25,12 @@
import android.content.Context;
import android.os.Parcel;
import android.os.Process;
-import android.util.SparseArray;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.R;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageUserKey;
@@ -39,8 +40,11 @@
import com.android.systemui.plugins.CustomWidgetPlugin;
import com.android.systemui.plugins.PluginListener;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
@@ -52,24 +56,37 @@
public static final MainThreadInitializedObject<CustomWidgetManager> INSTANCE =
new MainThreadInitializedObject<>(CustomWidgetManager::new);
+ private static final String TAG = "CustomWidgetManager";
private final Context mContext;
- /**
- * auto provider Id is an ever-increasing number that serves as the providerId whenever a new
- * custom widget has been connected.
- */
- private int mAutoProviderId = 0;
- private final SparseArray<CustomWidgetPlugin> mPlugins;
+ private final HashMap<String, CustomWidgetPlugin> mPlugins;
private final List<CustomAppWidgetProviderInfo> mCustomWidgets;
- private final SparseArray<ComponentName> mWidgetsIdMap;
+ private final HashMap<ComponentName, String> mWidgetsIdMap;
private Consumer<PackageUserKey> mWidgetRefreshCallback;
private CustomWidgetManager(Context context) {
mContext = context;
- mPlugins = new SparseArray<>();
+ mPlugins = new HashMap<>();
mCustomWidgets = new ArrayList<>();
- mWidgetsIdMap = new SparseArray<>();
+ mWidgetsIdMap = new HashMap<>();
PluginManagerWrapper.INSTANCE.get(context)
.addPluginListener(this, CustomWidgetPlugin.class, true);
+
+ if (SMARTSPACE_AS_A_WIDGET.get()) {
+ for (String s: context.getResources()
+ .getStringArray(R.array.custom_widget_providers)) {
+ try {
+ Class<?> cls = Class.forName(s);
+ CustomWidgetPlugin plugin = (CustomWidgetPlugin)
+ cls.getDeclaredConstructor(Context.class).newInstance(context);
+ mPlugins.put(plugin.getId(), plugin);
+ onPluginConnected(mPlugins.get(plugin.getId()), context);
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+ | ClassCastException | NoSuchMethodException
+ | InvocationTargetException e) {
+ Log.e(TAG, "Exception found when trying to add custom widgets: " + e);
+ }
+ }
+ }
}
@Override
@@ -79,28 +96,41 @@
@Override
public void onPluginConnected(CustomWidgetPlugin plugin, Context context) {
- mPlugins.put(mAutoProviderId, plugin);
List<AppWidgetProviderInfo> providers = AppWidgetManager.getInstance(context)
.getInstalledProvidersForProfile(Process.myUserHandle());
if (providers.isEmpty()) return;
Parcel parcel = Parcel.obtain();
providers.get(0).writeToParcel(parcel, 0);
parcel.setDataPosition(0);
- CustomAppWidgetProviderInfo info = newInfo(mAutoProviderId, plugin, parcel, context);
+ CustomAppWidgetProviderInfo info = newInfo(plugin.getId(), plugin, parcel, context);
parcel.recycle();
mCustomWidgets.add(info);
- mWidgetsIdMap.put(mAutoProviderId, info.provider);
- mWidgetRefreshCallback.accept(null);
- mAutoProviderId++;
+ mWidgetsIdMap.put(info.provider, plugin.getId());
}
@Override
public void onPluginDisconnected(CustomWidgetPlugin plugin) {
- int providerId = findProviderId(plugin);
- if (providerId == -1) return;
- mPlugins.remove(providerId);
- mCustomWidgets.remove(getWidgetProvider(providerId));
- mWidgetsIdMap.remove(providerId);
+ String providerId = plugin.getId();
+ if (mPlugins.containsKey(providerId)) {
+ mPlugins.remove(providerId);
+ }
+
+ ComponentName cn = null;
+ for (Map.Entry entry: mWidgetsIdMap.entrySet()) {
+ if (entry.getValue().equals(providerId)) {
+ cn = (ComponentName) entry.getKey();
+ }
+ }
+
+ if (cn != null) {
+ mWidgetsIdMap.remove(cn);
+ for (int i = 0; i < mCustomWidgets.size(); i++) {
+ if (mCustomWidgets.get(i).getComponent().equals(cn)) {
+ mCustomWidgets.remove(i);
+ return;
+ }
+ }
+ }
}
/**
@@ -131,12 +161,11 @@
/**
* Returns the widget id for a specific provider.
*/
- public int getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
- int index = mWidgetsIdMap.indexOfValue(provider);
- if (index >= 0) {
- return LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - mWidgetsIdMap.keyAt(index);
+ public String getWidgetIdForCustomProvider(@NonNull ComponentName provider) {
+ if (mWidgetsIdMap.containsKey(provider)) {
+ return mWidgetsIdMap.get(provider);
} else {
- return AppWidgetManager.INVALID_APPWIDGET_ID;
+ return "";
}
}
@@ -144,38 +173,26 @@
* Returns the widget provider in respect to given widget id.
*/
@Nullable
- public LauncherAppWidgetProviderInfo getWidgetProvider(int widgetId) {
- ComponentName cn = mWidgetsIdMap.get(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - widgetId);
+ public LauncherAppWidgetProviderInfo getWidgetProvider(ComponentName componentName) {
for (LauncherAppWidgetProviderInfo info : mCustomWidgets) {
- if (info.provider.equals(cn)) return info;
+ if (info.provider.equals(componentName)) return info;
}
return null;
}
- private static CustomAppWidgetProviderInfo newInfo(int providerId, CustomWidgetPlugin plugin,
+ private static CustomAppWidgetProviderInfo newInfo(String providerId, CustomWidgetPlugin plugin,
Parcel parcel, Context context) {
CustomAppWidgetProviderInfo info = new CustomAppWidgetProviderInfo(
parcel, false, providerId);
- info.provider = new ComponentName(
- context.getPackageName(), CLS_CUSTOM_WIDGET_PREFIX + providerId);
-
- info.label = plugin.getLabel();
- info.resizeMode = plugin.getResizeMode();
-
- info.spanX = plugin.getSpanX();
- info.spanY = plugin.getSpanY();
- info.minSpanX = plugin.getMinSpanX();
- info.minSpanY = plugin.getMinSpanY();
+ plugin.updateWidgetInfo(info, context);
return info;
}
- private int findProviderId(CustomWidgetPlugin plugin) {
- for (int i = 0; i < mPlugins.size(); i++) {
- int providerId = mPlugins.keyAt(i);
- if (mPlugins.get(providerId) == plugin) {
- return providerId;
- }
- }
- return -1;
+ /**
+ * Returns an id to set as the appWidgetId for a custom widget.
+ */
+ public int allocateCustomAppWidgetId(ComponentName componentName) {
+ return CUSTOM_WIDGET_ID - mCustomWidgets.indexOf(getWidgetProvider(componentName));
}
+
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index a4b605c..78116ae 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -18,7 +18,7 @@
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.config.FeatureFlags.LARGE_SCREEN_WIDGET_PICKER;
+import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_DIALOG_SEEN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
@@ -40,6 +40,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
+import android.view.WindowInsetsController;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.Button;
@@ -56,10 +57,12 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.UserManagerState;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pm.UserCache;
@@ -97,8 +100,6 @@
// resolution or landscape on phone. This ratio defines the max percentage of content area that
// the table can display.
private static final float RECOMMENDATION_TABLE_HEIGHT_RATIO = 0.75f;
- private static final String KEY_WIDGETS_EDUCATION_DIALOG_SEEN =
- "launcher.widgets_education_dialog_seen";
private final UserManagerState mUserManagerState = new UserManagerState();
private final UserHandle mCurrentUser = Process.myUserHandle();
@@ -678,10 +679,10 @@
/** Shows the {@link WidgetsFullSheet} on the launcher. */
public static WidgetsFullSheet show(Launcher launcher, boolean animate) {
- boolean isTwoPane = LARGE_SCREEN_WIDGET_PICKER.get()
- && launcher.getDeviceProfile().isTablet
+ boolean isTwoPane = launcher.getDeviceProfile().isTablet
&& launcher.getDeviceProfile().isLandscape
- && !launcher.getDeviceProfile().isTwoPanels;
+ && (!launcher.getDeviceProfile().isTwoPanels
+ || FeatureFlags.UNFOLDED_WIDGET_PICKER.get());
WidgetsFullSheet sheet;
if (isTwoPane) {
@@ -796,8 +797,7 @@
// Checks the orientation of the screen
if (mOrientation != newConfig.orientation) {
mOrientation = newConfig.orientation;
- if (LARGE_SCREEN_WIDGET_PICKER.get()
- && mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) {
+ if (mDeviceProfile.isTablet && !mDeviceProfile.isTwoPanels) {
handleClose(false);
show(Launcher.getLauncher(getContext()), false);
} else {
@@ -819,7 +819,10 @@
@Override
public void onDragStart(boolean start, float startDisplacement) {
super.onDragStart(start, startDisplacement);
- getWindowInsetsController().hide(WindowInsets.Type.ime());
+ WindowInsetsController insetsController = getWindowInsetsController();
+ if (insetsController != null) {
+ insetsController.hide(WindowInsets.Type.ime());
+ }
}
@Nullable private View getViewToShowEducationTip() {
@@ -850,15 +853,13 @@
/** Shows education dialog for widgets. */
private WidgetsEduView showEducationDialog() {
- mActivityContext.getSharedPrefs().edit()
- .putBoolean(KEY_WIDGETS_EDUCATION_DIALOG_SEEN, true).apply();
+ LauncherPrefs.get(getContext()).put(WIDGETS_EDUCATION_DIALOG_SEEN, true);
return WidgetsEduView.showEducationDialog(mActivityContext);
}
/** Returns {@code true} if education dialog has previously been shown. */
protected boolean hasSeenEducationDialog() {
- return mActivityContext.getSharedPrefs()
- .getBoolean(KEY_WIDGETS_EDUCATION_DIALOG_SEEN, false)
+ return LauncherPrefs.get(getContext()).get(WIDGETS_EDUCATION_DIALOG_SEEN)
|| Utilities.isRunningInTestHarness();
}
diff --git a/src_build_config/com/android/launcher3/BuildConfig.java b/src_build_config/com/android/launcher3/BuildConfig.java
index 1f2e0e5..3841969 100644
--- a/src_build_config/com/android/launcher3/BuildConfig.java
+++ b/src_build_config/com/android/launcher3/BuildConfig.java
@@ -27,6 +27,11 @@
public static final boolean QSB_ON_FIRST_SCREEN = true;
/**
+ * Flag to state if the widget on the top of the first screen should be shown.
+ */
+ public static final boolean WIDGET_ON_FIRST_SCREEN = false;
+
+ /**
* Flag to control various developer centric features
*/
public static final boolean IS_DEBUG_DEVICE = false;
diff --git a/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java b/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
index 56ebcc5..af4f22c 100644
--- a/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/CustomWidgetPlugin.java
@@ -17,6 +17,8 @@
package com.android.systemui.plugins;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -30,42 +32,20 @@
int VERSION = 1;
/**
- * The label to display to the user in the AppWidget picker.
- */
- String getLabel();
-
- /**
- * The default width of the widget when added to a host, in dp. The widget will get
- * at least this width, and will often be given more, depending on the host.
- */
- int getSpanX();
-
- /**
- * The default height of the widget when added to a host, in dp. The widget will get
- * at least this height, and will often be given more, depending on the host.
- */
- int getSpanY();
-
- /**
- * Minimum width (in dp) which the widget can be resized to. This field has no effect if it
- * is greater than minWidth or if horizontal resizing isn't enabled.
- */
- int getMinSpanX();
-
- /**
- * Minimum height (in dp) which the widget can be resized to. This field has no effect if it
- * is greater than minHeight or if vertical resizing isn't enabled.
- */
- int getMinSpanY();
-
- /**
- * The rules by which a widget can be resized.
- */
- int getResizeMode();
-
- /**
* Notify the plugin that container of the widget has been rendered, where the custom widget
* can be attached to.
*/
void onViewCreated(AppWidgetHostView parent);
+
+ /**
+ * Get the UUID for the custom widget.
+ */
+ String getId();
+
+ /**
+ * Used to modify a widgets' info.
+ */
+ default void updateWidgetInfo(AppWidgetProviderInfo info, Context context) {
+
+ }
}
diff --git a/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java b/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java
index 9e22355..32f0216 100644
--- a/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java
@@ -18,7 +18,6 @@
import android.app.Activity;
import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.shared.LauncherExterns;
import com.android.systemui.plugins.shared.LauncherOverlayManager;
/**
@@ -29,6 +28,6 @@
String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERLAY";
int VERSION = 1;
- LauncherOverlayManager createOverlayManager(Activity activity, LauncherExterns externs);
+ LauncherOverlayManager createOverlayManager(Activity activity);
}
diff --git a/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java b/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java
deleted file mode 100644
index 173b454..0000000
--- a/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.systemui.plugins.shared;
-
-import android.content.SharedPreferences;
-
-import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
-
-/**
- * This interface defines the set of methods that the Launcher activity exposes. Methods
- * here should be safe to call from classes outside of com.android.launcher3.*
- */
-public interface LauncherExterns {
-
- /**
- * Returns the shared main preference
- */
- SharedPreferences getSharedPrefs();
-
- /**
- * Returns the device specific preference
- */
- SharedPreferences getDevicePrefs();
-
- /**
- * Sets the overlay on the target activity
- */
- void setLauncherOverlay(LauncherOverlay overlay);
-}
diff --git a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
index 582ab23..54cc0bc 100644
--- a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
+++ b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java
@@ -15,16 +15,12 @@
*/
package com.android.systemui.plugins.shared;
-import android.app.Activity;
-import android.app.Application;
-import android.os.Bundle;
-
import java.io.PrintWriter;
/**
* Interface to control the overlay on Launcher
*/
-public interface LauncherOverlayManager extends Application.ActivityLifecycleCallbacks {
+public interface LauncherOverlayManager {
default void onDeviceProvideChanged() { }
@@ -41,30 +37,15 @@
default void hideOverlay(int duration) { }
- default boolean startSearch(byte[] config, Bundle extras) {
- return false;
- }
+ default void onActivityStarted() { }
- @Override
- default void onActivityCreated(Activity activity, Bundle bundle) { }
+ default void onActivityResumed() { }
- @Override
- default void onActivityStarted(Activity activity) { }
+ default void onActivityPaused() { }
- @Override
- default void onActivityResumed(Activity activity) { }
+ default void onActivityStopped() { }
- @Override
- default void onActivityPaused(Activity activity) { }
-
- @Override
- default void onActivityStopped(Activity activity) { }
-
- @Override
- default void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
-
- @Override
- default void onActivityDestroyed(Activity activity) { }
+ default void onActivityDestroyed() { }
interface LauncherOverlay {
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/LauncherBinder.java b/src_shortcuts_overrides/com/android/launcher3/model/LauncherBinder.java
index e1a5f24..7e73ab5 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/LauncherBinder.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/LauncherBinder.java
@@ -51,4 +51,9 @@
mBgDataModel.widgetsModel.getWidgetsListForPicker(mApp.getContext());
executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
}
+
+ @Override
+ public void bindSmartspaceWidget() {
+ executeCallbacksTask(c -> c.bindSmartspaceWidget(), mUiExecutor);
+ }
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
index 599a591..fe5c1fd 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -21,10 +21,16 @@
import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.ColorDrawable;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArrayMap;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.UserIconInfo;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
/**
@@ -48,4 +54,41 @@
public static ActivityOptions createFadeOutAnimOptions(Context context) {
return ActivityOptions.makeCustomAnimation(context, 0, android.R.anim.fade_out);
}
+
+ /**
+ * Returns a map of all users on the device to their corresponding UI properties
+ */
+ public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
+ UserManager um = context.getSystemService(UserManager.class);
+ Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
+ List<UserHandle> usersActual = um.getUserProfiles();
+ if (usersActual != null) {
+ for (UserHandle user : usersActual) {
+ long serial = um.getSerialNumberForUser(user);
+
+ // Simple check to check if the provided user is work profile
+ // TODO: Migrate to a better platform API
+ NoopDrawable d = new NoopDrawable();
+ boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
+ UserIconInfo info = new UserIconInfo(
+ user,
+ isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
+ serial);
+ users.put(user, info);
+ }
+ }
+ return users;
+ }
+
+ private static class NoopDrawable extends ColorDrawable {
+ @Override
+ public int getIntrinsicHeight() {
+ return 1;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return 1;
+ }
+ }
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
similarity index 75%
rename from src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
rename to src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index 68843f2..6afa446 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -15,8 +15,13 @@
*/
package com.android.launcher3.uioverrides.flags;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceFragmentCompat;
+
/**
* Place holder class for developer options.
*/
-public class DeveloperOptionsFragment {
+public class DeveloperOptionsUI {
+
+ public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) { }
}
diff --git a/tests/Android.bp b/tests/Android.bp
index fec7de9..8725b46 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -29,6 +29,30 @@
],
}
+// Source code used for screenshot tests
+filegroup {
+ name: "launcher-image-tests-src",
+ srcs: [
+ "src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java",
+ "src/com/android/launcher3/celllayout/CellLayoutBoard.java",
+ "src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java",
+ "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
+ "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
+ "src/com/android/launcher3/ui/TestViewHelpers.java",
+ "src/com/android/launcher3/util/LauncherLayoutBuilder.java",
+ "src/com/android/launcher3/util/ModelTestExtensions.kt",
+ "src/com/android/launcher3/util/TestConstants.java",
+ "src/com/android/launcher3/util/TestUtil.java",
+ "src/com/android/launcher3/util/Wait.java",
+ "src/com/android/launcher3/util/WidgetUtils.java",
+ "src/com/android/launcher3/util/rule/*.java",
+ "src/com/android/launcher3/util/rule/*.kt",
+ "src/com/android/launcher3/util/viewcapture_analysis/*.java",
+ "src/com/android/launcher3/testcomponent/*.java",
+ "src/com/android/launcher3/testcomponent/*.kt",
+ ],
+}
+
// Source code used for non-quickstep tests
filegroup {
name: "launcher-non-quickstep-tests-src",
@@ -42,10 +66,18 @@
filegroup {
name: "launcher-oop-tests-src",
srcs: [
+ "src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java",
+ "src/com/android/launcher3/allapps/TaplTestsAllAppsIconsWorking.java",
+ "src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java",
+ "src/com/android/launcher3/dragging/TaplDragTest.java",
+ "src/com/android/launcher3/dragging/TaplUninstallRemove.java",
"src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
"src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
"src/com/android/launcher3/ui/TaplTestsLauncher3.java",
+ "src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java",
+ "src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java",
"src/com/android/launcher3/util/LauncherLayoutBuilder.java",
+ "src/com/android/launcher3/util/TestConstants.java",
"src/com/android/launcher3/util/TestUtil.java",
"src/com/android/launcher3/util/Wait.java",
"src/com/android/launcher3/util/WidgetUtils.java",
@@ -54,8 +86,8 @@
"src/com/android/launcher3/util/rule/SamplerRule.java",
"src/com/android/launcher3/util/rule/ScreenRecordRule.java",
"src/com/android/launcher3/util/rule/ShellCommandRule.java",
+ "src/com/android/launcher3/util/rule/TestIsolationRule.java",
"src/com/android/launcher3/util/rule/TestStabilityRule.java",
- "src/com/android/launcher3/util/rule/TISBindRule.java",
"src/com/android/launcher3/util/viewcapture_analysis/*.java",
"src/com/android/launcher3/testcomponent/BaseTestingActivity.java",
"src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java",
@@ -73,6 +105,7 @@
asset_dirs: ["assets"],
resource_dirs: ["res"],
static_libs: [
+ "flag-junit-base",
"launcher-aosp-tapl",
"androidx.test.core",
"androidx.test.runner",
@@ -82,11 +115,14 @@
"androidx.test.espresso.contrib",
"androidx.test.espresso.intents",
"androidx.test.uiautomator_uiautomator",
- "mockito-target-inline-minus-junit4",
+ "mockito-kotlin2",
+ "mockito-target-extended-minus-junit4",
"launcher_log_protos_lite",
"truth",
"platform-test-rules",
"testables",
+ "com_android_launcher3_flags_lib",
+ "com_android_wm_shell_flags_lib",
],
manifest: "AndroidManifest-common.xml",
platform_apis: true,
@@ -103,12 +139,16 @@
":launcher-tests-src",
":launcher-non-quickstep-tests-src",
],
- static_libs: ["Launcher3TestLib"],
+ static_libs: [
+ "Launcher3TestLib",
+ "com_android_launcher3_flags_lib",
+ ],
libs: [
"android.test.base",
"android.test.runner",
"android.test.mock",
],
+ // Libraries used by mockito inline extended
jni_libs: [
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
diff --git a/tests/OWNERS b/tests/OWNERS
index 6b8643c..b5ee7d7 100644
--- a/tests/OWNERS
+++ b/tests/OWNERS
@@ -3,3 +3,4 @@
sunnygoyal@google.com
winsonc@google.com
hyunyoungs@google.com
+mateuszc@google.com
diff --git a/tests/assets/databases/v30_workspace_items.sql b/tests/assets/databases/v30_workspace_items.sql
new file mode 100644
index 0000000..fcf5788
--- /dev/null
+++ b/tests/assets/databases/v30_workspace_items.sql
@@ -0,0 +1,5 @@
+DROP TABLE IF EXISTS 'favorites';
+CREATE TABLE favorites (_id INTEGER PRIMARY KEY,title TEXT,intent TEXT,container INTEGER,screen INTEGER,cellX INTEGER,cellY INTEGER,spanX INTEGER,spanY INTEGER,itemType INTEGER,appWidgetId INTEGER NOT NULL DEFAULT -1,iconPackage TEXT,iconResource TEXT,icon BLOB,appWidgetProvider TEXT,modified INTEGER NOT NULL DEFAULT 0,restored INTEGER NOT NULL DEFAULT 0,profileId INTEGER DEFAULT 0,rank INTEGER NOT NULL DEFAULT 0,options INTEGER NOT NULL DEFAULT 0,appWidgetSource INTEGER NOT NULL DEFAULT -1);
+INSERT INTO 'favorites' VALUES(1,'Phone','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.dialer/.extensions.GoogleDialtactsActivity;end',-101,0,0,0,1,1,0,-1,"iconPackage1","iconResource1",NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(2,'Messages','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.messaging/.ui.ConversationListActivity;end',-101,1,1,0,1,1,0,-1,"iconPackage2","iconResource2",NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(3,'Play Store','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.vending/.AssetBrowserActivity;end',-101,2,2,0,1,1,0,-1,"iconPackage3","iconResource3",NULL,NULL,0,0,0,0,0,-1);
\ No newline at end of file
diff --git a/tests/assets/databases/workspace_items.sql b/tests/assets/databases/workspace_items.sql
new file mode 100644
index 0000000..68f7d50
--- /dev/null
+++ b/tests/assets/databases/workspace_items.sql
@@ -0,0 +1,79 @@
+DROP TABLE IF EXISTS 'favorites';
+CREATE TABLE favorites (_id INTEGER PRIMARY KEY,title TEXT,intent TEXT,container INTEGER,screen INTEGER,cellX INTEGER,cellY INTEGER,spanX INTEGER,spanY INTEGER,itemType INTEGER,appWidgetId INTEGER NOT NULL DEFAULT -1,icon BLOB,appWidgetProvider TEXT,modified INTEGER NOT NULL DEFAULT 0,restored INTEGER NOT NULL DEFAULT 0,profileId INTEGER DEFAULT 0,rank INTEGER NOT NULL DEFAULT 0,options INTEGER NOT NULL DEFAULT 0,appWidgetSource INTEGER NOT NULL DEFAULT -1);
+INSERT INTO 'favorites' VALUES(1,'Phone','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.dialer/.extensions.GoogleDialtactsActivity;end',-101,0,0,0,1,1,0,-1,NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(2,'Messages','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.messaging/.ui.ConversationListActivity;end',-101,1,1,0,1,1,0,-1,NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(3,'Play Store','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.vending/.AssetBrowserActivity;end',-101,2,2,0,1,1,0,-1,NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(4,'Chrome','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.chrome/com.google.android.apps.chrome.Main;end',-101,3,3,0,1,1,0,-1,NULL,NULL,0,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(6,'Settings','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.settings/.Settings;end',-100,0,0,1,1,1,0,-1,X'',NULL,1693590010654,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(7,'Drive','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.docs/.app.NewMainProxyActivity;end',-100,0,1,2,1,1,0,-1,X'',NULL,1693589533751,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(8,'Better Bug','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.internal.betterbug/com.google.android.apps.betterbug.bugslist.BugsListActivity;end',16,0,0,0,1,1,0,-1,X'',NULL,1693589597917,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(9,'Flag Flipper','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.theflippinapp/.MainActivity;end',-100,0,3,2,1,1,0,-1,X'',NULL,1693589546863,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(10,NULL,NULL,-100,0,1,3,3,2,4,3,NULL,'com.google.android.apps.docs/com.google.android.apps.docs.drive.widget.suggestion.SuggestionAppWidgetProvider',1693589554018,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(11,'Scan','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_scan;end',-100,0,0,3,1,1,6,-1,X'',NULL,1693589559601,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(12,'Upload','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_upload;end',-100,0,0,4,1,1,6,-1,X'',NULL,1693589576040,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(13,'Search','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_search;end',-100,0,4,4,1,1,6,-1,X'',NULL,1693589582487,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(15,'BluetoothCompanionApp','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.bluetooth.companion/.MainActivity;end',-100,0,1,1,1,1,0,-1,X'',NULL,1693589594115,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(16,'Better Bug',NULL,-100,0,3,1,1,1,2,-1,NULL,NULL,1693589600675,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(17,'Better Bug','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.internal.betterbug/com.google.android.apps.betterbug.bugslist.BugsListActivity;end',16,0,1,0,1,1,0,-1,X'',NULL,1693589597936,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(18,'Better Bug','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.internal.betterbug/com.google.android.apps.betterbug.bugslist.BugsListActivity;end',16,0,0,1,1,1,0,-1,X'',NULL,1693589603123,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(19,'Incognito Tab','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.chrome;component=com.android.chrome/com.google.android.apps.chrome.Main;S.shortcut_id=dynamic-new-incognito-tab-shortcut;end',-100,0,2,2,1,1,6,-1,X'',NULL,1693589609963,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(20,NULL,NULL,-100,1,0,0,3,2,4,5,NULL,'com.google.android.deskclock/com.android.alarmclock.AnalogAppWidgetProvider',1693589630235,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(21,NULL,NULL,-100,1,1,3,2,2,4,6,NULL,'com.android.chrome/org.chromium.chrome.browser.quickactionsearchwidget.QuickActionSearchWidgetProvider$QuickActionSearchWidgetProviderDino',1693589677239,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(22,'New tab','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.chrome;component=com.android.chrome/com.google.android.apps.chrome.Main;S.shortcut_id=new-tab-shortcut;end',36,0,0,0,1,1,6,-1,X'',NULL,1693589694253,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(25,'Selfie','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.GoogleCamera;component=com.google.android.GoogleCamera/com.android.camera.CameraLauncher;S.shortcut_id=selfie;end',33,0,0,0,1,1,6,-1,X'',NULL,1693589686832,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(26,'Calculator','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.calculator/com.android.calculator2.Calculator;end',-100,1,4,2,1,1,0,-1,X'',NULL,1693589656954,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(27,'Calendar','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.calendar/com.android.calendar.AllInOneActivity;end',-100,1,4,0,1,1,0,-1,X'',NULL,1693589660516,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(28,'New event','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.calendar;component=com.google.android.calendar/com.android.calendar.AllInOneActivity;S.shortcut_id=launcher_shortcuts_shortcut_new_event;end',38,0,0,0,1,1,6,-1,X'',NULL,1693589698615,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(29,'New task','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.calendar;component=com.google.android.calendar/com.android.calendar.AllInOneActivity;S.shortcut_id=launcher_shortcuts_shortcut_create_task;end',-100,1,0,4,1,1,6,-1,X'',NULL,1693589677243,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(30,'Contacts','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.contacts/com.android.contacts.activities.PeopleActivity;end',-100,1,4,1,1,1,0,-1,X'',NULL,1693589671550,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(31,'Alex Eaves','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.contacts;component=com.google.android.contacts/com.android.contacts.activities.PeopleActivity;S.shortcut_id=822i60c772551678bd93;end',-100,1,4,3,1,1,6,-1,X'',NULL,1693589681873,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(32,'Add contact','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.contacts;component=com.google.android.contacts/com.android.contacts.activities.PeopleActivity;S.shortcut_id=shortcut-add-contact;end',-100,1,3,3,1,1,6,-1,X'',NULL,1693589681880,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(33,'Call',NULL,-100,1,3,2,1,1,2,-1,NULL,NULL,1693589687263,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(34,'Contacts','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.contacts/com.android.contacts.activities.PeopleActivity;end',33,0,1,0,1,1,0,-1,X'',NULL,1693589686853,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(35,'Gmail','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.gm/.ConversationListActivityGmail;end',33,0,0,1,1,1,0,-1,X'',NULL,1693589690561,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(36,'Files',NULL,-100,1,3,1,1,1,2,-1,NULL,NULL,1693589706696,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(37,'Files','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.nbu.files/.home.HomeActivity;end',36,0,1,0,1,1,0,-1,X'',NULL,1693589694261,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(38,NULL,NULL,-100,1,0,3,1,1,2,-1,NULL,NULL,1693589698611,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(39,'Scan','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_scan;end',38,0,1,0,1,1,6,-1,X'',NULL,1693589698621,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(40,'Search','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_search;end',-100,1,3,4,1,1,6,-1,X'',NULL,1693589702696,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(41,'Upload','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.docs;component=com.google.android.apps.docs/.app.NewMainProxyActivity;S.shortcut_id=launcher_shortcut_upload;end',-100,1,1,2,1,1,6,-1,X'',NULL,1693589706711,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(42,'Camera Obfuscator','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.internal.camera.imageobfuscator/.activities.MainActivity;end',-100,1,3,0,1,1,0,-1,X'',NULL,1693589710458,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(43,'Files','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.nbu.files/.home.HomeActivity;end',45,0,0,0,1,1,0,-1,X'',NULL,1693589727388,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(44,'Flag Flipper','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.theflippinapp/.MainActivity;end',-100,2,1,0,1,1,0,-1,X'',NULL,1693589724756,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(45,NULL,NULL,-100,2,0,0,1,1,2,-1,NULL,NULL,1693589727385,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(46,'Flag Flipper','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.theflippinapp/.MainActivity;end',45,0,1,0,1,1,0,-1,X'',NULL,1693589727398,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(47,'Gmail','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.gm/.ConversationListActivityGmail;end',-100,2,2,0,1,1,0,-1,X'',NULL,1693589730037,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(48,'Compose','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.gm;component=com.google.android.gm/.ConversationListActivityGmail;S.shortcut_id=manifest_compose_shortcut;end',-100,2,3,0,1,1,6,-1,X'',NULL,1693589733121,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(49,NULL,NULL,-100,2,0,1,3,2,4,7,NULL,'com.google.android.gm/com.google.android.gm.widget.GmailWidgetProvider',1693589740752,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(50,NULL,NULL,-100,3,1,0,4,5,4,8,NULL,'com.google.android.calendar/com.google.android.calendar.widgetmonth.MonthViewWidgetProvider',1693589746495,0,0,0,0,-111);
+INSERT INTO 'favorites' VALUES(54,'Maps','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.MapsActivity;end',-100,2,3,2,1,1,0,-1,X'',NULL,1693589785990,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(55,'Productivity',NULL,-100,2,3,4,1,1,2,-1,NULL,NULL,1693589797590,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(56,'Work','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.maps;component=com.google.android.apps.maps/com.google.android.maps.MapsActivity;S.shortcut_id=manifest_work;end',55,0,1,0,1,1,6,-1,X'',NULL,1693589789538,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(57,'Home','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.apps.maps;component=com.google.android.apps.maps/com.google.android.maps.MapsActivity;S.shortcut_id=manifest_home;end',-100,2,3,1,1,1,6,-1,X'',NULL,1693589793825,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(58,'Gyotaku','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.internal.gyotaku/.Launcher;end',-100,2,3,3,1,1,0,-1,X'',NULL,1693589797615,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(60,'Phone','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.dialer/.extensions.GoogleDialtactsActivity;end',-100,2,4,3,1,1,0,-1,X'',NULL,1693589805582,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(61,'Photos','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.photos/.home.HomeActivity;end',-100,2,4,4,1,1,0,-1,X'',NULL,1693589809050,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(63,'Pixel Logger',NULL,-100,3,0,3,1,1,2,-1,NULL,NULL,1693589820775,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(65,'Pixel Tips','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.tips/.TipsMain;end',-100,3,0,4,1,1,0,-1,X'',NULL,1693589823832,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(66,'Play Store','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.vending/.AssetBrowserActivity;end',-100,3,0,1,1,1,0,-1,X'',NULL,1693589834647,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(67,NULL,NULL,-100,4,2,0,3,2,4,10,NULL,'com.google.android.apps.youtube.music/com.google.android.apps.youtube.music.player.widget.gm3.FreeformMusicWidgetProvider',1693589842256,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(68,NULL,NULL,-100,4,0,2,4,3,4,11,NULL,'com.google.android.apps.youtube.music/com.google.android.apps.youtube.music.player.widget.gm3.FreeformMusicWidgetProvider',1693589854706,0,0,0,0,-112);
+INSERT INTO 'favorites' VALUES(69,'YouTube','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;end',-100,4,4,4,1,1,0,-1,X'',NULL,1693589859008,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(70,'Explore','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.youtube;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;S.shortcut_id=explore-shortcut;end',-100,4,4,3,1,1,6,-1,X'',NULL,1693589867283,0,0,3,0,-1);
+INSERT INTO 'favorites' VALUES(71,'Search','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.youtube;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;S.shortcut_id=search-shortcut;end',-100,4,4,2,1,1,6,-1,X'',NULL,1693589871989,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(72,'Shorts','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.youtube;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;S.shortcut_id=shorts-shortcut;end',-100,4,0,1,1,1,6,-1,X'',NULL,1693589882256,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(73,'Subscriptions','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.google.android.youtube;component=com.google.android.youtube/.app.honeycomb.Shell%24HomeActivity;S.shortcut_id=subscriptions-shortcut;end',-100,4,0,0,1,1,6,-1,X'',NULL,1693589888244,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(74,'Safety','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.safetyhub/.LauncherActivity;end',-100,4,1,1,1,1,0,-1,X'',NULL,1693589891720,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(75,'Wi‑Fi','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.settings;component=com.android.settings/.Settings;S.shortcut_id=manifest-shortcut-wifi;end',-100,5,2,0,1,1,6,-1,X'',NULL,1693589897994,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(76,'Data usage','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.settings;component=com.android.settings/.Settings;S.shortcut_id=manifest-shortcut-data-usage;end',-100,5,3,1,1,1,6,-1,X'',NULL,1693589904331,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(77,'Battery','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.settings;component=com.android.settings/.Settings;S.shortcut_id=manifest-shortcut-battery;end',-100,5,1,2,1,1,6,-1,X'',NULL,1693589907795,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(78,'Internet','#Intent;action=android.intent.action.MAIN;category=com.android.launcher3.DEEP_SHORTCUT;launchFlags=0x10200000;package=com.android.settings;component=com.android.settings/.Settings;S.shortcut_id=component-shortcut-com.android.settings%2F.Settings%24NetworkProviderSettingsActivity;end',-100,5,2,1,1,1,6,-1,X'',NULL,1693589914187,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(79,'Safety','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.safetyhub/.LauncherActivity;end',-100,5,2,3,1,1,0,-1,X'',NULL,1693589917447,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(80,'Recorder','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.recorder/.ui.recordings.MainActivity;end',-100,5,0,4,1,1,0,-1,X'',NULL,1693589920866,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(81,'Maps','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.apps.maps/com.google.android.maps.MapsActivity;end',82,0,0,0,1,1,0,-1,X'',NULL,1693589929103,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(82,NULL,NULL,-100,5,3,3,1,1,2,-1,NULL,NULL,1693589929099,0,0,0,0,-1);
+INSERT INTO 'favorites' VALUES(83,'Flag Flipper','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.theflippinapp/.MainActivity;end',82,0,1,0,1,1,0,-1,X'',NULL,1693589929134,0,0,1,0,-1);
+INSERT INTO 'favorites' VALUES(84,'Gmail','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.gm/.ConversationListActivityGmail;end',82,0,2,0,1,1,0,-1,X'',NULL,1693589938320,0,0,2,0,-1);
+INSERT INTO 'favorites' VALUES(85,'Google','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.googlequicksearchbox/.SearchActivity;end',82,0,0,1,1,1,0,-1,X'',NULL,1693589938321,0,0,3,0,-1);
+INSERT INTO 'favorites' VALUES(86,'Calendar','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.google.android.calendar/com.android.calendar.AllInOneActivity;end',82,0,1,1,1,1,0,-1,X'',NULL,1693589938316,0,0,4,0,-1);
+INSERT INTO 'favorites' VALUES(87,'Chrome','#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.chrome/com.google.android.apps.chrome.Main;end',82,0,2,1,1,1,0,-1,X'',NULL,1693589941181,0,0,5,0,-1);
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
new file mode 100644
index 0000000..6c3fa5e
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1080.0px (411.42856dp)
+ heightPx: 2400.0px (914.2857dp)
+ availableWidthPx: 1080.0px (411.42856dp)
+ availableHeightPx: 2219.0px (845.3333dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 118.0px (44.95238dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 63.0px (24.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 159.0px (60.57143dp)
+ cellHeightPx: 229.0px (87.2381dp)
+ getCellSize().x: 207.0px (78.85714dp)
+ getCellSize().y: 383.0px (145.90475dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 21.0px (8.0dp)
+ cellLayoutPaddingPx.top: 28.0px (10.666667dp)
+ cellLayoutPaddingPx.right: 21.0px (8.0dp)
+ cellLayoutPaddingPx.bottom: 28.0px (10.666667dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 38.0px (14.476191dp)
+ iconDrawablePaddingPx: 12.0px (4.571429dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 195.0px (74.28571dp)
+ folderCellHeightPx: 230.0px (87.61905dp)
+ folderChildIconSizePx: 147.0px (56.0dp)
+ folderChildTextSizePx: 38.0px (14.476191dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 146.0px (55.61905dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 366.0px (139.42857dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsPadding.top: 0.0px (0.0dp)
+ allAppsPadding.left: 0.0px (0.0dp)
+ allAppsPadding.right: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 273.0px (104.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 107.0px (40.761906dp)
+ getHotseatLayoutPadding(context).left: 21.0px (8.0dp)
+ getHotseatLayoutPadding(context).right: 21.0px (8.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 0.0px (0.0dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 0.0px (0.0dp)
+ workspacePadding.bottom: 245.0px (93.333336dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 773.0px (294.4762dp)
+ unscaled extraSpace: 773.0px (294.4762dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 63.0px (24.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 84.0px (32.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1927.0px (734.0952dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7781155px (0.29642496dp)
+ getCellLayoutHeight(): 1974.0px (752.0dp)
+ getCellLayoutWidth(): 1080.0px (411.42856dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
new file mode 100644
index 0000000..cd06ed9
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1080.0px (411.42856dp)
+ heightPx: 2400.0px (914.2857dp)
+ availableWidthPx: 1080.0px (411.42856dp)
+ availableHeightPx: 2156.0px (821.3333dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 118.0px (44.95238dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 126.0px (48.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 159.0px (60.57143dp)
+ cellHeightPx: 229.0px (87.2381dp)
+ getCellSize().x: 207.0px (78.85714dp)
+ getCellSize().y: 379.0px (144.38095dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 21.0px (8.0dp)
+ cellLayoutPaddingPx.top: 28.0px (10.666667dp)
+ cellLayoutPaddingPx.right: 21.0px (8.0dp)
+ cellLayoutPaddingPx.bottom: 28.0px (10.666667dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 38.0px (14.476191dp)
+ iconDrawablePaddingPx: 12.0px (4.571429dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 195.0px (74.28571dp)
+ folderCellHeightPx: 230.0px (87.61905dp)
+ folderChildIconSizePx: 147.0px (56.0dp)
+ folderChildTextSizePx: 38.0px (14.476191dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 146.0px (55.61905dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 366.0px (139.42857dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsPadding.top: 0.0px (0.0dp)
+ allAppsPadding.left: 0.0px (0.0dp)
+ allAppsPadding.right: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 294.0px (112.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 147.0px (56.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 128.0px (48.761906dp)
+ getHotseatLayoutPadding(context).left: 21.0px (8.0dp)
+ getHotseatLayoutPadding(context).right: 21.0px (8.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 0.0px (0.0dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 0.0px (0.0dp)
+ workspacePadding.bottom: 203.0px (77.333336dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 752.0px (286.4762dp)
+ unscaled extraSpace: 752.0px (286.4762dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 126.0px (48.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 84.0px (32.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1906.0px (726.0952dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.77572966px (0.29551607dp)
+ getCellLayoutHeight(): 1953.0px (744.0dp)
+ getCellLayoutWidth(): 1080.0px (411.42856dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
new file mode 100644
index 0000000..cd19907
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2400.0px (914.2857dp)
+ heightPx: 1080.0px (411.42856dp)
+ availableWidthPx: 2282.0px (869.3333dp)
+ availableHeightPx: 943.0px (359.2381dp)
+ mInsets.left: 118.0px (44.95238dp)
+ mInsets.top: 74.0px (28.190475dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 63.0px (24.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 152.0px (57.904762dp)
+ cellHeightPx: 166.0px (63.238094dp)
+ getCellSize().x: 393.0px (149.71428dp)
+ getCellSize().y: 180.0px (68.57143dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.bottom: 40.0px (15.238095dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 0.0px (0.0dp)
+ iconDrawablePaddingPx: 0.0px (0.0dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 163.0px (62.095238dp)
+ folderCellHeightPx: 192.0px (73.14286dp)
+ folderChildIconSizePx: 123.0px (46.857143dp)
+ folderChildTextSizePx: 32.0px (12.190476dp)
+ folderChildDrawablePaddingPx: 3.0px (1.1428572dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 53.0px (20.190475dp)
+ folderFooterHeight: 123.0px (46.857143dp)
+ bottomSheetTopPadding: 114.0px (43.42857dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 372.0px (141.71428dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsPadding.top: 0.0px (0.0dp)
+ allAppsPadding.left: 0.0px (0.0dp)
+ allAppsPadding.right: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 252.0px (96.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 0.0px (0.0dp)
+ mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
+ mHotseatBarWorkspaceSpacePx: 42.0px (16.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)
+ getHotseatLayoutPadding(context).top: 64.0px (24.380953dp)
+ getHotseatLayoutPadding(context).bottom: 112.0px (42.666668dp)
+ getHotseatLayoutPadding(context).left: 42.0px (16.0dp)
+ getHotseatLayoutPadding(context).right: 63.0px (24.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)
+ workspacePadding.left: 10.0px (3.8095238dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 199.0px (75.809525dp)
+ workspacePadding.bottom: 0.0px (0.0dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 73.0px (27.809525dp)
+ unscaled extraSpace: 73.0px (27.809525dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 63.0px (24.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 16.0px (6.095238dp)
+ dropTargetBarSizePx: 95.0px (36.190475dp)
+ dropTargetBarBottomMarginPx: 16.0px (6.095238dp)
+ getCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)
+ getCellLayoutSpringLoadShrunkBottom(): 952.0px (362.66666dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.79639447px (0.30338836dp)
+ getCellLayoutHeight(): 943.0px (359.2381dp)
+ getCellLayoutWidth(): 2073.0px (789.7143dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
new file mode 100644
index 0000000..8850583
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:false
+ isPhone:true
+ transposeLayoutWithOrientation:true
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2400.0px (914.2857dp)
+ heightPx: 1080.0px (411.42856dp)
+ availableWidthPx: 2156.0px (821.3333dp)
+ availableHeightPx: 1006.0px (383.2381dp)
+ mInsets.left: 118.0px (44.95238dp)
+ mInsets.top: 74.0px (28.190475dp)
+ mInsets.right: 126.0px (48.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:2.2222223
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 5
+ inv.numColumns: 5
+ inv.numSearchContainerColumns: 5
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 152.0px (57.904762dp)
+ cellHeightPx: 166.0px (63.238094dp)
+ getCellSize().x: 368.0px (140.19048dp)
+ getCellSize().y: 193.0px (73.52381dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 53.0px (20.190475dp)
+ cellLayoutPaddingPx.bottom: 40.0px (15.238095dp)
+ iconSizePx: 147.0px (56.0dp)
+ iconTextSizePx: 0.0px (0.0dp)
+ iconDrawablePaddingPx: 0.0px (0.0dp)
+ inv.numFolderRows: 4
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 173.0px (65.90476dp)
+ folderCellHeightPx: 205.0px (78.09524dp)
+ folderChildIconSizePx: 131.0px (49.904762dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 4.0px (1.5238096dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 56.0px (21.333334dp)
+ folderFooterHeight: 131.0px (49.904762dp)
+ bottomSheetTopPadding: 114.0px (43.42857dp)
+ bottomSheetOpenDuration: 267
+ bottomSheetCloseDuration: 267
+ bottomSheetWorkspaceScale: 1.0
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 788.0px (300.1905dp)
+ allAppsOpenDuration: 600
+ allAppsCloseDuration: 300
+ allAppsIconSizePx: 147.0px (56.0dp)
+ allAppsIconTextSizePx: 38.0px (14.476191dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 372.0px (141.71428dp)
+ allAppsCellWidthPx: 189.0px (72.0dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 5
+ allAppsPadding.top: 0.0px (0.0dp)
+ allAppsPadding.left: 0.0px (0.0dp)
+ allAppsPadding.right: 0.0px (0.0dp)
+ allAppsLeftRightMargin: 0.0px (0.0dp)
+ hotseatBarSizePx: 252.0px (96.0dp)
+ inv.hotseatColumnSpan: 5
+ hotseatCellHeightPx: 166.0px (63.238094dp)
+ hotseatBarBottomSpacePx: 0.0px (0.0dp)
+ mHotseatBarEdgePaddingPx: 63.0px (24.0dp)
+ mHotseatBarWorkspaceSpacePx: 42.0px (16.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)
+ getHotseatLayoutPadding(context).top: 64.0px (24.380953dp)
+ getHotseatLayoutPadding(context).bottom: 49.0px (18.666666dp)
+ getHotseatLayoutPadding(context).left: 42.0px (16.0dp)
+ getHotseatLayoutPadding(context).right: 189.0px (72.0dp)
+ numShownHotseatIcons: 5
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:false
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)
+ workspacePadding.left: 10.0px (3.8095238dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 199.0px (75.809525dp)
+ workspacePadding.bottom: 0.0px (0.0dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 136.0px (51.809525dp)
+ unscaled extraSpace: 136.0px (51.809525dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 16.0px (6.095238dp)
+ dropTargetBarSizePx: 95.0px (36.190475dp)
+ dropTargetBarBottomMarginPx: 16.0px (6.095238dp)
+ getCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1008.0px (384.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8021869px (0.305595dp)
+ getCellLayoutHeight(): 1006.0px (383.2381dp)
+ getCellLayoutWidth(): 1947.0px (741.7143dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
new file mode 100644
index 0000000..26b86dc
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2560.0px (1280.0dp)
+ heightPx: 1600.0px (800.0dp)
+ availableWidthPx: 2560.0px (1280.0dp)
+ availableHeightPx: 1496.0px (748.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(120.0, 104.0)dp
+ cellWidthPx: 240.0px (120.0dp)
+ cellHeightPx: 208.0px (104.0dp)
+ getCellSize().x: 240.0px (120.0dp)
+ getCellSize().y: 208.0px (104.0dp)
+ cellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)
+ cellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)
+ cellLayoutPaddingPx.left: 59.0px (29.5dp)
+ cellLayoutPaddingPx.top: 25.0px (12.5dp)
+ cellLayoutPaddingPx.right: 59.0px (29.5dp)
+ cellLayoutPaddingPx.bottom: 59.0px (29.5dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 240.0px (120.0dp)
+ folderCellHeightPx: 208.0px (104.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 11.0px (5.5dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 104.0px (52.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1496.0px (748.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 322.0px (161.0dp)
+ allAppsCellWidthPx: 252.0px (126.0dp)
+ allAppsBorderSpacePxX: 32.0px (16.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsPadding.top: 104.0px (52.0dp)
+ allAppsPadding.left: 32.0px (16.0dp)
+ allAppsPadding.right: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 412.0px (206.0dp)
+ hotseatBarSizePx: 200.0px (100.0dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 80.0px (40.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
+ getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 100.0px (50.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1224.0px (612.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)
+ workspacePadding.left: 181.0px (90.5dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 181.0px (90.5dp)
+ workspacePadding.bottom: 244.0px (122.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 80.0px (40.0dp)
+ unscaled extraSpace: 80.0px (40.0dp)
+ maxEmptySpace: 200.0px (100.0dp)
+ workspaceTopPadding: 25.0px (12.5dp)
+ workspaceBottomPadding: 55.0px (27.5dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 64.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)
+ getCellLayoutHeight(): 1252.0px (626.0dp)
+ getCellLayoutWidth(): 2198.0px (1099.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
new file mode 100644
index 0000000..5778306
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletLandscape3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2560.0px (1280.0dp)
+ heightPx: 1600.0px (800.0dp)
+ availableWidthPx: 2560.0px (1280.0dp)
+ availableHeightPx: 1496.0px (748.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(120.0, 104.0)dp
+ cellWidthPx: 240.0px (120.0dp)
+ cellHeightPx: 208.0px (104.0dp)
+ getCellSize().x: 240.0px (120.0dp)
+ getCellSize().y: 208.0px (104.0dp)
+ cellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)
+ cellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)
+ cellLayoutPaddingPx.left: 59.0px (29.5dp)
+ cellLayoutPaddingPx.top: 25.0px (12.5dp)
+ cellLayoutPaddingPx.right: 59.0px (29.5dp)
+ cellLayoutPaddingPx.bottom: 59.0px (29.5dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 240.0px (120.0dp)
+ folderCellHeightPx: 208.0px (104.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 11.0px (5.5dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 104.0px (52.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 1496.0px (748.0dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 322.0px (161.0dp)
+ allAppsCellWidthPx: 252.0px (126.0dp)
+ allAppsBorderSpacePxX: 32.0px (16.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsPadding.top: 104.0px (52.0dp)
+ allAppsPadding.left: 32.0px (16.0dp)
+ allAppsPadding.right: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 412.0px (206.0dp)
+ hotseatBarSizePx: 200.0px (100.0dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 80.0px (40.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)
+ getHotseatLayoutPadding(context).left: 668.0px (334.0dp)
+ getHotseatLayoutPadding(context).right: 668.0px (334.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 100.0px (50.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1224.0px (612.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)
+ workspacePadding.left: 181.0px (90.5dp)
+ workspacePadding.top: 0.0px (0.0dp)
+ workspacePadding.right: 181.0px (90.5dp)
+ workspacePadding.bottom: 244.0px (122.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 80.0px (40.0dp)
+ unscaled extraSpace: 80.0px (40.0dp)
+ maxEmptySpace: 200.0px (100.0dp)
+ workspaceTopPadding: 25.0px (12.5dp)
+ workspaceBottomPadding: 55.0px (27.5dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 64.0px (32.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)
+ getCellLayoutHeight(): 1252.0px (626.0dp)
+ getCellLayoutWidth(): 2198.0px (1099.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
new file mode 100644
index 0000000..9e943ae
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1600.0px (800.0dp)
+ heightPx: 2560.0px (1280.0dp)
+ availableWidthPx: 1600.0px (800.0dp)
+ availableHeightPx: 2456.0px (1228.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(102.0, 120.0)dp
+ cellWidthPx: 204.0px (102.0dp)
+ cellHeightPx: 240.0px (120.0dp)
+ getCellSize().x: 204.0px (102.0dp)
+ getCellSize().y: 240.0px (120.0dp)
+ cellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)
+ cellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)
+ cellLayoutPaddingPx.left: 72.0px (36.0dp)
+ cellLayoutPaddingPx.top: 72.0px (36.0dp)
+ cellLayoutPaddingPx.right: 72.0px (36.0dp)
+ cellLayoutPaddingPx.bottom: 72.0px (36.0dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 204.0px (102.0dp)
+ folderCellHeightPx: 240.0px (120.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 22.0px (11.0dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 704.0px (352.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 2019.0px (1009.5dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 354.0px (177.0dp)
+ allAppsCellWidthPx: 192.0px (96.0dp)
+ allAppsBorderSpacePxX: 16.0px (8.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsPadding.top: 541.0px (270.5dp)
+ allAppsPadding.left: 32.0px (16.0dp)
+ allAppsPadding.right: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 152.0px (76.0dp)
+ hotseatBarSizePx: 272.0px (136.0dp)
+ inv.hotseatColumnSpan: 6
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 152.0px (76.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)
+ getHotseatLayoutPadding(context).left: 150.0px (75.0dp)
+ getHotseatLayoutPadding(context).right: 150.0px (75.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 116.0px (58.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1300.0px (650.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)
+ workspacePadding.left: 36.0px (18.0dp)
+ workspacePadding.top: 132.0px (66.0dp)
+ workspacePadding.right: 36.0px (18.0dp)
+ workspacePadding.bottom: 468.0px (234.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 424.0px (212.0dp)
+ unscaled extraSpace: 424.0px (212.0dp)
+ maxEmptySpace: 19998.0px (9999.0dp)
+ workspaceTopPadding: 204.0px (102.0dp)
+ workspaceBottomPadding: 220.0px (110.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 220.0px (110.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 96.0px (48.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)
+ getCellLayoutHeight(): 1856.0px (928.0dp)
+ getCellLayoutWidth(): 1528.0px (764.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
new file mode 100644
index 0000000..f159b85
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/tabletPortrait3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.0 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:false
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1600.0px (800.0dp)
+ heightPx: 2560.0px (1280.0dp)
+ availableWidthPx: 1600.0px (800.0dp)
+ availableHeightPx: 2456.0px (1228.0dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 104.0px (52.0dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.6
+ isResponsiveGrid:false
+ isScalableGrid:true
+ inv.numRows: 5
+ inv.numColumns: 6
+ inv.numSearchContainerColumns: 3
+ minCellSize: PointF(102.0, 120.0)dp
+ cellWidthPx: 204.0px (102.0dp)
+ cellHeightPx: 240.0px (120.0dp)
+ getCellSize().x: 204.0px (102.0dp)
+ getCellSize().y: 240.0px (120.0dp)
+ cellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)
+ cellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)
+ cellLayoutPaddingPx.left: 72.0px (36.0dp)
+ cellLayoutPaddingPx.top: 72.0px (36.0dp)
+ cellLayoutPaddingPx.right: 72.0px (36.0dp)
+ cellLayoutPaddingPx.bottom: 72.0px (36.0dp)
+ iconSizePx: 120.0px (60.0dp)
+ iconTextSizePx: 28.0px (14.0dp)
+ iconDrawablePaddingPx: 9.0px (4.5dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 3
+ folderCellWidthPx: 204.0px (102.0dp)
+ folderCellHeightPx: 240.0px (120.0dp)
+ folderChildIconSizePx: 120.0px (60.0dp)
+ folderChildTextSizePx: 28.0px (14.0dp)
+ folderChildDrawablePaddingPx: 22.0px (11.0dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 0.0px (0.0dp)
+ folderTopPadding: 48.0px (24.0dp)
+ folderFooterHeight: 112.0px (56.0dp)
+ bottomSheetTopPadding: 704.0px (352.0dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 0.0
+ allAppsShiftRange: 2019.0px (1009.5dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 120.0px (60.0dp)
+ allAppsIconTextSizePx: 28.0px (14.0dp)
+ allAppsIconDrawablePaddingPx: 9.0px (4.5dp)
+ allAppsCellHeightPx: 354.0px (177.0dp)
+ allAppsCellWidthPx: 192.0px (96.0dp)
+ allAppsBorderSpacePxX: 16.0px (8.0dp)
+ allAppsBorderSpacePxY: 32.0px (16.0dp)
+ numShownAllAppsColumns: 6
+ allAppsPadding.top: 541.0px (270.5dp)
+ allAppsPadding.left: 32.0px (16.0dp)
+ allAppsPadding.right: 32.0px (16.0dp)
+ allAppsLeftRightMargin: 152.0px (76.0dp)
+ hotseatBarSizePx: 272.0px (136.0dp)
+ inv.hotseatColumnSpan: 6
+ hotseatCellHeightPx: 135.0px (67.5dp)
+ hotseatBarBottomSpacePx: 152.0px (76.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)
+ getHotseatLayoutPadding(context).left: 150.0px (75.0dp)
+ getHotseatLayoutPadding(context).right: 150.0px (75.0dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 116.0px (58.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 1300.0px (650.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)
+ workspacePadding.left: 36.0px (18.0dp)
+ workspacePadding.top: 132.0px (66.0dp)
+ workspacePadding.right: 36.0px (18.0dp)
+ workspacePadding.bottom: 468.0px (234.0dp)
+ iconScale: 1.0px (0.5dp)
+ cellScaleToFit : 1.0px (0.5dp)
+ extraSpace: 424.0px (212.0dp)
+ unscaled extraSpace: 424.0px (212.0dp)
+ maxEmptySpace: 19998.0px (9999.0dp)
+ workspaceTopPadding: 204.0px (102.0dp)
+ workspaceBottomPadding: 220.0px (110.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 220.0px (110.0dp)
+ dropTargetBarSizePx: 144.0px (72.0dp)
+ dropTargetBarBottomMarginPx: 96.0px (48.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)
+ getCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)
+ getCellLayoutHeight(): 1856.0px (928.0dp)
+ getCellLayoutWidth(): 1528.0px (764.0dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
new file mode 100644
index 0000000..55e9880
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1730.0px (659.0476dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 110.0px (41.904762dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
new file mode 100644
index 0000000..a2f0aa2
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelLandscape3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:true
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 2208.0px (841.1429dp)
+ heightPx: 1840.0px (700.9524dp)
+ availableWidthPx: 2208.0px (841.1429dp)
+ availableHeightPx: 1730.0px (659.0476dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 110.0px (41.904762dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 270.0px (102.85714dp)
+ getCellSize().y: 342.0px (130.28572dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 110.0px (41.904762dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 1730.0px (659.0476dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 110.0px (41.904762dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 183.0px (69.71429dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 113.0px (43.04762dp)
+ getHotseatLayoutPadding(context).right: 113.0px (43.04762dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 30.0px (11.428572dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 498.0px (189.71428dp)
+ unscaled extraSpace: 498.0px (189.71428dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 0.0px (0.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)
+ getCellLayoutHeight(): 1370.0px (521.9048dp)
+ getCellLayoutWidth(): 1083.0px (412.57144dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
new file mode 100644
index 0000000..ca42cda
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:true
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 2075.0px (790.4762dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 133.0px (50.666668dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 168.0px (64.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
new file mode 100644
index 0000000..d53badc
--- /dev/null
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/twoPanelPortrait3Button.txt
@@ -0,0 +1,129 @@
+DeviceProfile:
+ 1 dp = 2.625 px
+ isTablet:true
+ isPhone:false
+ transposeLayoutWithOrientation:false
+ isGestureMode:false
+ isLandscape:false
+ isMultiWindowMode:false
+ isTwoPanels:true
+ windowX: 0.0px (0.0dp)
+ windowY: 0.0px (0.0dp)
+ widthPx: 1840.0px (700.9524dp)
+ heightPx: 2208.0px (841.1429dp)
+ availableWidthPx: 1840.0px (700.9524dp)
+ availableHeightPx: 2075.0px (790.4762dp)
+ mInsets.left: 0.0px (0.0dp)
+ mInsets.top: 133.0px (50.666668dp)
+ mInsets.right: 0.0px (0.0dp)
+ mInsets.bottom: 0.0px (0.0dp)
+ aspectRatio:1.2
+ isResponsiveGrid:false
+ isScalableGrid:false
+ inv.numRows: 4
+ inv.numColumns: 4
+ inv.numSearchContainerColumns: 4
+ minCellSize: PointF(0.0, 0.0)dp
+ cellWidthPx: 154.0px (58.666668dp)
+ cellHeightPx: 218.0px (83.04762dp)
+ getCellSize().x: 224.0px (85.333336dp)
+ getCellSize().y: 430.0px (163.80952dp)
+ cellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)
+ cellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)
+ cellLayoutPaddingPx.left: 0.0px (0.0dp)
+ cellLayoutPaddingPx.top: 0.0px (0.0dp)
+ cellLayoutPaddingPx.right: 0.0px (0.0dp)
+ cellLayoutPaddingPx.bottom: 0.0px (0.0dp)
+ iconSizePx: 141.0px (53.714287dp)
+ iconTextSizePx: 34.0px (12.952381dp)
+ iconDrawablePaddingPx: 13.0px (4.952381dp)
+ inv.numFolderRows: 3
+ inv.numFolderColumns: 4
+ folderCellWidthPx: 189.0px (72.0dp)
+ folderCellHeightPx: 219.0px (83.42857dp)
+ folderChildIconSizePx: 141.0px (53.714287dp)
+ folderChildTextSizePx: 34.0px (12.952381dp)
+ folderChildDrawablePaddingPx: 5.0px (1.9047619dp)
+ folderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)
+ folderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)
+ folderContentPaddingLeftRight: 21.0px (8.0dp)
+ folderTopPadding: 63.0px (24.0dp)
+ folderFooterHeight: 147.0px (56.0dp)
+ bottomSheetTopPadding: 133.0px (50.666668dp)
+ bottomSheetOpenDuration: 500
+ bottomSheetCloseDuration: 500
+ bottomSheetWorkspaceScale: 0.97
+ bottomSheetDepth: 1.0
+ allAppsShiftRange: 2075.0px (790.4762dp)
+ allAppsOpenDuration: 500
+ allAppsCloseDuration: 500
+ allAppsIconSizePx: 141.0px (53.714287dp)
+ allAppsIconTextSizePx: 34.0px (12.952381dp)
+ allAppsIconDrawablePaddingPx: 21.0px (8.0dp)
+ allAppsCellHeightPx: 361.0px (137.5238dp)
+ allAppsCellWidthPx: 183.0px (69.71429dp)
+ allAppsBorderSpacePxX: 42.0px (16.0dp)
+ allAppsBorderSpacePxY: 42.0px (16.0dp)
+ numShownAllAppsColumns: 8
+ allAppsPadding.top: 133.0px (50.666668dp)
+ allAppsPadding.left: 42.0px (16.0dp)
+ allAppsPadding.right: 42.0px (16.0dp)
+ allAppsLeftRightMargin: 1.0px (0.3809524dp)
+ hotseatBarSizePx: 267.0px (101.71429dp)
+ inv.hotseatColumnSpan: 4
+ hotseatCellHeightPx: 159.0px (60.57143dp)
+ hotseatBarBottomSpacePx: 126.0px (48.0dp)
+ mHotseatBarEdgePaddingPx: 0.0px (0.0dp)
+ mHotseatBarWorkspaceSpacePx: 0.0px (0.0dp)
+ hotseatBarEndOffset: 0.0px (0.0dp)
+ hotseatQsbSpace: 0.0px (0.0dp)
+ hotseatQsbHeight: 0.0px (0.0dp)
+ springLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)
+ getHotseatLayoutPadding(context).top: 0.0px (0.0dp)
+ getHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)
+ getHotseatLayoutPadding(context).left: 98.0px (37.333332dp)
+ getHotseatLayoutPadding(context).right: 98.0px (37.333332dp)
+ numShownHotseatIcons: 6
+ hotseatBorderSpace: 0.0px (0.0dp)
+ isQsbInline: false
+ hotseatQsbWidth: 0.0px (0.0dp)
+ isTaskbarPresent:false
+ isTaskbarPresentInApps:true
+ taskbarHeight: 0.0px (0.0dp)
+ stashedTaskbarHeight: 0.0px (0.0dp)
+ taskbarBottomMargin: 0.0px (0.0dp)
+ taskbarIconSize: 0.0px (0.0dp)
+ desiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)
+ workspacePadding.left: 21.0px (8.0dp)
+ workspacePadding.top: 24.0px (9.142858dp)
+ workspacePadding.right: 21.0px (8.0dp)
+ workspacePadding.bottom: 330.0px (125.71429dp)
+ iconScale: 1.0px (0.3809524dp)
+ cellScaleToFit : 1.0px (0.3809524dp)
+ extraSpace: 849.0px (323.42856dp)
+ unscaled extraSpace: 849.0px (323.42856dp)
+ maxEmptySpace: 0.0px (0.0dp)
+ workspaceTopPadding: 0.0px (0.0dp)
+ workspaceBottomPadding: 0.0px (0.0dp)
+ overviewTaskMarginPx: 0.0px (0.0dp)
+ overviewTaskIconSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)
+ overviewTaskIconAppChipMenuDrawableSizePx: 0.0px (0.0dp)
+ overviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)
+ overviewActionsTopMarginPx: 0.0px (0.0dp)
+ overviewActionsHeight: 0.0px (0.0dp)
+ overviewActionsClaimedSpaceBelow: 0.0px (0.0dp)
+ overviewActionsButtonSpacing: 0.0px (0.0dp)
+ overviewPageSpacing: 0.0px (0.0dp)
+ overviewRowSpacing: 0.0px (0.0dp)
+ overviewGridSideMargin: 0.0px (0.0dp)
+ dropTargetBarTopMarginPx: 168.0px (64.0dp)
+ dropTargetBarSizePx: 147.0px (56.0dp)
+ dropTargetBarBottomMarginPx: 42.0px (16.0dp)
+ getCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)
+ getCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)
+ workspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)
+ getWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)
+ getCellLayoutHeight(): 1721.0px (655.619dp)
+ getCellLayoutWidth(): 899.0px (342.4762dp)
diff --git a/tests/res/xml/invalid_hotseat_file_case_1.xml b/tests/res/xml/invalid_hotseat_file_case_1.xml
index fcbc5ea..aaaf8bb 100644
--- a/tests/res/xml/invalid_hotseat_file_case_1.xml
+++ b/tests/res/xml/invalid_hotseat_file_case_1.xml
@@ -19,12 +19,14 @@
launcher:specType="height"
launcher:maxAvailableSize="847dp">
<hotseatQsbSpace launcher:ofAvailableSpace="1" />
+ <edgePadding launcher:fixedSize="36dp" />
</hotseatSpec>
<hotseatSpec
launcher:specType="height"
launcher:maxAvailableSize="9999dp">
<hotseatQsbSpace launcher:fixedSize="36dp" />
+ <edgePadding launcher:fixedSize="36dp" />
</hotseatSpec>
</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/res/xml/valid_hotseat_file.xml b/tests/res/xml/valid_hotseat_file.xml
index c7f52e8..f698bd1 100644
--- a/tests/res/xml/valid_hotseat_file.xml
+++ b/tests/res/xml/valid_hotseat_file.xml
@@ -16,15 +16,17 @@
<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
<hotseatSpec
- launcher:specType="height"
- launcher:maxAvailableSize="847dp">
+ launcher:maxAvailableSize="847dp"
+ launcher:specType="height">
<hotseatQsbSpace launcher:fixedSize="24dp" />
+ <edgePadding launcher:fixedSize="48dp" />
</hotseatSpec>
<hotseatSpec
- launcher:specType="height"
- launcher:maxAvailableSize="9999dp">
+ launcher:maxAvailableSize="9999dp"
+ launcher:specType="height">
<hotseatQsbSpace launcher:fixedSize="36dp" />
+ <edgePadding launcher:fixedSize="48dp" />
</hotseatSpec>
</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/res/xml/valid_hotseat_land_file.xml b/tests/res/xml/valid_hotseat_land_file.xml
new file mode 100644
index 0000000..fc4a836
--- /dev/null
+++ b/tests/res/xml/valid_hotseat_land_file.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<hotseatSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
+
+ <hotseatSpec
+ launcher:maxAvailableSize="743dp"
+ launcher:specType="width">
+ <hotseatQsbSpace launcher:fixedSize="0dp" />
+ <edgePadding launcher:fixedSize="48dp" />
+ </hotseatSpec>
+
+ <hotseatSpec
+ launcher:maxAvailableSize="9999dp"
+ launcher:specType="width">
+ <hotseatQsbSpace launcher:fixedSize="0dp" />
+ <edgePadding launcher:fixedSize="64dp" />
+ </hotseatSpec>
+
+</hotseatSpecs>
\ No newline at end of file
diff --git a/tests/res/xml/valid_workspace_unsorted_file.xml b/tests/res/xml/valid_workspace_unsorted_file.xml
new file mode 100644
index 0000000..1216c81
--- /dev/null
+++ b/tests/res/xml/valid_workspace_unsorted_file.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<workspaceSpecs xmlns:launcher="http://schemas.android.com/apk/res-auto">
+
+ <workspaceSpec
+ launcher:specType="height"
+ launcher:maxAvailableSize="9999dp">
+ <startPadding launcher:fixedSize="8dp" />
+ <endPadding launcher:ofRemainderSpace="1" />
+ <gutter launcher:fixedSize="16dp" />
+ <cellSize launcher:fixedSize="104dp" />
+ </workspaceSpec>
+
+ <!-- 584 grid height -->
+ <workspaceSpec
+ launcher:specType="height"
+ launcher:maxAvailableSize="584dp">
+ <startPadding launcher:fixedSize="0dp" />
+ <endPadding launcher:fixedSize="32dp" />
+ <gutter launcher:fixedSize="16dp" />
+ <cellSize launcher:ofAvailableSpace="0.15808" />
+ </workspaceSpec>
+
+ <!-- 584 grid height + 28 remainder space -->
+ <workspaceSpec
+ launcher:specType="height"
+ launcher:maxAvailableSize="612dp">
+ <startPadding launcher:fixedSize="0dp" />
+ <endPadding launcher:ofRemainderSpace="1" />
+ <gutter launcher:fixedSize="16dp" />
+ <cellSize launcher:fixedSize="104dp" />
+ </workspaceSpec>
+
+ <!-- Width spec is always the same -->
+ <workspaceSpec
+ launcher:specType="width"
+ launcher:maxAvailableSize="9999dp">
+ <startPadding launcher:fixedSize="22dp" />
+ <endPadding launcher:fixedSize="22dp" />
+ <gutter launcher:fixedSize="16dp" />
+ <cellSize launcher:ofRemainderSpace="0.25" />
+ </workspaceSpec>
+
+</workspaceSpecs>
diff --git a/tests/shared/com/android/launcher3/testing/OWNERS b/tests/shared/com/android/launcher3/testing/OWNERS
new file mode 100644
index 0000000..a818d5e
--- /dev/null
+++ b/tests/shared/com/android/launcher3/testing/OWNERS
@@ -0,0 +1,5 @@
+vadimt@google.com
+sunnygoyal@google.com
+winsonc@google.com
+hyunyoungs@google.com
+mateuszc@google.com
\ No newline at end of file
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index 825b3dc..3e80e6b 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -28,6 +28,7 @@
public static final String PAUSE_DETECTED_MESSAGE = "TAPL_PAUSE_DETECTED";
public static final String DISMISS_ANIMATION_ENDS_MESSAGE = "TAPL_DISMISS_ANIMATION_ENDS";
public static final String FOLDER_OPENED_MESSAGE = "TAPL_FOLDER_OPENED";
+ public static final String SEARCH_RESULT_COMPLETE = "SEARCH_RESULT_COMPLETE";
public static final int NORMAL_STATE_ORDINAL = 0;
public static final int SPRING_LOADED_STATE_ORDINAL = 1;
public static final int OVERVIEW_STATE_ORDINAL = 2;
@@ -102,6 +103,7 @@
public static final String REQUEST_WIDGETS_SCROLL_Y = "widgets-scroll-y";
public static final String REQUEST_TARGET_INSETS = "target-insets";
public static final String REQUEST_WINDOW_INSETS = "window-insets";
+ public static final String REQUEST_IME_INSETS = "ime-insets";
public static final String REQUEST_PID = "pid";
public static final String REQUEST_FORCE_GC = "gc";
public static final String REQUEST_RECENT_TASKS_LIST = "recent-tasks-list";
@@ -113,6 +115,7 @@
public static final String REQUEST_CLEAR_DATA = "clear-data";
public static final String REQUEST_HOTSEAT_ICON_NAMES = "get-hotseat-icon-names";
public static final String REQUEST_IS_TABLET = "is-tablet";
+ public static final String REQUEST_NUM_ALL_APPS_COLUMNS = "num-all-apps-columns";
public static final String REQUEST_IS_TWO_PANELS = "is-two-panel";
public static final String REQUEST_START_DRAG_THRESHOLD = "start-drag-threshold";
public static final String REQUEST_SHELL_DRAG_READY = "shell-drag-ready";
@@ -124,6 +127,7 @@
"taskbar-all-apps-top-padding";
public static final String REQUEST_ALL_APPS_TOP_PADDING = "all-apps-top-padding";
public static final String REQUEST_ALL_APPS_BOTTOM_PADDING = "all-apps-bottom-padding";
+ public static final String REQUEST_REFRESH_OVERVIEW_TARGET = "refresh-overview-target";
public static final String REQUEST_WORKSPACE_CELL_LAYOUT_SIZE = "workspace-cell-layout-size";
public static final String REQUEST_WORKSPACE_CELL_CENTER = "workspace-cell-center";
@@ -153,12 +157,8 @@
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
- public static final String FLAKY_QUICK_SWITCH_TO_PREVIOUS_APP = "b/286084688";
public static final String ICON_MISSING = "b/282963545";
- public static final String LAUNCH_SPLIT_PAIR = "b/288939273";
- public static final String OVERVIEW_OVER_HOME = "b/279059025";
- public static final String INCORRECT_HOME_STATE = "b/293191790";
public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
public static final String REQUEST_IS_EMULATE_DISPLAY_RUNNING = "is-emulate-display-running";
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index dd79ca8..0b31469 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -24,8 +24,10 @@
import androidx.test.core.app.ApplicationProvider
import com.android.launcher3.testing.shared.ResourceUtils
import com.android.launcher3.util.DisplayController
+import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext
import com.android.launcher3.util.NavigationMode
import com.android.launcher3.util.WindowBounds
+import com.android.launcher3.util.rule.TestStabilityRule
import com.android.launcher3.util.window.CachedDisplayInfo
import com.android.launcher3.util.window.WindowManagerProxy
import java.io.BufferedReader
@@ -34,11 +36,11 @@
import java.io.StringWriter
import kotlin.math.max
import kotlin.math.min
-import org.junit.After
-import org.junit.Before
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
+import org.junit.Rule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
/**
* This is an abstract class for DeviceProfile tests that create an InvariantDeviceProfile based on
@@ -47,27 +49,13 @@
* For an implementation that mocks InvariantDeviceProfile, use [FakeInvariantDeviceProfileTest]
*/
abstract class AbstractDeviceProfileTest {
- protected var context: Context? = null
+ protected lateinit var context: SandboxContext
protected open val runningContext: Context = ApplicationProvider.getApplicationContext()
- private var displayController: DisplayController = mock(DisplayController::class.java)
- private var windowManagerProxy: WindowManagerProxy = mock(WindowManagerProxy::class.java)
- private lateinit var originalDisplayController: DisplayController
- private lateinit var originalWindowManagerProxy: WindowManagerProxy
+ private val displayController: DisplayController = mock()
+ private val windowManagerProxy: WindowManagerProxy = mock()
+ private val launcherPrefs: LauncherPrefs = mock()
- @Before
- open fun setUp() {
- val appContext: Context = ApplicationProvider.getApplicationContext()
- originalWindowManagerProxy = WindowManagerProxy.INSTANCE.get(appContext)
- originalDisplayController = DisplayController.INSTANCE.get(appContext)
- WindowManagerProxy.INSTANCE.initializeForTesting(windowManagerProxy)
- DisplayController.INSTANCE.initializeForTesting(displayController)
- }
-
- @After
- open fun tearDown() {
- WindowManagerProxy.INSTANCE.initializeForTesting(originalWindowManagerProxy)
- DisplayController.INSTANCE.initializeForTesting(originalDisplayController)
- }
+ @Rule @JvmField val testStabilityRule = TestStabilityRule()
class DeviceSpec(
val naturalSize: Pair<Int, Int>,
@@ -283,11 +271,10 @@
) {
val windowsBounds = perDisplayBoundsCache[displayInfo]!!
val realBounds = windowsBounds[rotation]
- whenever(windowManagerProxy.getDisplayInfo(ArgumentMatchers.any())).thenReturn(displayInfo)
- whenever(windowManagerProxy.getRealBounds(ArgumentMatchers.any(), ArgumentMatchers.any()))
- .thenReturn(realBounds)
- whenever(windowManagerProxy.getRotation(ArgumentMatchers.any())).thenReturn(rotation)
- whenever(windowManagerProxy.getNavigationMode(ArgumentMatchers.any()))
+ whenever(windowManagerProxy.getDisplayInfo(any())).thenReturn(displayInfo)
+ whenever(windowManagerProxy.getRealBounds(any(), any())).thenReturn(realBounds)
+ whenever(windowManagerProxy.getRotation(any())).thenReturn(rotation)
+ whenever(windowManagerProxy.getNavigationMode(any()))
.thenReturn(
if (isGestureMode) NavigationMode.NO_BUTTON else NavigationMode.THREE_BUTTONS
)
@@ -300,11 +287,22 @@
screenHeightDp = (realBounds.bounds.height() / density).toInt()
smallestScreenWidthDp = min(screenWidthDp, screenHeightDp)
}
- context = runningContext.createConfigurationContext(config)
+ val configurationContext = runningContext.createConfigurationContext(config)
+ context =
+ SandboxContext(
+ configurationContext,
+ DisplayController.INSTANCE,
+ WindowManagerProxy.INSTANCE,
+ LauncherPrefs.INSTANCE
+ )
+ context.putObject(DisplayController.INSTANCE, displayController)
+ context.putObject(WindowManagerProxy.INSTANCE, windowManagerProxy)
+ context.putObject(LauncherPrefs.INSTANCE, launcherPrefs)
- val info = DisplayController.Info(context, windowManagerProxy, perDisplayBoundsCache)
+ whenever(launcherPrefs.get(LauncherPrefs.TASKBAR_PINNING)).thenReturn(false)
+ val info = spy(DisplayController.Info(context, windowManagerProxy, perDisplayBoundsCache))
whenever(displayController.info).thenReturn(info)
- whenever(displayController.isTransientTaskbar).thenReturn(isGestureMode)
+ whenever(info.isTransientTaskbar).thenReturn(isGestureMode)
}
/** Create a new dump of DeviceProfile, saves to a file in the device and returns it */
diff --git a/tests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt b/tests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt
new file mode 100644
index 0000000..21abab4
--- /dev/null
+++ b/tests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt
@@ -0,0 +1,171 @@
+package com.android.launcher3
+
+import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED
+import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED
+import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
+import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS
+import android.appwidget.AppWidgetManager.EXTRA_HOST_ID
+import android.content.Intent
+import android.platform.uiautomator_helpers.DeviceHelpers
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.LauncherPrefs.Companion.APP_WIDGET_IDS
+import com.android.launcher3.LauncherPrefs.Companion.OLD_APP_WIDGET_IDS
+import com.android.launcher3.util.IntArray
+import com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE
+import com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests for [AppWidgetsRestoredReceiver] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AppWidgetsRestoredReceiverTest {
+ private lateinit var launcherPrefs: LauncherPrefs
+ private lateinit var receiverUnderTest: AppWidgetsRestoredReceiver
+
+ @Before
+ fun setup() {
+ launcherPrefs = LauncherPrefs(DeviceHelpers.context)
+ receiverUnderTest = AppWidgetsRestoredReceiver()
+ }
+
+ @After
+ fun tearDown() {
+ launcherPrefs.remove(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)
+ }
+
+ @Test
+ fun `When AppWidgetsRestoredReceiver gets valid broadcast it sets old and new app widget ids`() {
+ // Given
+ val oldIds = intArrayOf(1, 2, 10)
+ val newIds = intArrayOf(10, 11, 12)
+ val expectedOldIds = IntArray.wrap(*oldIds).toConcatString()
+ val expectedNewIds = IntArray.wrap(*newIds).toConcatString()
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(EXTRA_APPWIDGET_OLD_IDS, oldIds)
+ putExtra(EXTRA_APPWIDGET_IDS, newIds)
+ putExtra(EXTRA_HOST_ID, APPWIDGET_HOST_ID)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.get(OLD_APP_WIDGET_IDS)).isEqualTo(expectedOldIds)
+ assertThat(launcherPrefs.get(APP_WIDGET_IDS)).isEqualTo(expectedNewIds)
+ }
+
+ @Test
+ fun `AppWidgetsRestoredReceiver does not set widget ids when Intent action is invalid`() {
+ // Given
+ val oldIds = intArrayOf(1, 2, 10)
+ val newIds = intArrayOf(10, 11, 12)
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_DELETED
+ putExtra(EXTRA_APPWIDGET_OLD_IDS, oldIds)
+ putExtra(EXTRA_APPWIDGET_IDS, newIds)
+ putExtra(EXTRA_HOST_ID, APPWIDGET_HOST_ID)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse()
+ }
+
+ @Test
+ fun `AppWidgetsRestoredReceiver does not set widget ids when Intent host id is not Launcher`() {
+ // Given
+ val oldIds = intArrayOf(1, 2, 10)
+ val newIds = intArrayOf(10, 11, 12)
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(EXTRA_APPWIDGET_OLD_IDS, oldIds)
+ putExtra(EXTRA_APPWIDGET_IDS, newIds)
+ putExtra(EXTRA_HOST_ID, 999999999)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse()
+ }
+
+ @Test
+ fun `AppWidgetsRestoredReceiver does not set ids when new and old ids differ in length`() {
+ // Given
+ val oldIds = intArrayOf(10)
+ val newIds = intArrayOf(10, 11, 12)
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(EXTRA_APPWIDGET_OLD_IDS, oldIds)
+ putExtra(EXTRA_APPWIDGET_IDS, newIds)
+ putExtra(EXTRA_HOST_ID, APPWIDGET_HOST_ID)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse()
+ }
+
+ @Test
+ fun `AppWidgetsRestoredReceiver does not set widget ids when old ids not set`() {
+ // Given
+ val newIds = intArrayOf(10, 11, 12)
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(EXTRA_APPWIDGET_IDS, newIds)
+ putExtra(EXTRA_HOST_ID, APPWIDGET_HOST_ID)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse()
+ }
+
+ @Test
+ fun `AppWidgetsRestoredReceiver does not set widget ids when new ids not set`() {
+ // Given
+ val oldIds = intArrayOf(10, 11, 12)
+ val intent =
+ Intent().apply {
+ component = null
+ `package` = TEST_PACKAGE
+ action = ACTION_APPWIDGET_HOST_RESTORED
+ putExtra(EXTRA_APPWIDGET_OLD_IDS, oldIds)
+ putExtra(EXTRA_HOST_ID, APPWIDGET_HOST_ID)
+ }
+
+ // When
+ receiverUnderTest.onReceive(DeviceHelpers.context, intent)
+
+ // Then
+ assertThat(launcherPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse()
+ }
+}
diff --git a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
index bcfb90b..46e66e4 100644
--- a/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
+++ b/tests/src/com/android/launcher3/DeleteDropTargetTest.kt
@@ -32,9 +32,9 @@
buttonDropTarget.setTextMultiLine(false)
// No space for text
- assertThat(buttonDropTarget.isTextClippedVertically(30)).isTrue()
+ assertThat(buttonDropTarget.isTextClippedVertically(1)).isTrue()
// A lot of space for text so the text should not be clipped
- assertThat(buttonDropTarget.isTextClippedVertically(100)).isFalse()
+ assertThat(buttonDropTarget.isTextClippedVertically(1000)).isFalse()
}
}
diff --git a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
index c22cf40..a421006 100644
--- a/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/FakeInvariantDeviceProfileTest.kt
@@ -27,9 +27,9 @@
import java.io.PrintWriter
import java.io.StringWriter
import org.junit.Before
-import org.mockito.ArgumentMatchers.any
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* This is an abstract class for DeviceProfile tests that don't need the real Context and mock an
@@ -41,12 +41,13 @@
protected var context: Context? = null
protected var inv: InvariantDeviceProfile? = null
- protected var info: Info = mock(Info::class.java)
+ protected val info: Info = mock()
protected var windowBounds: WindowBounds? = null
protected var isMultiWindowMode: Boolean = false
protected var transposeLayoutWithOrientation: Boolean = false
protected var useTwoPanels: Boolean = false
protected var isGestureMode: Boolean = true
+ protected var isTransientTaskbar: Boolean = true
@Before
fun setUp() {
@@ -68,7 +69,8 @@
useTwoPanels,
isGestureMode,
DEFAULT_PROVIDER,
- DEFAULT_DIMENSION_PROVIDER
+ DEFAULT_DIMENSION_PROVIDER,
+ isTransientTaskbar,
)
protected fun initializeVarsForPhone(
@@ -93,6 +95,7 @@
whenever(info.smallestSizeDp(any())).thenReturn(411f)
this.isGestureMode = isGestureMode
+ this.isTransientTaskbar = false
transposeLayoutWithOrientation = true
inv =
@@ -175,6 +178,7 @@
whenever(info.smallestSizeDp(any())).thenReturn(800f)
this.isGestureMode = isGestureMode
+ this.isTransientTaskbar = true
useTwoPanels = false
inv =
@@ -258,6 +262,7 @@
whenever(info.smallestSizeDp(any())).thenReturn(700f)
this.isGestureMode = isGestureMode
+ this.isTransientTaskbar = true
useTwoPanels = true
inv =
diff --git a/tests/src/com/android/launcher3/LauncherPrefsTest.kt b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
index d59e02a..88a430b 100644
--- a/tests/src/com/android/launcher3/LauncherPrefsTest.kt
+++ b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
@@ -33,7 +33,8 @@
private val TEST_BOOLEAN_ITEM = LauncherPrefs.nonRestorableItem("1", false)
private val TEST_STRING_ITEM = LauncherPrefs.nonRestorableItem("2", "( ͡❛ ͜ʖ ͡❛)")
private val TEST_INT_ITEM = LauncherPrefs.nonRestorableItem("3", -1)
-private val TEST_CONTEXTUAL_ITEM = ContextualItem("4", true, { true }, false, Boolean::class.java)
+private val TEST_CONTEXTUAL_ITEM =
+ ContextualItem("4", true, { true }, EncryptionType.ENCRYPTED, Boolean::class.java)
private const val TEST_DEFAULT_VALUE = "default"
private const val TEST_PREF_KEY = "test_pref_key"
@@ -51,13 +52,13 @@
@BeforeClass
@JvmStatic
fun setup() {
- isBootAwareStartupDataEnabled = true
+ moveStartupDataToDeviceProtectedStorageIsEnabled = true
}
@AfterClass
@JvmStatic
fun teardown() {
- isBootAwareStartupDataEnabled = false
+ moveStartupDataToDeviceProtectedStorageIsEnabled = false
}
}
@@ -203,7 +204,11 @@
@Test
fun put_bootAwareItem_updatesDeviceProtectedStorage() {
val bootAwareItem =
- LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
+ LauncherPrefs.backedUpItem(
+ TEST_PREF_KEY,
+ TEST_DEFAULT_VALUE,
+ EncryptionType.DEVICE_PROTECTED
+ )
val bootAwarePrefs: SharedPreferences =
context
@@ -220,7 +225,11 @@
@Test
fun put_bootAwareItem_updatesEncryptedStorage() {
val bootAwareItem =
- LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
+ LauncherPrefs.backedUpItem(
+ TEST_PREF_KEY,
+ TEST_DEFAULT_VALUE,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
@@ -235,7 +244,11 @@
@Test
fun remove_bootAwareItem_removesFromDeviceProtectedStorage() {
val bootAwareItem =
- LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
+ LauncherPrefs.backedUpItem(
+ TEST_PREF_KEY,
+ TEST_DEFAULT_VALUE,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
val bootAwarePrefs: SharedPreferences =
context
@@ -254,7 +267,11 @@
@Test
fun remove_bootAwareItem_removesFromEncryptedStorage() {
val bootAwareItem =
- LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
+ LauncherPrefs.backedUpItem(
+ TEST_PREF_KEY,
+ TEST_DEFAULT_VALUE,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
val encryptedPrefs: SharedPreferences =
context.getSharedPreferences(bootAwareItem.sharedPrefFile, Context.MODE_PRIVATE)
@@ -271,7 +288,11 @@
@Test
fun migrate_bootAwareItemsToDeviceProtectedStorage_worksAsIntended() {
val bootAwareItem =
- LauncherPrefs.backedUpItem(TEST_PREF_KEY, TEST_DEFAULT_VALUE, isBootAware = true)
+ LauncherPrefs.backedUpItem(
+ TEST_PREF_KEY,
+ TEST_DEFAULT_VALUE,
+ EncryptionType.MOVE_TO_DEVICE_PROTECTED
+ )
launcherPrefs.removeSync(bootAwareItem)
val bootAwarePrefs: SharedPreferences =
@@ -303,7 +324,7 @@
LauncherPrefs.backedUpItem(
TEST_PREF_KEY + "_",
TEST_DEFAULT_VALUE + "_",
- isBootAware = false
+ EncryptionType.ENCRYPTED
)
val bootAwarePrefs: SharedPreferences =
diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
new file mode 100644
index 0000000..80f73cb
--- /dev/null
+++ b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.view.KeyEvent;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TaplKeyboardFocusTest extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ @Test
+ public void testAllAppsFocusApp() {
+ final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ allApps.freeze();
+ try {
+ mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
+ executeOnLauncher(launcher -> assertNotNull("No focused child.",
+ launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ @Test
+ public void testAllAppsExitSearchAndFocusApp() {
+ final HomeAllApps allApps = mLauncher.goHome().switchToAllApps();
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ allApps.freeze();
+ try {
+ executeOnLauncher(launcher -> launcher.getAppsView().getSearchView().requestFocus());
+ waitForLauncherCondition("Search view does not have focus.",
+ launcher -> launcher.getAppsView().getSearchView().hasFocus());
+
+ mLauncher.pressAndHoldKeyCode(KeyEvent.KEYCODE_DPAD_DOWN, 0);
+ executeOnLauncher(launcher -> assertNotNull("No focused child.",
+ launcher.getAppsView().getActiveRecyclerView().getApps().getFocusedChild()));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java
new file mode 100644
index 0000000..39dbcb2
--- /dev/null
+++ b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.expectFail;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Intent;
+import android.platform.test.annotations.PlatinumTest;
+
+import androidx.test.filters.FlakyTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.tapl.AllApps;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test that we can open and close the all apps in multiple situations.
+ * The test runs in Out of process (Oop) and in process.
+ */
+public class TaplOpenCloseAllApps extends AbstractLauncherUiTest {
+
+ public static final String READ_DEVICE_CONFIG_PERMISSION =
+ "android.permission.READ_DEVICE_CONFIG";
+
+ /**
+ * Calls static method initialize
+ */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ /**
+ * Make sure we can go home after pressing the context menu on an Icon on the AllApps.
+ */
+ @Test
+ public void testPressHomeOnAllAppsContextMenu() {
+ final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon("TestActivity7").openMenu();
+ } finally {
+ allApps.unfreeze();
+ }
+ mLauncher.goHome();
+ }
+
+ /**
+ * Make sure we can open AllApps from the Workspace.
+ */
+ @Test
+ @PortraitLandscape
+ public void testWorkspaceSwitchToAllApps() {
+ assertNotNull("switchToAllApps() returned null",
+ mLauncher.getWorkspace().switchToAllApps());
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ }
+
+ /**
+ * Make sure we can go to Workspace from AllApps
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsSwitchToWorkspace() {
+ assertNotNull("switchToWorkspace() returned null",
+ mLauncher.getWorkspace().switchToAllApps()
+ .switchToWorkspace(/* swipeDown= */ true));
+ assertTrue("Launcher internal state is not Workspace",
+ isInState(() -> LauncherState.NORMAL));
+ }
+
+ /**
+ * Make sure the swipe up gesture can take us back to the workspace from AllApps
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ @PortraitLandscape
+ public void testAllAppsSwipeUpToWorkspace() {
+ assertNotNull("testAllAppsSwipeUpToWorkspace() returned null",
+ mLauncher.getWorkspace().switchToAllApps()
+ .switchToWorkspace(/* swipeDown= */ false));
+ assertTrue("Launcher internal state is not Workspace",
+ isInState(() -> LauncherState.NORMAL));
+ }
+
+ /**
+ * Make sure we can go to the Workspace from AllApps on tablets by tapping on the background.
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsDeadzoneForTablet() {
+ assumeTrue(mLauncher.isTablet());
+
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ true /* tapRight */);
+ mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
+ false /* tapRight */);
+ }
+
+ /**
+ * Make sure that AllApps closes when pressing the home button
+ */
+ @Test
+ @PortraitLandscape
+ public void testAllAppsFromHome() {
+ // Test opening all apps
+ assertNotNull("switchToAllApps() returned null",
+ mLauncher.getWorkspace().switchToAllApps());
+
+ runAllAppsTest(mLauncher.getAllApps());
+
+ // Testing pressHome.
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ assertNotNull("pressHome returned null", mLauncher.goHome());
+ assertTrue("Launcher internal state is not Home",
+ isInState(() -> LauncherState.NORMAL));
+ assertNotNull("getHome returned null", mLauncher.getWorkspace());
+ }
+
+ /**
+ * Makes sure the state of AllApps is correct.
+ */
+ public void runAllAppsTest(AllApps allApps) {
+ allApps.freeze();
+ try {
+ assertNotNull("allApps parameter is null", allApps);
+
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+
+ // Test flinging forward and backward.
+ executeOnLauncher(launcher -> assertEquals(
+ "All Apps started in already scrolled state", 0,
+ getAllAppsScroll(launcher)));
+
+ allApps.flingForward();
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ final Integer flingForwardY = getFromLauncher(
+ launcher -> getAllAppsScroll(launcher));
+ executeOnLauncher(
+ launcher -> assertTrue("flingForward() didn't scroll App Apps",
+ flingForwardY > 0));
+
+ allApps.flingBackward();
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ final Integer flingBackwardY = getFromLauncher(
+ launcher -> getAllAppsScroll(launcher));
+ executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
+ flingBackwardY < flingForwardY));
+
+ // Test scrolling down to YouTube.
+ assertNotNull("All apps: can't find YouTube", allApps.getAppIcon("YouTube"));
+ // Test scrolling up to Camera.
+ assertNotNull("All apps: can't find Camera", allApps.getAppIcon("Camera"));
+ // Test failing to find a non-existing app.
+ final AllApps allAppsFinal = allApps;
+ expectFail("All apps: could find a non-existing app",
+ () -> allAppsFinal.getAppIcon("NO APP"));
+
+ assertTrue(
+ "Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ /**
+ * Makes sure that when pressing back when AllApps is open we go back to the Home screen.
+ */
+ @FlakyTest(bugId = 256615483)
+ @Test
+ @PortraitLandscape
+ public void testPressBackFromAllAppsToHome() {
+ InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
+ READ_DEVICE_CONFIG_PERMISSION);
+ assumeFalse(FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get());
+ mLauncher.getWorkspace().switchToAllApps();
+ mLauncher.pressBack();
+ mLauncher.getWorkspace();
+ waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
+ startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ mLauncher.pressBack();
+ mLauncher.getWorkspace();
+ waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
+ }
+}
diff --git a/tests/src/com/android/launcher3/allapps/TaplTestsAllAppsIconsWorking.java b/tests/src/com/android/launcher3/allapps/TaplTestsAllAppsIconsWorking.java
new file mode 100644
index 0000000..fd4619e
--- /dev/null
+++ b/tests/src/com/android/launcher3/allapps/TaplTestsAllAppsIconsWorking.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.AppIcon;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * The test runs in Out of process (Oop) and in process.
+ * Makes sure the basic behaviors of Icons on AllApps are working.
+ */
+public class TaplTestsAllAppsIconsWorking extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ /**
+ * Makes sure we can launch an icon from All apps
+ */
+ @Test
+ @PortraitLandscape
+ public void testAppIconLaunchFromAllAppsFromHome() {
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ assertTrue("Launcher internal state is not All Apps",
+ isInState(() -> LauncherState.ALL_APPS));
+
+ allApps.freeze();
+ try {
+ final AppIcon app = allApps.getAppIcon("TestActivity7");
+ assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName()));
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the "
+ + "top one",
+ isInLaunchedApp(launcher)));
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
new file mode 100644
index 0000000..0f5d85b
--- /dev/null
+++ b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.appiconmenu;
+
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.PlatinumTest;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.popup.ArrowPopup;
+import com.android.launcher3.tapl.AllApps;
+import com.android.launcher3.tapl.AppIconMenu;
+import com.android.launcher3.tapl.AppIconMenuItem;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Tests the AppIconMenu (the menu that appears when you long press an app icon) and also make sure
+ * we can launch a shortcut from it.
+ */
+public class TaplAppIconMenuTest extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ private boolean isOptionsPopupVisible(Launcher launcher) {
+ final ArrowPopup<?> popup = launcher.getOptionsPopup();
+ return popup != null && popup.isShown();
+ }
+
+ /**
+ * Open All apps then open the AppIconMenu then launch a shortcut from the menu and make sure it
+ * launches.
+ */
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testLaunchMenuItem() {
+ final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ final AppIconMenu menu = allApps.getAppIcon(TEST_APP_NAME).openDeepShortcutMenu();
+
+ executeOnLauncher(
+ launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
+ isOptionsPopupVisible(launcher)));
+
+ final AppIconMenuItem menuItem = menu.getMenuItem(1);
+ assertEquals("Wrong menu item", "Shortcut 2", menuItem.getText());
+ menuItem.launch(getAppPackageName());
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ /**
+ * Drag icon from AllApps to the workspace and then open the AppIconMenu and launch a shortcut
+ * from it.
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testLaunchHomeScreenMenuItem() {
+ // Drag the test app icon to home screen and open short cut menu from the icon
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false);
+ final AppIconMenu menu = mLauncher.getWorkspace().getWorkspaceAppIcon(
+ TEST_APP_NAME).openDeepShortcutMenu();
+
+ executeOnLauncher(
+ launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
+ isOptionsPopupVisible(launcher)));
+
+ final AppIconMenuItem menuItem = menu.getMenuItem(1);
+ assertEquals("Wrong menu item", "Shortcut 2", menuItem.getText());
+ menuItem.launch(getAppPackageName());
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
index bf7a21c..fb364ad 100644
--- a/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
+++ b/tests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
@@ -29,13 +29,13 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.ModelDbController;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.util.ContentWriter;
+import com.android.launcher3.util.ModelTestExtensions;
import java.util.ArrayList;
import java.util.function.Supplier;
@@ -60,8 +60,7 @@
public void commit() {
LauncherModel model = LauncherAppState.getInstance(mContext).getModel();
// Load the model once so that there is no pending migration:
- loadModelSync(model);
-
+ ModelTestExtensions.INSTANCE.loadModelSync(model);
runOnExecutorSync(MODEL_EXECUTOR, () -> {
ModelDbController controller = model.getModelDbController();
// Migrate any previous data so that the DB state is correct
@@ -105,16 +104,7 @@
// Reload model
runOnExecutorSync(MAIN_EXECUTOR, model::forceReload);
- loadModelSync(model);
- }
-
- private void loadModelSync(LauncherModel model) {
- Callbacks mockCb = new Callbacks() { };
- runOnExecutorSync(MAIN_EXECUTOR, () -> model.addCallbacksAndLoad(mockCb));
- runOnExecutorSync(MODEL_EXECUTOR, () -> { });
-
- runOnExecutorSync(MAIN_EXECUTOR, () -> { });
- runOnExecutorSync(MAIN_EXECUTOR, () -> model.removeCallbacks(mockCb));
+ ModelTestExtensions.INSTANCE.loadModelSync(model);
}
/**
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 00d7ce6..3d388d60 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.celllayout;
+import static android.platform.uiautomator_helpers.DeviceHelpers.getContext;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -28,13 +30,16 @@
import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.MultipageCellLayout;
import com.android.launcher3.tapl.Widget;
import com.android.launcher3.tapl.WidgetResizeFrame;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.launcher3.util.ModelTestExtensions;
import com.android.launcher3.util.rule.ShellCommandRule;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
@@ -68,6 +73,13 @@
TaplTestsLauncher3.initialize(this);
}
+ @After
+ public void tearDown() {
+ ModelTestExtensions.INSTANCE.clearModelDb(
+ LauncherAppState.getInstance(getContext()).getModel()
+ );
+ }
+
/**
* Validate if the given board represent the current CellLayout
**/
diff --git a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
index f34a29e..c5d5de8 100644
--- a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
+++ b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
@@ -27,7 +27,7 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.util.rule.ViewCaptureRule;
import org.junit.After;
import org.junit.Test;
@@ -74,7 +74,6 @@
}
@Test
- @ScreenRecord // b/202985412
public void testPromiseIcon_addedFromEligibleSession() throws Throwable {
final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
final ItemOperator findPromiseApp = (info, view) ->
@@ -97,7 +96,7 @@
}
@Test
- @ScreenRecord // b/202985412
+ @ViewCaptureRule.MayProduceNoFrames
public void testPromiseIcon_notAddedFromIneligibleSession() throws Throwable {
final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
final ItemOperator findPromiseApp = (info, view) ->
diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
new file mode 100644
index 0000000..7ec7826
--- /dev/null
+++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.dragging;
+
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Point;
+import android.os.SystemClock;
+import android.platform.test.annotations.PlatinumTest;
+import android.util.Log;
+
+import com.android.launcher3.tapl.Folder;
+import com.android.launcher3.tapl.FolderIcon;
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.tapl.HomeAppIconMenuItem;
+import com.android.launcher3.tapl.Workspace;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.TestUtil;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Tests multiple facets of the drag interaction in the Launcher:
+ * * Can create a folder by dragging items.
+ * * Can create a shortcut by dragging it to Workspace.
+ * * Can create shortcuts in multiple spaces in the Workspace.
+ * * Can cancel a drag icon to workspace by dragging outside of the Workspace.
+ * * Can drag an icon from AllApps into the workspace
+ * * Can drag an icon on the Workspace to other positions of the Workspace.
+ */
+public class TaplDragTest extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ /**
+ * Adds two icons to the Workspace and combines them into a folder, then makes sure the icons
+ * are no longer in the Workspace then adds a third one to test adding an icon to an existing
+ * folder instead of creating one and drags it to the folder.
+ */
+ @Test
+ @PortraitLandscape
+ @ScreenRecord
+ @Ignore // b/233075289
+ @PlatinumTest(focusArea = "launcher")
+ public void testDragToFolder() {
+ // TODO: add the use case to drag an icon to an existing folder. Currently it either fails
+ // on tablets or phones due to difference in resolution.
+ final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1);
+ final HomeAppIcon gmailIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
+
+ FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
+ Folder folder = folderIcon.open();
+ folder.getAppIcon(STORE_APP_NAME);
+ folder.getAppIcon(GMAIL_APP_NAME);
+ Workspace workspace = folder.close();
+
+ workspace.verifyWorkspaceAppIconIsGone(STORE_APP_NAME + " should be moved to a folder.",
+ STORE_APP_NAME);
+ workspace.verifyWorkspaceAppIconIsGone(GMAIL_APP_NAME + " should be moved to a folder.",
+ GMAIL_APP_NAME);
+
+ final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
+ folderIcon = mapIcon.dragToIcon(folderIcon);
+ folder = folderIcon.open();
+ folder.getAppIcon(MAPS_APP_NAME);
+ workspace = folder.close();
+
+ workspace.verifyWorkspaceAppIconIsGone(MAPS_APP_NAME + " should be moved to a folder.",
+ MAPS_APP_NAME);
+ }
+
+
+ /** Drags a shortcut from a long press menu into the workspace.
+ * 1. Open all apps and wait for load complete.
+ * 2. Find the app and long press it to show shortcuts.
+ * 3. Press icon center until shortcuts appear
+ * 4. Drags shortcut to any free space in the Workspace.
+ */
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testDragShortcut() {
+
+ final HomeAllApps allApps = mLauncher
+ .getWorkspace()
+ .switchToAllApps();
+ allApps.freeze();
+ try {
+ final HomeAppIconMenuItem menuItem = allApps
+ .getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem(0);
+ final String actualShortcutName = menuItem.getText();
+ final String expectedShortcutName = "Shortcut 1";
+
+ assertEquals(expectedShortcutName, actualShortcutName);
+ menuItem.dragToWorkspace(false, false);
+ mLauncher.getWorkspace().getWorkspaceAppIcon(expectedShortcutName)
+ .launch(getAppPackageName());
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+
+ /**
+ * Similar to testDragShortcut but it adds shortcuts to multiple positions of the Workspace
+ * namely the corners and the center.
+ */
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testDragShortcutToMultipleWorkspaceCells() {
+ Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher);
+
+ for (Point target : targets) {
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(TEST_APP_NAME)
+ .openDeepShortcutMenu()
+ .getMenuItem(0)
+ .dragToWorkspace(target.x, target.y);
+ } finally {
+ allApps.unfreeze();
+ }
+ }
+ }
+
+ /**
+ * Drags an icon to the workspace but instead of submitting it, it gets dragged outside of the
+ * Workspace to cancel it.
+ */
+
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testDragAndCancelAppIcon() {
+ final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
+ Point positionBeforeDrag =
+ mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
+ assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag);
+
+ mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon);
+
+ Point positionAfterDrag =
+ mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
+ assertNotNull("App not found in Workspace after dragging.", positionAfterDrag);
+ assertEquals("App not returned to same position in Workspace after drag & cancel",
+ positionBeforeDrag, positionAfterDrag);
+ }
+
+ /**
+ * Drags app icon from AllApps into the Workspace.
+ * 1. Open all apps and wait for load complete.
+ * 2. Drag icon to homescreen.
+ * 3. Verify that the icon works on homescreen.
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ @PortraitLandscape
+ public void testDragAppIcon() {
+
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(false, false);
+ mLauncher.getWorkspace().getWorkspaceAppIcon(TEST_APP_NAME).launch(getAppPackageName());
+ } finally {
+ allApps.unfreeze();
+ }
+ executeOnLauncher(launcher -> assertTrue(
+ "Launcher activity is the top activity; expecting another activity to be the top "
+ + "one",
+ isInLaunchedApp(launcher)));
+ }
+
+ /**
+ * Similar start to testDragAppIcon but after dragging the icon to the workspace, it drags the
+ * icon inside of the workspace to different positions.
+ * @throws Exception
+ */
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testDragAppIconToMultipleWorkspaceCells() throws Exception {
+ long startTime, endTime, elapsedTime;
+ Point[] targets = TestUtil.getCornersAndCenterPositions(mLauncher);
+
+ for (Point target : targets) {
+ startTime = SystemClock.uptimeMillis();
+ final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ allApps.freeze();
+ try {
+ allApps.getAppIcon(TEST_APP_NAME).dragToWorkspace(target.x, target.y);
+ } finally {
+ allApps.unfreeze();
+ }
+ // Reset the workspace for the next shortcut creation.
+ initialize(this, true);
+ endTime = SystemClock.uptimeMillis();
+ elapsedTime = endTime - startTime;
+ Log.d("testDragAppIconToWorkspaceCellTime",
+ "Milliseconds taken to drag app icon to workspace cell: " + elapsedTime);
+ }
+
+ // test to move a shortcut to other cell.
+ final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(TEST_APP_NAME);
+ for (Point target : targets) {
+ startTime = SystemClock.uptimeMillis();
+ launcherTestAppIcon.dragToWorkspace(target.x, target.y);
+ endTime = SystemClock.uptimeMillis();
+ elapsedTime = endTime - startTime;
+ Log.d("testDragAppIconToWorkspaceCellTime",
+ "Milliseconds taken to move shortcut to other cell: " + elapsedTime);
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java b/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java
new file mode 100644
index 0000000..7027e85
--- /dev/null
+++ b/tests/src/com/android/launcher3/dragging/TaplUninstallRemove.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.dragging;
+
+import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.TestConstants.AppNames.DUMMY_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.Point;
+import android.platform.test.annotations.PlatinumTest;
+import android.util.Log;
+
+import com.android.launcher3.tapl.HomeAllApps;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.tapl.Workspace;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.TestUtil;
+import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.ScreenRecordRule;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Test runs in Out of process (Oop) and In process (Ipc)
+ * Test the behaviour of uninstalling and removing apps both from AllApps, Workspace and Hotseat.
+ */
+public class TaplUninstallRemove extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ /**
+ * Deletes app both built-in and user-installed from the Workspace and makes sure it's no longer
+ * in the Workspace.
+ */
+ @Test
+ @PortraitLandscape
+ public void testDeleteFromWorkspace() {
+ for (String appName : new String[]{GMAIL_APP_NAME, STORE_APP_NAME, TEST_APP_NAME}) {
+ final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(appName);
+ Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
+ workspace.verifyWorkspaceAppIconIsGone(
+ appName + " app was found after being deleted from workspace",
+ appName);
+ }
+ }
+
+ private void verifyAppUninstalledFromAllApps(Workspace workspace, String appName) {
+ final HomeAllApps allApps = workspace.switchToAllApps();
+ Wait.atMost(appName + " app was found on all apps after being uninstalled",
+ () -> allApps.tryGetAppIcon(appName) == null,
+ DEFAULT_UI_TIMEOUT, mLauncher);
+ }
+
+ private void installDummyAppAndWaitForUIUpdate() throws IOException {
+ TestUtil.installDummyApp();
+ waitForLauncherUIUpdate();
+ }
+
+ private void waitForLauncherUIUpdate() {
+ // Wait for model thread completion as it may be processing
+ // the install event from the SystemService
+ mLauncher.waitForModelQueueCleared();
+ // Wait for Launcher UI thread completion, as it may be processing updating the UI in
+ // response to the model update. Not that `waitForLauncherInitialized` is just a proxy
+ // method, we can use any method which touches Launcher UI thread,
+ mLauncher.waitForLauncherInitialized();
+ }
+
+ /**
+ * Makes sure you can uninstall an app from the Workspace.
+ * @throws Exception
+ */
+ @Test
+ @PortraitLandscape
+ // TODO(b/293944634): Remove Screenrecord after flaky debug, and add
+ // @PlatinumTest(focusArea = "launcher") back
+ @ScreenRecordRule.ScreenRecord
+ public void testUninstallFromWorkspace() throws Exception {
+ installDummyAppAndWaitForUIUpdate();
+ try {
+ verifyAppUninstalledFromAllApps(
+ createShortcutInCenterIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
+ } finally {
+ TestUtil.uninstallDummyApp();
+ }
+ }
+
+ /**
+ * Makes sure you can uninstall an app from AllApps.
+ * @throws Exception
+ */
+ @Test
+ @PortraitLandscape
+ @PlatinumTest(focusArea = "launcher")
+ public void testUninstallFromAllApps() throws Exception {
+ installDummyAppAndWaitForUIUpdate();
+ try {
+ Workspace workspace = mLauncher.getWorkspace();
+ final HomeAllApps allApps = workspace.switchToAllApps();
+ workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
+ verifyAppUninstalledFromAllApps(workspace, DUMMY_APP_NAME);
+ } finally {
+ TestUtil.uninstallDummyApp();
+ }
+ }
+
+ /**
+ * Adds three icons to the workspace and removes one of them by dragging to uninstall.
+ */
+ @Test
+ @PlatinumTest(focusArea = "launcher")
+ public void uninstallWorkspaceIcon() throws IOException {
+ Point[] gridPositions = TestUtil.getCornersAndCenterPositions(mLauncher);
+ StringBuilder sb = new StringBuilder();
+ for (Point p : gridPositions) {
+ sb.append(p).append(", ");
+ }
+ Log.d(ICON_MISSING, "allGridPositions: " + sb);
+ createShortcutIfNotExist(STORE_APP_NAME, gridPositions[0]);
+ createShortcutIfNotExist(MAPS_APP_NAME, gridPositions[1]);
+ installDummyAppAndWaitForUIUpdate();
+ try {
+ createShortcutIfNotExist(DUMMY_APP_NAME, gridPositions[2]);
+ Map<String, Point> initialPositions =
+ mLauncher.getWorkspace().getWorkspaceIconsPositions();
+ assertThat(initialPositions.keySet())
+ .containsAtLeast(DUMMY_APP_NAME, MAPS_APP_NAME, STORE_APP_NAME);
+
+ mLauncher.getWorkspace().getWorkspaceAppIcon(DUMMY_APP_NAME).uninstall();
+ mLauncher.getWorkspace().verifyWorkspaceAppIconIsGone(
+ DUMMY_APP_NAME + " was expected to disappear after uninstall.", DUMMY_APP_NAME);
+
+ Map<String, Point> finalPositions =
+ mLauncher.getWorkspace().getWorkspaceIconsPositions();
+ assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
+ } finally {
+ TestUtil.uninstallDummyApp();
+ }
+ }
+
+ /**
+ * Drag icon from the Hotseat to the delete drop target
+ */
+ @Test
+ @PortraitLandscape
+ public void testAddDeleteShortcutOnHotseat() {
+ mLauncher.getWorkspace()
+ .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
+ .switchToAllApps()
+ .getAppIcon(TEST_APP_NAME)
+ .dragToHotseat(0);
+ mLauncher.getWorkspace().deleteAppIcon(
+ mLauncher.getWorkspace().getHotseatAppIcon(TEST_APP_NAME));
+ }
+}
diff --git a/tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt b/tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
index fffa6d7..a29218c 100644
--- a/tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
+++ b/tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
@@ -357,6 +357,7 @@
assertThat(underTest.startTimeByEvent.size()).isEqualTo(4)
assertThat(underTest.endTimeByEvent.size()).isEqualTo(4)
assertThat(underTest.cardinality).isEqualTo(235)
+ assertThat(underTest.isTornDown).isFalse()
underTest.reset()
@@ -364,5 +365,26 @@
assertThat(underTest.endTimeByEvent.isEmpty()).isTrue()
assertThat(underTest.cardinality).isEqualTo(StartupLatencyLogger.UNSET_INT)
assertThat(underTest.workspaceLoadStartTime).isEqualTo(StartupLatencyLogger.UNSET_LONG)
+ assertThat(underTest.isTornDown).isTrue()
+ }
+
+ @Test
+ @UiThreadTest
+ fun tornDown_rejectLogs() {
+ underTest.reset()
+
+ underTest
+ .logStart(
+ StatsLogManager.LauncherLatencyEvent.LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION,
+ 100
+ )
+ .logEnd(
+ StatsLogManager.LauncherLatencyEvent.LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION,
+ 200
+ )
+ .logCardinality(123)
+ assertThat(underTest.startTimeByEvent.isEmpty()).isTrue()
+ assertThat(underTest.endTimeByEvent.isEmpty()).isTrue()
+ assertThat(underTest.cardinality).isEqualTo(StartupLatencyLogger.UNSET_INT)
}
}
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
index 1155227..78c61d5 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
@@ -24,20 +24,19 @@
import com.android.launcher3.util.Executors
import com.android.launcher3.util.IntArray
import com.android.launcher3.util.TestUtil.runOnExecutorSync
-import com.android.launcher3.util.any
-import com.android.launcher3.util.eq
-import com.android.launcher3.util.same
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.same
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
/** Tests for [AddWorkspaceItemsTask] */
@SmallTest
@@ -46,12 +45,11 @@
private lateinit var mDataModelCallbacks: MyCallbacks
- @Mock private lateinit var mWorkspaceItemSpaceFinder: WorkspaceItemSpaceFinder
+ private val mWorkspaceItemSpaceFinder: WorkspaceItemSpaceFinder = mock()
@Before
override fun setup() {
super.setup()
- MockitoAnnotations.initMocks(this)
mDataModelCallbacks = MyCallbacks()
Executors.MAIN_EXECUTOR.submit { mModelHelper.model.addCallbacks(mDataModelCallbacks) }
.get()
diff --git a/tests/src/com/android/launcher3/model/DatabaseHelperTest.kt b/tests/src/com/android/launcher3/model/DatabaseHelperTest.kt
new file mode 100644
index 0000000..c9ea421
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/DatabaseHelperTest.kt
@@ -0,0 +1,79 @@
+package com.android.launcher3.model
+
+import android.database.sqlite.SQLiteDatabase
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME
+import com.android.launcher3.LauncherSettings.Favorites.TMP_TABLE
+import com.android.launcher3.LauncherSettings.Favorites.addTableToDb
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.provider.LauncherDbUtils
+import java.util.function.ToLongFunction
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val INSERTION_SQL = "databases/v30_workspace_items.sql"
+
+private const val ICON_PACKAGE = "iconPackage"
+private const val ICON_RESOURCE = "iconResource"
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DatabaseHelperTest {
+
+ /**
+ * b/304687723 occurred when a return was accidentally added to a case statement in
+ * DatabaseHelper.onUpgrade, which stopped the final data migration from successfully occurring.
+ * This test loads an in-memory db from a text file containing SQL statements, and then performs
+ * the migration on the db, and verifies that the correct columns have been deleted.
+ */
+ @Test
+ fun onUpgrade_to_version_32_from_30() {
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ val userSerialProvider =
+ ToLongFunction<UserHandle> {
+ UserCache.INSTANCE.get(context).getSerialNumberForUser(it)
+ }
+ val dbHelper = DatabaseHelper(context, null, userSerialProvider) {}
+ val db = FactitiousDbController(context, INSERTION_SQL).inMemoryDb
+
+ dbHelper.onUpgrade(db, 30, 32)
+
+ assertFalse(hasFavoritesColumn(db, ICON_PACKAGE))
+ assertFalse(hasFavoritesColumn(db, ICON_RESOURCE))
+ }
+
+ /**
+ * b/304687723 causes a crash due to copying a table with 21 columns to a table with 19 columns.
+ * This test loads an in-memory db from a text file containing SQL statements, and then copies
+ * data from the created table into a temporary one, and verifies that no exception is thrown.
+ */
+ @Test
+ fun after_migrating_from_db_v30_to_v32_copy_table() {
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ val db = FactitiousDbController(context, INSERTION_SQL).inMemoryDb // v30 - 21 columns
+
+ addTableToDb(db, 1, true, TMP_TABLE)
+ LauncherDbUtils.copyTable(db, TABLE_NAME, db, TMP_TABLE, context)
+
+ val c1 = db.query(TABLE_NAME, null, null, null, null, null, null)
+ val c2 = db.query(TMP_TABLE, null, null, null, null, null, null)
+
+ assertEquals(21, c1.columnCount)
+ assertEquals(19, c2.columnCount)
+ assertEquals(c1.count, c2.count)
+
+ c1.close()
+ c2.close()
+ }
+
+ private fun hasFavoritesColumn(db: SQLiteDatabase, columnName: String): Boolean {
+ db.query(TABLE_NAME, null, null, null, null, null, null).use { c ->
+ return c.getColumnIndex(columnName) >= 0
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/model/FactitiousDbController.kt b/tests/src/com/android/launcher3/model/FactitiousDbController.kt
new file mode 100644
index 0000000..711e1d2
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/FactitiousDbController.kt
@@ -0,0 +1,60 @@
+package com.android.launcher3.model
+
+import android.content.Context
+import android.database.Cursor
+import android.database.sqlite.SQLiteDatabase
+import androidx.test.platform.app.InstrumentationRegistry
+import java.io.BufferedReader
+import java.io.InputStreamReader
+
+private val All_COLUMNS =
+ arrayOf(
+ "_id",
+ "title",
+ "intent",
+ "container",
+ "screen",
+ "cellX",
+ "cellY",
+ "spanX",
+ "spanY",
+ "itemType",
+ "appWidgetId",
+ "icon",
+ "appWidgetProvider",
+ "modified",
+ "restored",
+ "profileId",
+ "rank",
+ "options",
+ "appWidgetSource"
+ )
+
+class FactitiousDbController(context: Context, insertFile: String) : ModelDbController(context) {
+
+ val inMemoryDb: SQLiteDatabase by lazy {
+ SQLiteDatabase.createInMemory(SQLiteDatabase.OpenParams.Builder().build()).also { db ->
+ BufferedReader(
+ InputStreamReader(
+ InstrumentationRegistry.getInstrumentation().context.assets.open(insertFile)
+ )
+ )
+ .lines()
+ .forEach { sqlStatement -> db.execSQL(sqlStatement) }
+ }
+ }
+
+ override fun query(
+ table: String,
+ projection: Array<out String>?,
+ selection: String?,
+ selectionArgs: Array<out String>?,
+ sortOrder: String?
+ ): Cursor {
+ return inMemoryDb.query(table, All_COLUMNS, selection, selectionArgs, null, null, sortOrder)
+ }
+
+ override fun loadDefaultFavoritesIfNecessary() {
+ // No-Op
+ }
+}
diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
index 544ed6b..389ec5c 100644
--- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -175,7 +175,7 @@
// Item outside screen bounds are not placed
assertFalse(mLoaderCursor.checkItemPlacement(
- newItemInfo(4, 4, 1, 1, CONTAINER_DESKTOP, 1)));
+ newItemInfo(4, 4, 1, 1, CONTAINER_DESKTOP, 1), true));
}
@Test
@@ -186,22 +186,22 @@
// Overlapping mItems are not placed
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1)));
+ newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1), true));
assertFalse(mLoaderCursor.checkItemPlacement(
- newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1)));
+ newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1), true));
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2)));
+ newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2), true));
assertFalse(mLoaderCursor.checkItemPlacement(
- newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2)));
+ newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2), true));
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(1, 1, 1, 1, CONTAINER_DESKTOP, 1)));
+ newItemInfo(1, 1, 1, 1, CONTAINER_DESKTOP, 1), true));
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(2, 2, 2, 2, CONTAINER_DESKTOP, 1)));
+ newItemInfo(2, 2, 2, 2, CONTAINER_DESKTOP, 1), true));
assertFalse(mLoaderCursor.checkItemPlacement(
- newItemInfo(3, 2, 1, 2, CONTAINER_DESKTOP, 1)));
+ newItemInfo(3, 2, 1, 2, CONTAINER_DESKTOP, 1), true));
}
@Test
@@ -212,12 +212,12 @@
// Hotseat mItems are only placed based on screenId
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 1)));
+ newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 1), true));
assertTrue(mLoaderCursor.checkItemPlacement(
- newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 2)));
+ newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 2), true));
assertFalse(mLoaderCursor.checkItemPlacement(
- newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 3)));
+ newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 3), true));
}
private ItemInfo newItemInfo(int cellX, int cellY, int spanX, int spanY,
diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
new file mode 100644
index 0000000..036f2d8
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
@@ -0,0 +1,107 @@
+package com.android.launcher3.model
+
+import android.appwidget.AppWidgetManager
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.InvariantDeviceProfile
+import com.android.launcher3.LauncherAppState
+import com.android.launcher3.LauncherModel
+import com.android.launcher3.LauncherModel.LoaderTransaction
+import com.android.launcher3.icons.IconCache
+import com.android.launcher3.icons.cache.CachingLogic
+import com.android.launcher3.icons.cache.IconCacheUpdateHandler
+import com.android.launcher3.util.Executors.MODEL_EXECUTOR
+import com.android.launcher3.util.LooperIdleLock
+import com.google.common.truth.Truth
+import java.util.concurrent.CountDownLatch
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+private const val INSERTION_STATEMENT_FILE = "databases/workspace_items.sql"
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class LoaderTaskTest {
+ @Mock private lateinit var app: LauncherAppState
+ @Mock private lateinit var bgAllAppsList: AllAppsList
+ @Mock private lateinit var modelDelegate: ModelDelegate
+ @Mock private lateinit var launcherBinder: LauncherBinder
+ @Mock private lateinit var launcherModel: LauncherModel
+ @Mock private lateinit var transaction: LoaderTransaction
+ @Mock private lateinit var iconCache: IconCache
+ @Mock private lateinit var idleLock: LooperIdleLock
+ @Mock private lateinit var iconCacheUpdateHandler: IconCacheUpdateHandler
+ @Mock private lateinit var appWidgetManager: AppWidgetManager
+
+ @Before
+ fun setup() {
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ val idp =
+ InvariantDeviceProfile.INSTANCE[context].apply {
+ numRows = 5
+ numColumns = 6
+ numDatabaseHotseatIcons = 5
+ }
+
+ MockitoAnnotations.initMocks(this)
+ `when`(app.context).thenReturn(context)
+ `when`(app.model).thenReturn(launcherModel)
+ `when`(launcherModel.beginLoader(any(LoaderTask::class.java))).thenReturn(transaction)
+ `when`(app.iconCache).thenReturn(iconCache)
+ `when`(launcherModel.modelDbController)
+ .thenReturn(FactitiousDbController(context, INSERTION_STATEMENT_FILE))
+ `when`(app.invariantDeviceProfile).thenReturn(idp)
+ `when`(launcherBinder.newIdleLock(any(LoaderTask::class.java))).thenReturn(idleLock)
+ `when`(idleLock.awaitLocked(1000)).thenReturn(false)
+ `when`(iconCache.updateHandler).thenReturn(iconCacheUpdateHandler)
+ `when`(appWidgetManager.getInstalledProvidersForProfile(any(UserHandle::class.java)))
+ .thenReturn(emptyList())
+ }
+
+ @Test
+ fun loadsDataProperly() =
+ with(BgDataModel()) {
+ LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder)
+ .runSyncOnBackgroundThread()
+ Truth.assertThat(workspaceItems.size).isAtLeast(25)
+ Truth.assertThat(appWidgets.size).isAtLeast(7)
+ Truth.assertThat(folders.size()).isAtLeast(8)
+ Truth.assertThat(itemsIdMap.size()).isAtLeast(40)
+ }
+
+ @Test
+ fun bindsLoadedDataCorrectly() {
+ LoaderTask(app, bgAllAppsList, BgDataModel(), modelDelegate, launcherBinder)
+ .runSyncOnBackgroundThread()
+
+ verify(launcherBinder).bindWorkspace(true, false)
+ verify(modelDelegate).workspaceLoadComplete()
+ verify(modelDelegate).loadAndBindAllAppsItems(any(), any(), any())
+ verify(launcherBinder).bindAllApps()
+ verify(iconCacheUpdateHandler, times(4)).updateIcons(any(), any<CachingLogic<Any>>(), any())
+ verify(launcherBinder).bindDeepShortcuts()
+ verify(launcherBinder).bindWidgets()
+ verify(modelDelegate).loadAndBindOtherItems(any())
+ verify(iconCacheUpdateHandler).finish()
+ verify(modelDelegate).modelLoadComplete()
+ verify(transaction).commit()
+ }
+}
+
+private fun LoaderTask.runSyncOnBackgroundThread() {
+ val latch = CountDownLatch(1)
+ MODEL_EXECUTOR.execute {
+ run()
+ latch.countDown()
+ }
+ latch.await()
+}
diff --git a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
index 270672f..9b67310 100644
--- a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
+++ b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt
@@ -15,14 +15,14 @@
*/
package com.android.launcher3.nonquickstep
+import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
import com.android.launcher3.AbstractDeviceProfileTest
import com.android.launcher3.DeviceProfile
import com.android.launcher3.InvariantDeviceProfile
import com.google.common.truth.Truth.assertThat
-import java.io.PrintWriter
-import java.io.StringWriter
import org.junit.Test
import org.junit.runner.RunWith
@@ -30,142 +30,14 @@
@SmallTest
@RunWith(AndroidJUnit4::class)
class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
-
+ private val testContext: Context = InstrumentationRegistry.getInstrumentation().context
+ private val folderName: String = "DeviceProfileDumpTest"
@Test
fun phonePortrait3Button() {
initializeVarsForPhone(deviceSpecs["phone"]!!, isGestureMode = false)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1080.0px (411.42856dp)\n" +
- "\theightPx: 2400.0px (914.2857dp)\n" +
- "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
- "\tavailableHeightPx: 2156.0px (821.3333dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 118.0px (44.95238dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 126.0px (48.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 159.0px (60.57143dp)\n" +
- "\tcellHeightPx: 229.0px (87.2381dp)\n" +
- "\tgetCellSize().x: 207.0px (78.85714dp)\n" +
- "\tgetCellSize().y: 379.0px (144.38095dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 38.0px (14.476191dp)\n" +
- "\ticonDrawablePaddingPx: 12.0px (4.571429dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 195.0px (74.28571dp)\n" +
- "\tfolderCellHeightPx: 230.0px (87.61905dp)\n" +
- "\tfolderChildIconSizePx: 147.0px (56.0dp)\n" +
- "\tfolderChildTextSizePx: 38.0px (14.476191dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 294.0px (112.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 147.0px (56.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 128.0px (48.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 21.0px (8.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 21.0px (8.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.bottom: 203.0px (77.333336dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 752.0px (286.4762dp)\n" +
- "\tunscaled extraSpace: 752.0px (286.4762dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 126.0px (48.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1906.0px (726.0952dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.77572966px (0.29551607dp)\n" +
- "\tgetCellLayoutHeight(): 1953.0px (744.0dp)\n" +
- "\tgetCellLayoutWidth(): 1080.0px (411.42856dp)\n"
- )
+ assertDump(dp, "phonePortrait3Button")
}
@Test
@@ -173,136 +45,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1080.0px (411.42856dp)\n" +
- "\theightPx: 2400.0px (914.2857dp)\n" +
- "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
- "\tavailableHeightPx: 2219.0px (845.3333dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 118.0px (44.95238dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 63.0px (24.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 159.0px (60.57143dp)\n" +
- "\tcellHeightPx: 229.0px (87.2381dp)\n" +
- "\tgetCellSize().x: 207.0px (78.85714dp)\n" +
- "\tgetCellSize().y: 383.0px (145.90475dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
- "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 38.0px (14.476191dp)\n" +
- "\ticonDrawablePaddingPx: 12.0px (4.571429dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 195.0px (74.28571dp)\n" +
- "\tfolderCellHeightPx: 230.0px (87.61905dp)\n" +
- "\tfolderChildIconSizePx: 147.0px (56.0dp)\n" +
- "\tfolderChildTextSizePx: 38.0px (14.476191dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 273.0px (104.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 107.0px (40.761906dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 21.0px (8.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 21.0px (8.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.bottom: 245.0px (93.333336dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 773.0px (294.4762dp)\n" +
- "\tunscaled extraSpace: 773.0px (294.4762dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 63.0px (24.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1927.0px (734.0952dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7781155px (0.29642496dp)\n" +
- "\tgetCellLayoutHeight(): 1974.0px (752.0dp)\n" +
- "\tgetCellLayoutWidth(): 1080.0px (411.42856dp)\n"
- )
+ assertDump(dp, "phonePortrait")
}
@Test
@@ -310,136 +53,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true, isGestureMode = false)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2400.0px (914.2857dp)\n" +
- "\theightPx: 1080.0px (411.42856dp)\n" +
- "\tavailableWidthPx: 2156.0px (821.3333dp)\n" +
- "\tavailableHeightPx: 1006.0px (383.2381dp)\n" +
- "\tmInsets.left: 118.0px (44.95238dp)\n" +
- "\tmInsets.top: 74.0px (28.190475dp)\n" +
- "\tmInsets.right: 126.0px (48.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 152.0px (57.904762dp)\n" +
- "\tcellHeightPx: 166.0px (63.238094dp)\n" +
- "\tgetCellSize().x: 368.0px (140.19048dp)\n" +
- "\tgetCellSize().y: 193.0px (73.52381dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 173.0px (65.90476dp)\n" +
- "\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
- "\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 4.0px (1.5238096dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 56.0px (21.333334dp)\n" +
- "\tfolderFooterHeight: 131.0px (49.904762dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 321.0px (122.28571dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 252.0px (96.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 64.0px (24.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 49.0px (18.666666dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 189.0px (72.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 199.0px (75.809525dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 136.0px (51.809525dp)\n" +
- "\tunscaled extraSpace: 136.0px (51.809525dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
- "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
- "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1008.0px (384.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8021869px (0.305595dp)\n" +
- "\tgetCellLayoutHeight(): 1006.0px (383.2381dp)\n" +
- "\tgetCellLayoutWidth(): 1947.0px (741.7143dp)\n"
- )
+ assertDump(dp, "phoneVerticalBar3Button")
}
@Test
@@ -447,136 +61,7 @@
initializeVarsForPhone(deviceSpecs["phone"]!!, isVerticalBar = true)
val dp = getDeviceProfileForGrid("5_by_5")
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:false\n" +
- "\tisPhone:true\n" +
- "\ttransposeLayoutWithOrientation:true\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2400.0px (914.2857dp)\n" +
- "\theightPx: 1080.0px (411.42856dp)\n" +
- "\tavailableWidthPx: 2282.0px (869.3333dp)\n" +
- "\tavailableHeightPx: 943.0px (359.2381dp)\n" +
- "\tmInsets.left: 118.0px (44.95238dp)\n" +
- "\tmInsets.top: 74.0px (28.190475dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 63.0px (24.0dp)\n" +
- "\taspectRatio:2.2222223\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 5\n" +
- "\tinv.numSearchContainerColumns: 5\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 152.0px (57.904762dp)\n" +
- "\tcellHeightPx: 166.0px (63.238094dp)\n" +
- "\tgetCellSize().x: 393.0px (149.71428dp)\n" +
- "\tgetCellSize().y: 180.0px (68.57143dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
- "\ticonSizePx: 147.0px (56.0dp)\n" +
- "\ticonTextSizePx: 0.0px (0.0dp)\n" +
- "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
- "\tinv.numFolderRows: 4\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 163.0px (62.095238dp)\n" +
- "\tfolderCellHeightPx: 192.0px (73.14286dp)\n" +
- "\tfolderChildIconSizePx: 123.0px (46.857143dp)\n" +
- "\tfolderChildTextSizePx: 32.0px (12.190476dp)\n" +
- "\tfolderChildDrawablePaddingPx: 3.0px (1.1428572dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 53.0px (20.190475dp)\n" +
- "\tfolderFooterHeight: 123.0px (46.857143dp)\n" +
- "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
- "\tbottomSheetOpenDuration: 267\n" +
- "\tbottomSheetCloseDuration: 267\n" +
- "\tbottomSheetWorkspaceScale: 1.0\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
- "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
- "\tallAppsOpenDuration: 600\n" +
- "\tallAppsCloseDuration: 300\n" +
- "\tallAppsIconSizePx: 147.0px (56.0dp)\n" +
- "\tallAppsIconTextSizePx: 38.0px (14.476191dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 321.0px (122.28571dp)\n" +
- "\tallAppsCellWidthPx: 189.0px (72.0dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 5\n" +
- "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
- "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
- "\thotseatBarSizePx: 252.0px (96.0dp)\n" +
- "\tinv.hotseatColumnSpan: 5\n" +
- "\thotseatCellHeightPx: 166.0px (63.238094dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 64.0px (24.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 112.0px (42.666668dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 63.0px (24.0dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:false\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 199.0px (75.809525dp)\n" +
- "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 73.0px (27.809525dp)\n" +
- "\tunscaled extraSpace: 73.0px (27.809525dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 63.0px (24.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
- "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
- "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 952.0px (362.66666dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.79639447px (0.30338836dp)\n" +
- "\tgetCellLayoutHeight(): 943.0px (359.2381dp)\n" +
- "\tgetCellLayoutWidth(): 2073.0px (789.7143dp)\n"
- )
+ assertDump(dp, "phoneVerticalBar")
}
@Test
@@ -585,136 +70,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2560.0px (1280.0dp)\n" +
- "\theightPx: 1600.0px (800.0dp)\n" +
- "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
- "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(120.0, 104.0)dp\n" +
- "\tcellWidthPx: 240.0px (120.0dp)\n" +
- "\tcellHeightPx: 208.0px (104.0dp)\n" +
- "\tgetCellSize().x: 240.0px (120.0dp)\n" +
- "\tgetCellSize().y: 208.0px (104.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.top: 25.0px (12.5dp)\n" +
- "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
- "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 11.0px (5.5dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
- "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
- "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 412.0px (206.0dp)\n" +
- "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 668.0px (334.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 668.0px (334.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1224.0px (612.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
- "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.bottom: 244.0px (122.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 80.0px (40.0dp)\n" +
- "\tunscaled extraSpace: 80.0px (40.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 25.0px (12.5dp)\n" +
- "\tworkspaceBottomPadding: 55.0px (27.5dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)\n" +
- "\tgetCellLayoutHeight(): 1252.0px (626.0dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n"
- )
+ assertDump(dp, "tabletLandscape3Button")
}
@Test
@@ -723,136 +79,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2560.0px (1280.0dp)\n" +
- "\theightPx: 1600.0px (800.0dp)\n" +
- "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
- "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(120.0, 104.0)dp\n" +
- "\tcellWidthPx: 240.0px (120.0dp)\n" +
- "\tcellHeightPx: 208.0px (104.0dp)\n" +
- "\tgetCellSize().x: 240.0px (120.0dp)\n" +
- "\tgetCellSize().y: 208.0px (104.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.top: 25.0px (12.5dp)\n" +
- "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
- "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 11.0px (5.5dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
- "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
- "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
- "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 412.0px (206.0dp)\n" +
- "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 668.0px (334.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 668.0px (334.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1224.0px (612.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
- "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
- "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
- "\tworkspacePadding.bottom: 244.0px (122.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 80.0px (40.0dp)\n" +
- "\tunscaled extraSpace: 80.0px (40.0dp)\n" +
- "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
- "\tworkspaceTopPadding: 25.0px (12.5dp)\n" +
- "\tworkspaceBottomPadding: 55.0px (27.5dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.76677316px (0.38338658dp)\n" +
- "\tgetCellLayoutHeight(): 1252.0px (626.0dp)\n" +
- "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n"
- )
+ assertDump(dp, "tabletLandscape")
}
@Test
@@ -861,136 +88,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1600.0px (800.0dp)\n" +
- "\theightPx: 2560.0px (1280.0dp)\n" +
- "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
- "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(102.0, 120.0)dp\n" +
- "\tcellWidthPx: 204.0px (102.0dp)\n" +
- "\tcellHeightPx: 240.0px (120.0dp)\n" +
- "\tgetCellSize().x: 204.0px (102.0dp)\n" +
- "\tgetCellSize().y: 240.0px (120.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
- "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 22.0px (11.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1810.0px (905.0dp)\n" +
- "\tallAppsTopPadding: 750.0px (375.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
- "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
- "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 152.0px (76.0dp)\n" +
- "\thotseatBarSizePx: 272.0px (136.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 152.0px (76.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 150.0px (75.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 132.0px (66.0dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 468.0px (234.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 424.0px (212.0dp)\n" +
- "\tunscaled extraSpace: 424.0px (212.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 204.0px (102.0dp)\n" +
- "\tworkspaceBottomPadding: 220.0px (110.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n"
- )
+ assertDump(dp, "tabletPortrait3Button")
}
@Test
@@ -999,136 +97,7 @@
val dp = getDeviceProfileForGrid("6_by_5")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.0 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:false\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1600.0px (800.0dp)\n" +
- "\theightPx: 2560.0px (1280.0dp)\n" +
- "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
- "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 104.0px (52.0dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.6\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:true\n" +
- "\tinv.numRows: 5\n" +
- "\tinv.numColumns: 6\n" +
- "\tinv.numSearchContainerColumns: 3\n" +
- "\tminCellSize: PointF(102.0, 120.0)dp\n" +
- "\tcellWidthPx: 204.0px (102.0dp)\n" +
- "\tcellHeightPx: 240.0px (120.0dp)\n" +
- "\tgetCellSize().x: 204.0px (102.0dp)\n" +
- "\tgetCellSize().y: 240.0px (120.0dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
- "\ticonSizePx: 120.0px (60.0dp)\n" +
- "\ticonTextSizePx: 28.0px (14.0dp)\n" +
- "\ticonDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 3\n" +
- "\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
- "\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
- "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
- "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
- "\tfolderChildDrawablePaddingPx: 22.0px (11.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
- "\tfolderTopPadding: 48.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 112.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 0.0\n" +
- "\tallAppsShiftRange: 1810.0px (905.0dp)\n" +
- "\tallAppsTopPadding: 750.0px (375.0dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
- "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 9.0px (4.5dp)\n" +
- "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
- "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
- "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
- "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 6\n" +
- "\tallAppsLeftRightPadding: 32.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 152.0px (76.0dp)\n" +
- "\thotseatBarSizePx: 272.0px (136.0dp)\n" +
- "\tinv.hotseatColumnSpan: 6\n" +
- "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
- "\thotseatBarBottomSpacePx: 152.0px (76.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 137.0px (68.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 150.0px (75.0dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
- "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.top: 132.0px (66.0dp)\n" +
- "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
- "\tworkspacePadding.bottom: 468.0px (234.0dp)\n" +
- "\ticonScale: 1.0px (0.5dp)\n" +
- "\tcellScaleToFit : 1.0px (0.5dp)\n" +
- "\textraSpace: 424.0px (212.0dp)\n" +
- "\tunscaled extraSpace: 424.0px (212.0dp)\n" +
- "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
- "\tworkspaceTopPadding: 204.0px (102.0dp)\n" +
- "\tworkspaceBottomPadding: 220.0px (110.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
- "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 2072.0px (1036.0dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8125px (0.40625dp)\n" +
- "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
- "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n"
- )
+ assertDump(dp, "tabletPortrait")
}
@Test
@@ -1142,136 +111,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2208.0px (841.1429dp)\n" +
- "\theightPx: 1840.0px (700.9524dp)\n" +
- "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
- "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 110.0px (41.904762dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 270.0px (102.85714dp)\n" +
- "\tgetCellSize().y: 342.0px (130.28572dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 183.0px (69.71429dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 113.0px (43.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 113.0px (43.04762dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 30.0px (11.428572dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 498.0px (189.71428dp)\n" +
- "\tunscaled extraSpace: 498.0px (189.71428dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)\n" +
- "\tgetCellLayoutHeight(): 1370.0px (521.9048dp)\n" +
- "\tgetCellLayoutWidth(): 1083.0px (412.57144dp)\n"
- )
+ assertDump(dp, "twoPanelLandscape3Button")
}
@Test
@@ -1284,136 +124,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:true\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 2208.0px (841.1429dp)\n" +
- "\theightPx: 1840.0px (700.9524dp)\n" +
- "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
- "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 110.0px (41.904762dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 270.0px (102.85714dp)\n" +
- "\tgetCellSize().y: 342.0px (130.28572dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
- "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 183.0px (69.71429dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 113.0px (43.04762dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 113.0px (43.04762dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 30.0px (11.428572dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 498.0px (189.71428dp)\n" +
- "\tunscaled extraSpace: 498.0px (189.71428dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1457.0px (555.0476dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.8452555px (0.32200208dp)\n" +
- "\tgetCellLayoutHeight(): 1370.0px (521.9048dp)\n" +
- "\tgetCellLayoutWidth(): 1083.0px (412.57144dp)\n"
- )
+ assertDump(dp, "twoPanelLandscape")
}
@Test
@@ -1426,136 +137,7 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:false\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1840.0px (700.9524dp)\n" +
- "\theightPx: 2208.0px (841.1429dp)\n" +
- "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
- "\tavailableHeightPx: 2075.0px (790.4762dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 133.0px (50.666668dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 224.0px (85.333336dp)\n" +
- "\tgetCellSize().y: 430.0px (163.80952dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 133.0px (50.666668dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1826.0px (695.619dp)\n" +
- "\tallAppsTopPadding: 382.0px (145.5238dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 1.0px (0.3809524dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 98.0px (37.333332dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 98.0px (37.333332dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 24.0px (9.142858dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 849.0px (323.42856dp)\n" +
- "\tunscaled extraSpace: 849.0px (323.42856dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)\n" +
- "\tgetCellLayoutHeight(): 1721.0px (655.619dp)\n" +
- "\tgetCellLayoutWidth(): 899.0px (342.4762dp)\n"
- )
+ assertDump(dp, "twoPanelPortrait3Button")
}
@Test
@@ -1564,147 +146,17 @@
val dp = getDeviceProfileForGrid("4_by_4")
dp.isTaskbarPresentInApps = true
- assertThat(dump(dp))
- .isEqualTo(
- "DeviceProfile:\n" +
- "\t1 dp = 2.625 px\n" +
- "\tisTablet:true\n" +
- "\tisPhone:false\n" +
- "\ttransposeLayoutWithOrientation:false\n" +
- "\tisGestureMode:true\n" +
- "\tisLandscape:false\n" +
- "\tisMultiWindowMode:false\n" +
- "\tisTwoPanels:true\n" +
- "\twindowX: 0.0px (0.0dp)\n" +
- "\twindowY: 0.0px (0.0dp)\n" +
- "\twidthPx: 1840.0px (700.9524dp)\n" +
- "\theightPx: 2208.0px (841.1429dp)\n" +
- "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
- "\tavailableHeightPx: 2075.0px (790.4762dp)\n" +
- "\tmInsets.left: 0.0px (0.0dp)\n" +
- "\tmInsets.top: 133.0px (50.666668dp)\n" +
- "\tmInsets.right: 0.0px (0.0dp)\n" +
- "\tmInsets.bottom: 0.0px (0.0dp)\n" +
- "\taspectRatio:1.2\n" +
- "\tisResponsiveGrid:false\n" +
- "\tisScalableGrid:false\n" +
- "\tinv.numRows: 4\n" +
- "\tinv.numColumns: 4\n" +
- "\tinv.numSearchContainerColumns: 4\n" +
- "\tminCellSize: PointF(0.0, 0.0)dp\n" +
- "\tcellWidthPx: 154.0px (58.666668dp)\n" +
- "\tcellHeightPx: 218.0px (83.04762dp)\n" +
- "\tgetCellSize().x: 224.0px (85.333336dp)\n" +
- "\tgetCellSize().y: 430.0px (163.80952dp)\n" +
- "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
- "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.left: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.right: 0.0px (0.0dp)\n" +
- "\tcellLayoutPaddingPx.bottom: 0.0px (0.0dp)\n" +
- "\ticonSizePx: 141.0px (53.714287dp)\n" +
- "\ticonTextSizePx: 34.0px (12.952381dp)\n" +
- "\ticonDrawablePaddingPx: 13.0px (4.952381dp)\n" +
- "\tinv.numFolderRows: 3\n" +
- "\tinv.numFolderColumns: 4\n" +
- "\tfolderCellWidthPx: 189.0px (72.0dp)\n" +
- "\tfolderCellHeightPx: 219.0px (83.42857dp)\n" +
- "\tfolderChildIconSizePx: 141.0px (53.714287dp)\n" +
- "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
- "\tfolderChildDrawablePaddingPx: 5.0px (1.9047619dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.x: 0.0px (0.0dp)\n" +
- "\tfolderCellLayoutBorderSpacePx.y: 0.0px (0.0dp)\n" +
- "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
- "\tfolderTopPadding: 63.0px (24.0dp)\n" +
- "\tfolderFooterHeight: 147.0px (56.0dp)\n" +
- "\tbottomSheetTopPadding: 133.0px (50.666668dp)\n" +
- "\tbottomSheetOpenDuration: 500\n" +
- "\tbottomSheetCloseDuration: 500\n" +
- "\tbottomSheetWorkspaceScale: 0.97\n" +
- "\tbottomSheetDepth: 1.0\n" +
- "\tallAppsShiftRange: 1826.0px (695.619dp)\n" +
- "\tallAppsTopPadding: 382.0px (145.5238dp)\n" +
- "\tallAppsOpenDuration: 500\n" +
- "\tallAppsCloseDuration: 500\n" +
- "\tallAppsIconSizePx: 141.0px (53.714287dp)\n" +
- "\tallAppsIconTextSizePx: 34.0px (12.952381dp)\n" +
- "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
- "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
- "\tallAppsCellWidthPx: 183.0px (69.71429dp)\n" +
- "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
- "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
- "\tnumShownAllAppsColumns: 8\n" +
- "\tallAppsLeftRightPadding: 42.0px (16.0dp)\n" +
- "\tallAppsLeftRightMargin: 1.0px (0.3809524dp)\n" +
- "\thotseatBarSizePx: 267.0px (101.71429dp)\n" +
- "\tinv.hotseatColumnSpan: 4\n" +
- "\thotseatCellHeightPx: 159.0px (60.57143dp)\n" +
- "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
- "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
- "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
- "\thotseatQsbSpace: 0.0px (0.0dp)\n" +
- "\thotseatQsbHeight: 0.0px (0.0dp)\n" +
- "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
- "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).bottom: 108.0px (41.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 98.0px (37.333332dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 98.0px (37.333332dp)\n" +
- "\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
- "\tisQsbInline: false\n" +
- "\thotseatQsbWidth: 0.0px (0.0dp)\n" +
- "\tisTaskbarPresent:false\n" +
- "\tisTaskbarPresentInApps:true\n" +
- "\ttaskbarHeight: 0.0px (0.0dp)\n" +
- "\tstashedTaskbarHeight: 0.0px (0.0dp)\n" +
- "\ttaskbarBottomMargin: 0.0px (0.0dp)\n" +
- "\ttaskbarIconSize: 0.0px (0.0dp)\n" +
- "\tdesiredWorkspaceHorizontalMarginPx: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.left: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.top: 24.0px (9.142858dp)\n" +
- "\tworkspacePadding.right: 21.0px (8.0dp)\n" +
- "\tworkspacePadding.bottom: 330.0px (125.71429dp)\n" +
- "\ticonScale: 1.0px (0.3809524dp)\n" +
- "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
- "\textraSpace: 849.0px (323.42856dp)\n" +
- "\tunscaled extraSpace: 849.0px (323.42856dp)\n" +
- "\tmaxEmptySpace: 0.0px (0.0dp)\n" +
- "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
- "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
- "\toverviewTaskMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizePx: 0.0px (0.0dp)\n" +
- "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
- "\toverviewTaskThumbnailTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsTopMarginPx: 0.0px (0.0dp)\n" +
- "\toverviewActionsHeight: 0.0px (0.0dp)\n" +
- "\toverviewActionsClaimedSpaceBelow: 0.0px (0.0dp)\n" +
- "\toverviewActionsButtonSpacing: 0.0px (0.0dp)\n" +
- "\toverviewPageSpacing: 0.0px (0.0dp)\n" +
- "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
- "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
- "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
- "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
- "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkTop(): 490.0px (186.66667dp)\n" +
- "\tgetCellLayoutSpringLoadShrunkBottom(): 1770.0px (674.2857dp)\n" +
- "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
- "\tgetWorkspaceSpringLoadScale(): 0.7437536px (0.2833347dp)\n" +
- "\tgetCellLayoutHeight(): 1721.0px (655.619dp)\n" +
- "\tgetCellLayoutWidth(): 899.0px (342.4762dp)\n"
- )
+ assertDump(dp, "twoPanelPortrait")
}
private fun getDeviceProfileForGrid(gridName: String): DeviceProfile {
return InvariantDeviceProfile(context, gridName).getDeviceProfile(context)
}
- private fun dump(dp: DeviceProfile): String {
- val stringWriter = StringWriter()
- val printWriter = PrintWriter(stringWriter)
- dp.dump(context, "", printWriter)
- printWriter.flush()
- return stringWriter.toString()
+ private fun assertDump(dp: DeviceProfile, filename: String) {
+ val dump = dump(context!!, dp, "${folderName}_$filename.txt")
+ val expected = readDumpFromAssets(testContext, "$folderName/$filename.txt")
+
+ assertThat(dump).isEqualTo(expected)
}
}
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 6764e09..f3eb0a9 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -64,34 +64,14 @@
MAX_SHORTCUTS - NUM_DYNAMIC, NUM_DYNAMIC);
}
- @Test
- public void testDeDupeShortcutId() {
- // Successfully remove one of the shortcuts
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 2, 0, generateId(true, 1));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(0, 3), 0, 2, generateId(false, 1));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 1, generateId(false, 1));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 1, 2, generateId(true, 1));
- // Successfully keep all shortcuts when id doesn't exist
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(false, 1));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(3, 0), 3, 0, generateId(true, 4));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(false, 4));
- filterShortcutsAndAssertNumStaticAndDynamic(createShortcutsList(2, 2), 2, 2, generateId(true, 4));
- }
-
private String generateId(boolean isStatic, int rank) {
return (isStatic ? "static" : "dynamic") + rank;
}
private void filterShortcutsAndAssertNumStaticAndDynamic(
List<ShortcutInfo> shortcuts, int expectedStatic, int expectedDynamic) {
- filterShortcutsAndAssertNumStaticAndDynamic(shortcuts, expectedStatic, expectedDynamic, null);
- }
-
- private void filterShortcutsAndAssertNumStaticAndDynamic(List<ShortcutInfo> shortcuts,
- int expectedStatic, int expectedDynamic, String shortcutIdToRemove) {
Collections.shuffle(shortcuts);
- List<ShortcutInfo> filteredShortcuts = PopupPopulator.sortAndFilterShortcuts(
- shortcuts, shortcutIdToRemove);
+ List<ShortcutInfo> filteredShortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts);
assertIsSorted(filteredShortcuts);
int numStatic = 0;
diff --git a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
index 73bb586..10d9133 100644
--- a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
+++ b/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
@@ -19,17 +19,30 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS;
+import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS;
+import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
+import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID;
+
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import android.app.backup.BackupManager;
+import android.appwidget.AppWidgetHost;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
@@ -43,15 +56,21 @@
import androidx.test.filters.SmallTest;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.model.ModelDbController;
+import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LauncherModelHelper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
/**
* Tests for {@link RestoreDbTask}
@@ -66,16 +85,27 @@
private LauncherModelHelper mModelHelper;
private Context mContext;
+ private RestoreDbTask mTask;
+ private ModelDbController mMockController;
+ private SQLiteDatabase mMockDb;
+ private Cursor mMockCursor;
+ private LauncherPrefs mPrefs;
@Before
public void setup() {
mModelHelper = new LauncherModelHelper();
mContext = mModelHelper.sandboxContext;
+ mTask = new RestoreDbTask();
+ mMockController = Mockito.mock(ModelDbController.class);
+ mMockDb = mock(SQLiteDatabase.class);
+ mMockCursor = mock(Cursor.class);
+ mPrefs = new LauncherPrefs(mContext);
}
@After
public void teardown() {
mModelHelper.destroy();
+ LauncherPrefs.get(mContext).removeSync(RESTORE_DEVICE);
}
@Test
@@ -148,8 +178,7 @@
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
- RestoreDbTask task = new RestoreDbTask();
- task.sanitizeDB(mContext, controller, controller.getDb(), bm);
+ mTask.sanitizeDB(mContext, controller, controller.getDb(), bm);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
@@ -178,8 +207,7 @@
assertEquals(10, getItemCountForProfile(db, myProfileId_old));
assertEquals(6, getItemCountForProfile(db, workProfileId_old));
- RestoreDbTask task = new RestoreDbTask();
- task.sanitizeDB(mContext, controller, controller.getDb(), bm);
+ mTask.sanitizeDB(mContext, controller, controller.getDb(), bm);
// All the data has been migrated to the new user ids
assertEquals(0, getItemCountForProfile(db, myProfileId_old));
@@ -188,6 +216,83 @@
assertEquals(10, getCount(db, "select * from favorites"));
}
+ @Test
+ public void givenLauncherPrefsHasNoIds_whenRestoreAppWidgetIdsIfExists_thenIdsAreRemoved() {
+ // When
+ mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
+ // Then
+ assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
+ }
+
+ @Test
+ public void givenNoPendingRestore_WhenRestoreAppWidgetIds_ThenRemoveNewWidgetIds() {
+ // Given
+ AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
+ int[] expectedOldIds = generateOldWidgetIds(expectedHost);
+ int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
+ when(mMockController.getDb()).thenReturn(mMockDb);
+ mPrefs.remove(RESTORE_DEVICE);
+
+ // When
+ setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
+ mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
+
+ // Then
+ assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds);
+ assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
+ verifyZeroInteractions(mMockController);
+ }
+
+ @Test
+ public void givenRestoreWithNonExistingWidgets_WhenRestoreAppWidgetIds_ThenRemoveNewIds() {
+ // Given
+ AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
+ int[] expectedOldIds = generateOldWidgetIds(expectedHost);
+ int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
+ when(mMockController.getDb()).thenReturn(mMockDb);
+ when(mMockDb.query(any(), any(), any(), any(), any(), any(), any())).thenReturn(
+ mMockCursor);
+ when(mMockCursor.moveToFirst()).thenReturn(false);
+ RestoreDbTask.setPending(mContext);
+
+ // When
+ setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
+ mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
+
+ // Then
+ assertThat(expectedHost.getAppWidgetIds()).isEqualTo(expectedOldIds);
+ assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
+ verify(mMockController, times(expectedOldIds.length)).update(any(), any(), any(), any());
+ }
+
+ @Test
+ public void givenRestore_WhenRestoreAppWidgetIds_ThenAddNewIds() {
+ // Given
+ AppWidgetHost expectedHost = new AppWidgetHost(mContext, APPWIDGET_HOST_ID);
+ int[] expectedOldIds = generateOldWidgetIds(expectedHost);
+ int[] expectedNewIds = generateNewWidgetIds(expectedHost, expectedOldIds);
+ int[] allExpectedIds = IntStream.concat(
+ Arrays.stream(expectedOldIds),
+ Arrays.stream(expectedNewIds)
+ ).toArray();
+
+ when(mMockController.getDb()).thenReturn(mMockDb);
+ when(mMockDb.query(any(), any(), any(), any(), any(), any(), any()))
+ .thenReturn(mMockCursor);
+ when(mMockCursor.moveToFirst()).thenReturn(true);
+ when(mMockCursor.isAfterLast()).thenReturn(true);
+ RestoreDbTask.setPending(mContext);
+
+ // When
+ setRestoredAppWidgetIds(mContext, expectedOldIds, expectedNewIds);
+ mTask.restoreAppWidgetIdsIfExists(mContext, mMockController);
+
+ // Then
+ assertThat(expectedHost.getAppWidgetIds()).isEqualTo(allExpectedIds);
+ assertThat(mPrefs.has(OLD_APP_WIDGET_IDS, APP_WIDGET_IDS)).isFalse();
+ verify(mMockController, times(expectedOldIds.length)).update(any(), any(), any(), any());
+ }
+
private void addIconsBulk(MyModelDbController controller,
int count, int screen, long profileId) {
int columns = LauncherAppState.getIDP(mContext).numColumns;
@@ -270,6 +375,19 @@
}
}
+ private int[] generateOldWidgetIds(AppWidgetHost host) {
+ // generate some widget ids in case there are none
+ host.allocateAppWidgetId();
+ host.allocateAppWidgetId();
+ return host.getAppWidgetIds();
+ }
+
+ private int[] generateNewWidgetIds(AppWidgetHost host, int[] oldWidgetIds) {
+ // map as many new ids as old ids
+ return Arrays.stream(oldWidgetIds)
+ .map(id -> host.allocateAppWidgetId()).toArray();
+ }
+
private class MyModelDbController extends ModelDbController {
public final LongSparseArray<UserHandle> users = new LongSparseArray<>();
@@ -285,4 +403,10 @@
return index >= 0 ? users.keyAt(index) : -1;
}
}
+
+ private void setRestoredAppWidgetIds(Context context, int[] oldIds, int[] newIds) {
+ LauncherPrefs.get(context).putSync(
+ OLD_APP_WIDGET_IDS.to(IntArray.wrap(oldIds).toConcatString()),
+ APP_WIDGET_IDS.to(IntArray.wrap(newIds).toConcatString()));
+ }
}
diff --git a/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt b/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
index 0ecf7ba..5865036 100644
--- a/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
+++ b/tests/src/com/android/launcher3/responsive/CalculatedHotseatSpecTest.kt
@@ -50,6 +50,7 @@
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(95)
+ assertThat(heightSpec.edgePadding).isEqualTo(126)
}
/**
@@ -71,5 +72,27 @@
assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
assertThat(heightSpec.hotseatQsbSpace).isEqualTo(81)
+ assertThat(heightSpec.edgePadding).isEqualTo(162)
+ }
+
+ /**
+ * This test tests:
+ * - (width spec) gets the correct breakpoint from the XML - skips the first breakpoint
+ */
+ @Test
+ fun normalPhoneLandscape_returnsSecondBreakpointSpec() {
+ val deviceSpec = deviceSpecs["phone"]!!
+ initializeVarsForPhone(deviceSpec, isVerticalBar = true)
+
+ // Hotseat uses the whole device width
+ val availableWidth = deviceSpec.naturalSize.second
+
+ val hotseatSpecs =
+ HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_land_file))
+ val widthSpec = hotseatSpecs.getCalculatedWidthSpec(availableWidth)
+
+ assertThat(widthSpec.availableSpace).isEqualTo(availableWidth)
+ assertThat(widthSpec.hotseatQsbSpace).isEqualTo(0)
+ assertThat(widthSpec.edgePadding).isEqualTo(168)
}
}
diff --git a/tests/src/com/android/launcher3/responsive/CalculatedWorkspaceSpecTest.kt b/tests/src/com/android/launcher3/responsive/CalculatedWorkspaceSpecTest.kt
index 0af694e..8f56c5f 100644
--- a/tests/src/com/android/launcher3/responsive/CalculatedWorkspaceSpecTest.kt
+++ b/tests/src/com/android/launcher3/responsive/CalculatedWorkspaceSpecTest.kt
@@ -104,4 +104,43 @@
assertThat(heightSpec.gutterPx).isEqualTo(54)
assertThat(heightSpec.cellSizePx).isEqualTo(260)
}
+
+ /**
+ * This test tests:
+ * - (height spec) gets the correct breakpoint from the XML - use the first breakpoint
+ * - (height spec) do the correct calculations for remainder space and fixed size
+ * - (width spec) do the correct calculations for remainder space and fixed size
+ */
+ @Test
+ fun smallPhone_returnsFirstBreakpointSpec_unsortedFile() {
+ val deviceSpec = deviceSpecs["phone"]!!
+ deviceSpec.densityDpi = 540 // larger display size
+ initializeVarsForPhone(deviceSpec)
+
+ val availableWidth = deviceSpec.naturalSize.first
+ // Hotseat size is roughly 640px on a real device,
+ // it doesn't need to be precise on unit tests
+ val availableHeight = deviceSpec.naturalSize.second - deviceSpec.statusBarNaturalPx - 640
+
+ val workspaceSpecs =
+ WorkspaceSpecs.create(
+ TestResourceHelper(context!!, TestR.xml.valid_workspace_unsorted_file)
+ )
+ val widthSpec = workspaceSpecs.getCalculatedWidthSpec(4, availableWidth)
+ val heightSpec = workspaceSpecs.getCalculatedHeightSpec(5, availableHeight)
+
+ assertThat(widthSpec.availableSpace).isEqualTo(availableWidth)
+ assertThat(widthSpec.cells).isEqualTo(4)
+ assertThat(widthSpec.startPaddingPx).isEqualTo(74)
+ assertThat(widthSpec.endPaddingPx).isEqualTo(74)
+ assertThat(widthSpec.gutterPx).isEqualTo(54)
+ assertThat(widthSpec.cellSizePx).isEqualTo(193)
+
+ assertThat(heightSpec.availableSpace).isEqualTo(availableHeight)
+ assertThat(heightSpec.cells).isEqualTo(5)
+ assertThat(heightSpec.startPaddingPx).isEqualTo(0)
+ assertThat(heightSpec.endPaddingPx).isEqualTo(108)
+ assertThat(heightSpec.gutterPx).isEqualTo(54)
+ assertThat(heightSpec.cellSizePx).isEqualTo(260)
+ }
}
diff --git a/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt b/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
index c764e47..f650e91 100644
--- a/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
+++ b/tests/src/com/android/launcher3/responsive/HotseatSpecsTest.kt
@@ -23,7 +23,6 @@
import com.android.launcher3.AbstractDeviceProfileTest
import com.android.launcher3.tests.R as TestR
import com.android.launcher3.util.TestResourceHelper
-import com.android.systemui.util.dpToPx
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@@ -43,25 +42,55 @@
fun parseValidFile() {
val hotseatSpecs =
HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_file))
- assertThat(hotseatSpecs.specs.size).isEqualTo(2)
- val expectedSpecs =
+ val expectedHeightSpecs =
listOf(
HotseatSpec(
maxAvailableSize = 847.dpToPx(),
specType = ResponsiveSpec.SpecType.HEIGHT,
- hotseatQsbSpace = SizeSpec(24f.dpToPx())
+ hotseatQsbSpace = SizeSpec(24f.dpToPx()),
+ edgePadding = SizeSpec(48f.dpToPx())
),
HotseatSpec(
maxAvailableSize = 9999.dpToPx(),
specType = ResponsiveSpec.SpecType.HEIGHT,
- hotseatQsbSpace = SizeSpec(36f.dpToPx())
+ hotseatQsbSpace = SizeSpec(36f.dpToPx()),
+ edgePadding = SizeSpec(48f.dpToPx())
),
)
- assertThat(hotseatSpecs.specs.size).isEqualTo(expectedSpecs.size)
- assertThat(hotseatSpecs.specs[0]).isEqualTo(expectedSpecs[0])
- assertThat(hotseatSpecs.specs[1]).isEqualTo(expectedSpecs[1])
+ assertThat(hotseatSpecs.heightSpecs.size).isEqualTo(expectedHeightSpecs.size)
+ assertThat(hotseatSpecs.heightSpecs[0]).isEqualTo(expectedHeightSpecs[0])
+ assertThat(hotseatSpecs.heightSpecs[1]).isEqualTo(expectedHeightSpecs[1])
+
+ assertThat(hotseatSpecs.widthSpecs.size).isEqualTo(0)
+ }
+
+ @Test
+ fun parseValidLandscapeFile() {
+ val hotseatSpecs =
+ HotseatSpecs.create(TestResourceHelper(context!!, TestR.xml.valid_hotseat_land_file))
+ assertThat(hotseatSpecs.heightSpecs.size).isEqualTo(0)
+
+ val expectedWidthSpecs =
+ listOf(
+ HotseatSpec(
+ maxAvailableSize = 743.dpToPx(),
+ specType = ResponsiveSpec.SpecType.WIDTH,
+ hotseatQsbSpace = SizeSpec(0f),
+ edgePadding = SizeSpec(48f.dpToPx())
+ ),
+ HotseatSpec(
+ maxAvailableSize = 9999.dpToPx(),
+ specType = ResponsiveSpec.SpecType.WIDTH,
+ hotseatQsbSpace = SizeSpec(0f),
+ edgePadding = SizeSpec(64f.dpToPx())
+ ),
+ )
+
+ assertThat(hotseatSpecs.widthSpecs.size).isEqualTo(expectedWidthSpecs.size)
+ assertThat(hotseatSpecs.widthSpecs[0]).isEqualTo(expectedWidthSpecs[0])
+ assertThat(hotseatSpecs.widthSpecs[1]).isEqualTo(expectedWidthSpecs[1])
}
@Test(expected = IllegalStateException::class)
diff --git a/tests/src/com/android/launcher3/settings/SettingsActivityTest.java b/tests/src/com/android/launcher3/settings/SettingsActivityTest.java
index 837973f..10e0be8 100644
--- a/tests/src/com/android/launcher3/settings/SettingsActivityTest.java
+++ b/tests/src/com/android/launcher3/settings/SettingsActivityTest.java
@@ -31,8 +31,9 @@
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT;
+import static com.android.launcher3.settings.SettingsActivity.DEVELOPER_OPTIONS_KEY;
import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARGS;
+import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ROOT_KEY;
import static com.google.common.truth.Truth.assertThat;
@@ -43,18 +44,15 @@
import android.content.Intent;
import android.os.Bundle;
-import androidx.preference.PreferenceFragmentCompat;
import androidx.test.core.app.ActivityScenario;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.espresso.intent.Intents;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.launcher3.R;
-import com.android.launcher3.uioverrides.flags.DeveloperOptionsFragment;
import com.android.systemui.shared.plugins.PluginPrefs;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -100,7 +98,7 @@
intended(allOf(
hasComponent(SettingsActivity.class.getName()),
- hasExtra(EXTRA_FRAGMENT, DeveloperOptionsFragment.class.getName())));
+ hasExtra(EXTRA_FRAGMENT_ROOT_KEY, DEVELOPER_OPTIONS_KEY)));
}
@Test
@@ -122,7 +120,7 @@
@Ignore // b/199309785
public void testSettings_developerOptionsFragmentIntent() {
Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
- .putExtra(EXTRA_FRAGMENT, DeveloperOptionsFragment.class.getName());
+ .putExtra(EXTRA_FRAGMENT_ROOT_KEY, DEVELOPER_OPTIONS_KEY);
ActivityScenario.launch(intent);
onView(withText("Developer Options")).check(matches(isDisplayed()));
@@ -132,21 +130,6 @@
@Test
@Ignore // b/199309785
- public void testSettings_intentWithUnknownFragment() {
- String fragmentClass = PreferenceFragmentCompat.class.getName();
- Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
- .putExtra(EXTRA_FRAGMENT, fragmentClass);
-
- try {
- ActivityScenario.launch(intent);
- Assert.fail("Should have thrown an IllegalArgumentException.");
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage()).contains(fragmentClass);
- }
- }
-
- @Test
- @Ignore // b/199309785
public void testSettings_backButtonFinishesActivity() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putString(ARG_PREFERENCE_ROOT, "about_screen");
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5240e6a..9bfafcf 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -15,10 +15,11 @@
*/
package com.android.launcher3.ui;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
-import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static org.junit.Assert.assertEquals;
@@ -40,6 +41,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.system.OsConstants;
import android.util.Log;
@@ -68,6 +70,7 @@
import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.ShellCommandRule;
+import com.android.launcher3.util.rule.TestIsolationRule;
import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.launcher3.util.rule.ViewCaptureRule;
@@ -111,25 +114,39 @@
protected String mTargetPackage;
private int mLauncherPid;
+ /** Detects activity leaks and throws an exception if a leak is found. */
public static void checkDetectedLeaks(LauncherInstrumentation launcher) {
+ checkDetectedLeaks(launcher, false);
+ }
+
+ /** Detects activity leaks and throws an exception if a leak is found. */
+ public static void checkDetectedLeaks(LauncherInstrumentation launcher,
+ boolean requireOneActiveActivity) {
if (sActivityLeakReported) return;
// Check whether activity leak detector has found leaked activities.
- Wait.atMost(() -> getActivityLeakErrorMessage(launcher),
+ Wait.atMost(() -> getActivityLeakErrorMessage(launcher, requireOneActiveActivity),
() -> {
launcher.forceGc();
return MAIN_EXECUTOR.submit(
- () -> launcher.noLeakedActivities()).get();
+ () -> launcher.noLeakedActivities(requireOneActiveActivity)).get();
}, DEFAULT_UI_TIMEOUT, launcher);
}
- private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) {
- sActivityLeakReported = true;
- return "Activity leak detector has found leaked activities, "
- + dumpHprofData(launcher, false) + ".";
+ public static String getAppPackageName() {
+ return getInstrumentation().getContext().getPackageName();
}
- public static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak) {
+ private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher,
+ boolean requireOneActiveActivity) {
+ sActivityLeakReported = true;
+ return "Activity leak detector has found leaked activities, requirining 1 activity: "
+ + requireOneActiveActivity + "; "
+ + dumpHprofData(launcher, false, requireOneActiveActivity) + ".";
+ }
+
+ private static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak,
+ boolean requireOneActiveActivity) {
if (intentionalLeak) return "intentional leak; not generating dump";
String result;
@@ -148,7 +165,7 @@
"am dumpheap " + device.getLauncherPackageName() + " " + fileName);
}
Log.d(TAG, "Saved leak dump, the leak is still present: "
- + !launcher.noLeakedActivities());
+ + !launcher.noLeakedActivities(requireOneActiveActivity));
sDumpWasGenerated = true;
result = "saved memory dump as an artifact";
} catch (Throwable e) {
@@ -169,8 +186,8 @@
if (TestHelpers.isInLauncherProcess()) {
Utilities.enableRunningInTestHarnessForTests();
mLauncher.setSystemHealthSupplier(startTime -> TestCommandReceiver.callCommand(
- TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString()).
- getString("result"));
+ TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString())
+ .getString("result"));
mLauncher.setOnSettledStateAction(
containerType -> executeOnLauncher(
launcher ->
@@ -188,12 +205,15 @@
@Rule
public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
+ @Rule
+ public SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
protected void clearPackageData(String pkg) throws IOException, InterruptedException {
final CountDownLatch count = new CountDownLatch(2);
final SimpleBroadcastReceiver broadcastReceiver =
new SimpleBroadcastReceiver(i -> count.countDown());
broadcastReceiver.registerPkgActions(mTargetContext, pkg,
- Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED);
+ Intent.ACTION_PACKAGE_RESTARTED, Intent.ACTION_PACKAGE_DATA_CLEARED);
mDevice.executeShellCommand("pm clear " + pkg);
assertTrue(pkg + " didn't restart", count.await(10, TimeUnit.SECONDS));
@@ -206,7 +226,8 @@
final RuleChain inner = RuleChain
.outerRule(new PortraitLandscapeRunner(this))
.around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
- .around(viewCaptureRule);
+ .around(viewCaptureRule)
+ .around(new TestIsolationRule(mLauncher, true));
return TestHelpers.isInLauncherProcess()
? RuleChain.outerRule(ShellCommandRule.setDefaultLauncher()).around(inner)
@@ -227,7 +248,12 @@
public void setUp() throws Exception {
mLauncher.onTestStart();
- verifyKeyguardInvisible();
+ waitForSetupWizardDismissal();
+ if (TestStabilityRule.isPresubmit()) {
+ aggressivelyUnlockSysUi();
+ } else {
+ verifyKeyguardInvisible();
+ }
final String launcherPackageName = mDevice.getLauncherPackageName();
try {
@@ -258,9 +284,62 @@
}
}
}
+
+ verifyKeyguardInvisible();
}
- private static void verifyKeyguardInvisible() {
+ private boolean hasSystemUiObject(String resId) {
+ return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
+ }
+
+ // Seeing if this will decrease: b/303755862
+ void aggressivelyUnlockSysUi() {
+ for (int i = 0; i < 10 && hasSystemUiObject("keyguard_status_view"); ++i) {
+ Log.d(TAG, "Before attempting to unlock the phone");
+ try {
+ mDevice.executeShellCommand("input keyevent 82");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ mDevice.waitForIdle();
+ }
+ Assert.assertTrue("Keyguard still visible",
+ TestHelpers.wait(
+ Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
+ Log.d(TAG, "Keyguard is not visible");
+ }
+
+ // b/309008042
+ private static boolean sFirstTimeWaitingForWizard = true;
+
+ // b/309008042
+ static {
+ waitForSetupWizardDismissal();
+ }
+
+ // b/309008042
+ // TODO(309471958) Productize killing/dismissal of setup wizard.
+ /** Waits for setup wizard to go away. */
+ public static void waitForSetupWizardDismissal() {
+ if (sFirstTimeWaitingForWizard && TestStabilityRule.isPresubmit()) {
+ try {
+ UiDevice.getInstance(getInstrumentation()).executeShellCommand(
+ "am force-stop com.google.android.setupwizard");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ final boolean wizardDismissed = TestHelpers.wait(
+ Until.gone(By.pkg("com.google.android.setupwizard").depth(0)),
+ sFirstTimeWaitingForWizard ? 120000 : 0);
+ sFirstTimeWaitingForWizard = false;
+ // b/309496273
+// Assert.assertTrue("Setup wizard is still visible",
+// wizardDismissed);
+ }
+
+ public static void verifyKeyguardInvisible() {
final boolean keyguardAlreadyVisible = sSeenKeyguard;
sSeenKeyguard = sSeenKeyguard
@@ -329,6 +408,15 @@
});
}
+ // Execute an action on Launcher, but forgive it when launcher is null.
+ // Launcher can be null if teardown is happening after a failed setup step where launcher
+ // activity failed to be created.
+ protected void executeOnLauncherInTearDown(Consumer<Launcher> f) {
+ executeOnLauncher(launcher -> {
+ if (launcher != null) f.accept(launcher);
+ });
+ }
+
// Cannot be used in TaplTests between a Tapl call injecting a gesture and a tapl call
// expecting the results of that gesture because the wait can hide flakeness.
protected void waitForState(String message, Supplier<LauncherState> state) {
@@ -365,6 +453,7 @@
// flakiness.
protected void waitForLauncherCondition(
String message, Function<Launcher, Boolean> condition, long timeout) {
+ waitForSetupWizardDismissal();
verifyKeyguardInvisible();
if (!TestHelpers.isInLauncherProcess()) return;
Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher);
diff --git a/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java b/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
new file mode 100644
index 0000000..ba416ae
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.ui;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserHandle;
+import android.os.UserManager;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.WorkProfileManager;
+import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.util.ActivityContextWrapper;
+
+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;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActivityAllAppsContainerViewTest {
+
+ private static final UserHandle WORK_HANDLE = new UserHandle(13);
+ @Mock
+ private StatsLogManager mStatsLogManager;
+ private AppInfo[] mWorkAppInfo;
+ private ActivityAllAppsContainerView<?> mActivityAllAppsContainerView;
+ private WorkProfileManager mWorkManager;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ Context context = new ActivityContextWrapper(getApplicationContext());
+ mActivityAllAppsContainerView = new ActivityAllAppsContainerView(context);
+ mWorkManager = new WorkProfileManager(context.getSystemService(UserManager.class),
+ mActivityAllAppsContainerView, mStatsLogManager);
+ mActivityAllAppsContainerView.setWorkManager(mWorkManager);
+ ComponentName componentName = new ComponentName(context,
+ "com.android.launcher3.tests.Activity" + "Gmail");
+ AppInfo gmailWorkAppInfo = new AppInfo(componentName, "Gmail", WORK_HANDLE, new Intent());
+ mWorkAppInfo = new AppInfo[]{gmailWorkAppInfo};
+ }
+
+ @Test
+ public void testOnAppsUpdatedWithoutWorkApps_shouldShowTabsIsFalse() {
+ mActivityAllAppsContainerView.getAppsStore().setApps(EMPTY_ARRAY, 0, null);
+
+ mActivityAllAppsContainerView.onAppsUpdated();
+
+ assertThat(mActivityAllAppsContainerView.shouldShowTabs()).isEqualTo(false);
+ }
+
+ @Test
+ public void testOnAppsUpdatedWithWorkApps_shouldShowTabsIsTrue() {
+ mActivityAllAppsContainerView.getAppsStore().setApps(mWorkAppInfo, 0, null);
+
+ mActivityAllAppsContainerView.onAppsUpdated();
+
+ assertThat(mActivityAllAppsContainerView.shouldShowTabs()).isEqualTo(true);
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
index ba17fdc..58af51c 100644
--- a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
+++ b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java
@@ -20,26 +20,39 @@
import static com.android.launcher3.BubbleTextView.DISPLAY_ALL_APPS;
import static com.android.launcher3.BubbleTextView.DISPLAY_PREDICTION_ROW;
+import static com.android.launcher3.BubbleTextView.DISPLAY_SEARCH_RESULT;
+import static com.android.launcher3.BubbleTextView.DISPLAY_SEARCH_RESULT_SMALL;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWOLINE_ALLAPPS;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Typeface;
+import android.os.UserHandle;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.view.ViewGroup;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.Flags;
import com.android.launcher3.Utilities;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.search.StringMatcherUtility;
import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.TestUtil;
import com.android.launcher3.views.BaseDragLayer;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.mockito.MockitoAnnotations;
/**
* Unit tests for testing modifyTitleToSupportMultiLine() in BubbleTextView.java
@@ -50,8 +63,12 @@
*/
public class BubbleTextViewTest {
+ @Rule public final SetFlagsRule mSetFlagsRule =
+ new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
private static final StringMatcherUtility.StringMatcher
MATCHER = StringMatcherUtility.StringMatcher.getInstance();
+ private static final UserHandle WORK_HANDLE = new UserHandle(13);
+ private static final int WORK_FLAG = 1;
private static final int ONE_LINE = 1;
private static final int TWO_LINE = 2;
private static final String TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT = "Battery Stats";
@@ -69,14 +86,20 @@
"LEGO®\nBuilder";
private static final String EMPTY_STRING = "";
private static final int CHAR_CNT = 7;
+ private static final int MAX_HEIGHT = Integer.MAX_VALUE;
+ private static final int LIMITED_HEIGHT = 357; /* allowedHeight in Pixel6 */
+ private static final float SPACE_MULTIPLIER = 1;
+ private static final float SPACE_EXTRA = 0;
private BubbleTextView mBubbleTextView;
private ItemInfoWithIcon mItemInfoWithIcon;
private Context mContext;
private int mLimitedWidth;
+ private AppInfo mGmailAppInfo;
@Before
public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
Utilities.enableRunningInTestHarnessForTests();
mContext = new ActivityContextWrapper(getApplicationContext());
mBubbleTextView = new BubbleTextView(mContext);
@@ -99,17 +122,23 @@
return null;
}
};
+ ComponentName componentName = new ComponentName(mContext,
+ "com.android.launcher3.tests.Activity" + "Gmail");
+ mGmailAppInfo = new AppInfo(componentName, "Gmail", WORK_HANDLE, new Intent());
}
@Test
public void testEmptyString_flagOn() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
mItemInfoWithIcon.title = EMPTY_STRING;
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertNotEquals(TWO_LINE, mBubbleTextView.getMaxLines());
} catch (Exception e) {
throw new RuntimeException(e);
@@ -118,13 +147,16 @@
@Test
public void testEmptyString_flagOff() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) {
mItemInfoWithIcon.title = EMPTY_STRING;
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
throw new RuntimeException(e);
@@ -133,14 +165,17 @@
@Test
public void testStringWithSpaceLongerThanCharLimit_flagOn() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
// test string: "Battery Stats"
mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(TWO_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
throw new RuntimeException(e);
@@ -149,14 +184,17 @@
@Test
public void testStringWithSpaceLongerThanCharLimit_flagOff() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) {
// test string: "Battery Stats"
mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
throw new RuntimeException(e);
@@ -165,14 +203,17 @@
@Test
public void testLongStringNoSpaceLongerThanCharLimit_flagOn() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
// test string: "flutterappflorafy"
mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
throw new RuntimeException(e);
@@ -181,81 +222,96 @@
@Test
public void testLongStringNoSpaceLongerThanCharLimit_flagOff() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) {
// test string: "flutterappflorafy"
mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
@Test
public void testLongStringWithSpaceLongerThanCharLimit_flagOn() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
// test string: "System UWB Field Test"
mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(TWO_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
@Test
public void testLongStringWithSpaceLongerThanCharLimit_flagOff() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) {
// test string: "System UWB Field Test"
mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
@Test
public void testLongStringSymbolLongerThanCharLimit_flagOn() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
// test string: "LEGO®Builder"
mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(TWO_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
@Test
public void testLongStringSymbolLongerThanCharLimit_flagOff() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) {
// test string: "LEGO®Builder"
mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
}
@@ -265,8 +321,11 @@
IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints(
TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER);
CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth,
+ MAX_HEIGHT,
TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(),
- breakPoints);
+ breakPoints,
+ SPACE_MULTIPLIER,
+ SPACE_EXTRA);
assertEquals(TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT_RESULT, newString);
}
@@ -275,9 +334,11 @@
// test string: "flutterappflorafy"
IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints(
TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER);
- CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth,
+ CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, 0,
TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(),
- breakPoints);
+ breakPoints,
+ SPACE_MULTIPLIER,
+ SPACE_EXTRA);
assertEquals(TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, newString);
}
@@ -287,8 +348,11 @@
IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints(
TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER);
CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth,
+ MAX_HEIGHT,
TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(),
- breakPoints);
+ breakPoints,
+ SPACE_MULTIPLIER,
+ SPACE_EXTRA);
assertEquals(TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT_RESULT, newString);
}
@@ -297,25 +361,93 @@
// test string: "LEGO®Builder"
IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints(
TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT, MATCHER);
- CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth,
+ CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(
+ mLimitedWidth,
+ MAX_HEIGHT,
TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(),
- breakPoints);
+ breakPoints,
+ SPACE_MULTIPLIER,
+ SPACE_EXTRA);
assertEquals(TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT_RESULT, newString);
}
@Test
- public void testEnsurePredictionRowIsOneLine() {
+ public void testEnsurePredictionRowIsTwoLine() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
// test string: "Battery Stats"
mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT;
mBubbleTextView.setDisplay(DISPLAY_PREDICTION_ROW);
mBubbleTextView.applyLabel(mItemInfoWithIcon);
mBubbleTextView.setTypeface(Typeface.MONOSPACE);
- mBubbleTextView.measure(mLimitedWidth, 0);
+ mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT);
+
mBubbleTextView.onPreDraw();
+
+ assertEquals(TWO_LINE, mBubbleTextView.getLineCount());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ public void modifyTitleToSupportMultiLine_whenLimitedHeight_shouldBeOneLine() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
+ try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
+ // test string: "LEGO®Builder"
+ mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT;
+ mBubbleTextView.applyLabel(mItemInfoWithIcon);
+ mBubbleTextView.setTypeface(Typeface.MONOSPACE);
+ mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT);
+
+ mBubbleTextView.onPreDraw();
+
assertEquals(ONE_LINE, mBubbleTextView.getLineCount());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
+
+ @Test
+ public void modifyTitleToSupportMultiLine_whenUnlimitedHeight_shouldBeTwoLine() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS);
+ try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) {
+ // test string: "LEGO®Builder"
+ mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT;
+ mBubbleTextView.setDisplay(DISPLAY_ALL_APPS);
+ mBubbleTextView.applyLabel(mItemInfoWithIcon);
+ mBubbleTextView.setTypeface(Typeface.MONOSPACE);
+ mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT);
+
+ mBubbleTextView.onPreDraw();
+
+ assertEquals(TWO_LINE, mBubbleTextView.getLineCount());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ public void applyIconAndLabel_whenDisplay_DISPLAY_SEARCH_RESULT_SMALL_noBadge() {
+ FlagOp op = FlagOp.NO_OP;
+ // apply the WORK bitmap flag to show work badge
+ mGmailAppInfo.bitmap.flags = op.apply(WORK_FLAG);
+ mBubbleTextView.setDisplay(DISPLAY_SEARCH_RESULT_SMALL);
+
+ mBubbleTextView.applyIconAndLabel(mGmailAppInfo);
+
+ assertThat(mBubbleTextView.getIcon().hasBadge()).isEqualTo(false);
+ }
+
+ @Test
+ public void applyIconAndLabel_whenDisplay_DISPLAY_SEARCH_RESULT_hasBadge() {
+ FlagOp op = FlagOp.NO_OP;
+ // apply the WORK bitmap flag to show work badge
+ mGmailAppInfo.bitmap.flags = op.apply(WORK_FLAG);
+ mBubbleTextView.setDisplay(DISPLAY_SEARCH_RESULT);
+
+ mBubbleTextView.applyIconAndLabel(mGmailAppInfo);
+
+ assertThat(mBubbleTextView.getIcon().hasBadge()).isEqualTo(true);
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index f0875f8..d94e4a5 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -4,6 +4,7 @@
import android.view.Surface;
import com.android.launcher3.tapl.TestHelpers;
+import com.android.launcher3.util.rule.TestStabilityRule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -30,8 +31,12 @@
@Override
public Statement apply(Statement base, Description description) {
- if (!TestHelpers.isInLauncherProcess() ||
- description.getAnnotation(PortraitLandscape.class) == null) {
+ if (!TestHelpers.isInLauncherProcess()
+ || description.getAnnotation(PortraitLandscape.class) == null
+ // If running in presubmit, don't run in both orientations.
+ // It's important to keep presubmits fast even if we will occasionally miss
+ // regressions in presubmit.
+ || TestStabilityRule.isPresubmit()) {
return base;
}
@@ -67,7 +72,7 @@
private void evaluateInPortrait() throws Throwable {
mTest.mDevice.setOrientationNatural();
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_0);
- AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher);
+ AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher, true);
base.evaluate();
mTest.getDevice().pressHome();
}
@@ -75,7 +80,7 @@
private void evaluateInLandscape() throws Throwable {
mTest.mDevice.setOrientationLeft();
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_90);
- AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher);
+ AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher, true);
base.evaluate();
mTest.getDevice().pressHome();
}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 45b01f4..f2cbd92 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -16,82 +16,21 @@
package com.android.launcher3.ui;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-import android.content.Intent;
-import android.graphics.Point;
-import android.os.SystemClock;
-import android.platform.test.annotations.PlatinumTest;
-import android.util.Log;
-
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.LargeTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.popup.ArrowPopup;
-import com.android.launcher3.tapl.AllApps;
-import com.android.launcher3.tapl.AppIcon;
-import com.android.launcher3.tapl.AppIconMenu;
-import com.android.launcher3.tapl.AppIconMenuItem;
-import com.android.launcher3.tapl.Folder;
-import com.android.launcher3.tapl.FolderIcon;
-import com.android.launcher3.tapl.HomeAllApps;
-import com.android.launcher3.tapl.HomeAppIcon;
-import com.android.launcher3.tapl.HomeAppIconMenuItem;
-import com.android.launcher3.tapl.Widgets;
-import com.android.launcher3.tapl.Workspace;
-import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
-import com.android.launcher3.util.LauncherLayoutBuilder;
-import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.Wait;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
-import com.android.launcher3.util.rule.TISBindRule;
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
-import com.android.launcher3.widget.picker.WidgetsFullSheet;
-import com.android.launcher3.widget.picker.WidgetsRecyclerView;
-import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
-import java.util.Map;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
- private static final String APP_NAME = "LauncherTestApp";
- private static final String DUMMY_APP_NAME = "Aardwolf";
- private static final String MAPS_APP_NAME = "Maps";
- private static final String STORE_APP_NAME = "Play Store";
- private static final String GMAIL_APP_NAME = "Gmail";
- private static final String READ_DEVICE_CONFIG_PERMISSION =
- "android.permission.READ_DEVICE_CONFIG";
-
- @Rule
- public TISBindRule mTISBindRule = new TISBindRule();
-
- private AutoCloseable mLauncherLayout;
@Before
public void setUp() throws Exception {
@@ -113,14 +52,7 @@
test.waitForResumed("Launcher internal state is still Background");
// Check that we switched to home.
test.mLauncher.getWorkspace();
- AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher);
- }
-
- @After
- public void tearDown() throws Exception {
- if (mLauncherLayout != null) {
- mLauncherLayout.close();
- }
+ AbstractLauncherUiTest.checkDetectedLeaks(test.mLauncher, true);
}
// Please don't add negative test cases for methods that fail only after a long wait.
@@ -134,18 +66,6 @@
assertTrue(message, failed);
}
- public static boolean isWorkspaceScrollable(Launcher launcher) {
- return launcher.getWorkspace().getPageCount() > launcher.getWorkspace().getPanelCount();
- }
-
- private int getCurrentWorkspacePage(Launcher launcher) {
- return launcher.getWorkspace().getCurrentPage();
- }
-
- private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
- return WidgetsFullSheet.getWidgetsView(launcher);
- }
-
@Test
public void testDevicePressMenu() throws Exception {
mDevice.pressMenu();
@@ -156,583 +76,4 @@
// Check that pressHome works when the menu is shown.
mLauncher.goHome();
}
-
- @Test
- public void testPressHomeOnAllAppsContextMenu() throws Exception {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon("TestActivity7").openMenu();
- } finally {
- allApps.unfreeze();
- }
- mLauncher.goHome();
- }
-
- public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
- allApps.freeze();
- try {
- assertNotNull("allApps parameter is null", allApps);
-
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
-
- // Test flinging forward and backward.
- test.executeOnLauncher(launcher -> assertEquals(
- "All Apps started in already scrolled state", 0,
- test.getAllAppsScroll(launcher)));
-
- allApps.flingForward();
- assertTrue("Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- final Integer flingForwardY = test.getFromLauncher(
- launcher -> test.getAllAppsScroll(launcher));
- test.executeOnLauncher(
- launcher -> assertTrue("flingForward() didn't scroll App Apps",
- flingForwardY > 0));
-
- allApps.flingBackward();
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- final Integer flingBackwardY = test.getFromLauncher(
- launcher -> test.getAllAppsScroll(launcher));
- test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
- flingBackwardY < flingForwardY));
-
- // Test scrolling down to YouTube.
- assertNotNull("All apps: can't find YouTube", allApps.getAppIcon("YouTube"));
- // Test scrolling up to Camera.
- assertNotNull("All apps: can't find Camera", allApps.getAppIcon("Camera"));
- // Test failing to find a non-existing app.
- final AllApps allAppsFinal = allApps;
- expectFail("All apps: could find a non-existing app",
- () -> allAppsFinal.getAppIcon("NO APP"));
-
- assertTrue(
- "Launcher internal state is not All Apps",
- test.isInState(() -> LauncherState.ALL_APPS));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testWorkspaceSwitchToAllApps() {
- assertNotNull("switchToAllApps() returned null",
- mLauncher.getWorkspace().switchToAllApps());
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsSwitchToWorkspace() {
- assertNotNull("switchToWorkspace() returned null",
- mLauncher.getWorkspace().switchToAllApps()
- .switchToWorkspace(/* swipeDown= */ true));
- assertTrue("Launcher internal state is not Workspace",
- isInState(() -> LauncherState.NORMAL));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsSwipeUpToWorkspace() {
- assertNotNull("testAllAppsSwipeUpToWorkspace() returned null",
- mLauncher.getWorkspace().switchToAllApps()
- .switchToWorkspace(/* swipeDown= */ false));
- assertTrue("Launcher internal state is not Workspace",
- isInState(() -> LauncherState.NORMAL));
- }
-
- @Test
- @PortraitLandscape
- public void testAllAppsDeadzoneForTablet() throws Exception {
- assumeTrue(mLauncher.isTablet());
-
- mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
- true /* tapRight */);
- mLauncher.getWorkspace().switchToAllApps().dismissByTappingOutsideForTablet(
- false /* tapRight */);
- }
-
- @PlatinumTest(focusArea = "launcher")
- @Test
- @ScreenRecord // b/202433017
- public void testWorkspace() throws Exception {
- // Set workspace that includes the chrome Activity app icon on the hotseat.
- LauncherLayoutBuilder builder = new LauncherLayoutBuilder()
- .atHotseat(0).putApp("com.android.chrome", "com.google.android.apps.chrome.Main");
- mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, builder);
- reinitializeLauncherData();
-
- final Workspace workspace = mLauncher.getWorkspace();
-
- // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
- executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
- isWorkspaceScrollable(launcher)));
- assertEquals("Initial workspace doesn't have the correct page", workspace.pagesPerScreen(),
- workspace.getPageCount());
- workspace.verifyWorkspaceAppIconIsGone("Chrome app was found on empty workspace", "Chrome");
- workspace.ensureWorkspaceIsScrollable();
-
- executeOnLauncher(
- launcher -> assertEquals(
- "Ensuring workspace scrollable didn't switch to next screen",
- workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
- executeOnLauncher(
- launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
- isWorkspaceScrollable(launcher)));
- assertNotNull("ensureScrollable didn't add Chrome app",
- workspace.getWorkspaceAppIcon("Chrome"));
-
- // Test flinging workspace.
- workspace.flingBackward();
- assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
- executeOnLauncher(
- launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
- 0, getCurrentWorkspacePage(launcher)));
-
- workspace.flingForward();
- executeOnLauncher(
- launcher -> assertEquals("Flinging forward didn't switch workspace to next screen",
- workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
- assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
-
- // Test starting a workspace app.
- final HomeAppIcon app = workspace.getWorkspaceAppIcon("Chrome");
- assertNotNull("No Chrome app in workspace", app);
- }
-
- public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
- allApps.freeze();
- try {
- final AppIcon app = allApps.getAppIcon("TestActivity7");
- assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName()));
- test.executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the "
- + "top one",
- test.isInLaunchedApp(launcher)));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- assertTrue("Launcher internal state is not All Apps",
- isInState(() -> LauncherState.ALL_APPS));
-
- runIconLaunchFromAllAppsTest(this, allApps);
- }
-
- @Test
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/293191790
- @ScreenRecord
- @PortraitLandscape
- public void testWidgets() throws Exception {
- // Test opening widgets.
- executeOnLauncher(launcher ->
- assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
- Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
- assertNotNull("openAllWidgets() returned null", widgets);
- widgets = mLauncher.getAllWidgets();
- assertNotNull("getAllWidgets() returned null", widgets);
- executeOnLauncher(launcher ->
- assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
- executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
- 0, getWidgetsScroll(launcher)));
-
- // Test flinging widgets.
- widgets.flingForward();
- Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
- executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
- flingForwardY > 0));
-
- widgets.flingBackward();
- executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
- getWidgetsScroll(launcher) < flingForwardY));
-
- mLauncher.goHome();
- waitForLauncherCondition("Widgets were not closed",
- launcher -> getWidgetsView(launcher) == null);
- }
-
- private int getWidgetsScroll(Launcher launcher) {
- return getWidgetsView(launcher).computeVerticalScrollOffset();
- }
-
- private boolean isOptionsPopupVisible(Launcher launcher) {
- final ArrowPopup<?> popup = launcher.getOptionsPopup();
- return popup != null && popup.isShown();
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testLaunchMenuItem() throws Exception {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- final AppIconMenu menu = allApps.
- getAppIcon(APP_NAME).
- openDeepShortcutMenu();
-
- executeOnLauncher(
- launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
- isOptionsPopupVisible(launcher)));
-
- final AppIconMenuItem menuItem = menu.getMenuItem(1);
- assertEquals("Wrong menu item", "Shortcut 2", menuItem.getText());
- menuItem.launch(getAppPackageName());
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- public void testLaunchHomeScreenMenuItem() {
- // Drag the test app icon to home screen and open short cut menu from the icon
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
- final AppIconMenu menu = mLauncher.getWorkspace().getWorkspaceAppIcon(
- APP_NAME).openDeepShortcutMenu();
-
- executeOnLauncher(
- launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
- isOptionsPopupVisible(launcher)));
-
- final AppIconMenuItem menuItem = menu.getMenuItem(1);
- assertEquals("Wrong menu item", "Shortcut 2", menuItem.getText());
- menuItem.launch(getAppPackageName());
- } finally {
- allApps.unfreeze();
- }
- }
-
- @PlatinumTest(focusArea = "launcher")
- @Test
- @PortraitLandscape
- @ScreenRecord // b/256898879
- public void testDragAppIcon() throws Throwable {
- // 1. Open all apps and wait for load complete.
- // 2. Drag icon to homescreen.
- // 3. Verify that the icon works on homescreen.
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
- mLauncher.getWorkspace().getWorkspaceAppIcon(APP_NAME).launch(getAppPackageName());
- } finally {
- allApps.unfreeze();
- }
- executeOnLauncher(launcher -> assertTrue(
- "Launcher activity is the top activity; expecting another activity to be the top "
- + "one",
- isInLaunchedApp(launcher)));
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testDragShortcut() throws Throwable {
- // 1. Open all apps and wait for load complete.
- // 2. Find the app and long press it to show shortcuts.
- // 3. Press icon center until shortcuts appear
- final HomeAllApps allApps = mLauncher
- .getWorkspace()
- .switchToAllApps();
- allApps.freeze();
- try {
- final HomeAppIconMenuItem menuItem = allApps
- .getAppIcon(APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem(0);
- final String actualShortcutName = menuItem.getText();
- final String expectedShortcutName = "Shortcut 1";
-
- assertEquals(expectedShortcutName, actualShortcutName);
- menuItem.dragToWorkspace(false, false);
- mLauncher.getWorkspace().getWorkspaceAppIcon(expectedShortcutName)
- .launch(getAppPackageName());
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- @PortraitLandscape
- @ScreenRecord
- @Ignore // b/233075289
- @PlatinumTest(focusArea = "launcher")
- public void testDragToFolder() {
- // TODO: add the use case to drag an icon to an existing folder. Currently it either fails
- // on tablets or phones due to difference in resolution.
- final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1);
- final HomeAppIcon gmailIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
-
- FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
- Folder folder = folderIcon.open();
- folder.getAppIcon(STORE_APP_NAME);
- folder.getAppIcon(GMAIL_APP_NAME);
- Workspace workspace = folder.close();
-
- workspace.verifyWorkspaceAppIconIsGone(STORE_APP_NAME + " should be moved to a folder.",
- STORE_APP_NAME);
- workspace.verifyWorkspaceAppIconIsGone(GMAIL_APP_NAME + " should be moved to a folder.",
- GMAIL_APP_NAME);
-
- final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
- folderIcon = mapIcon.dragToIcon(folderIcon);
- folder = folderIcon.open();
- folder.getAppIcon(MAPS_APP_NAME);
- workspace = folder.close();
-
- workspace.verifyWorkspaceAppIconIsGone(MAPS_APP_NAME + " should be moved to a folder.",
- MAPS_APP_NAME);
- }
-
- @FlakyTest(bugId = 256615483)
- @Test
- @PortraitLandscape
- public void testPressBack() throws Exception {
- InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
- READ_DEVICE_CONFIG_PERMISSION);
- assumeFalse(FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get());
- mLauncher.getWorkspace().switchToAllApps();
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testDragAndCancelAppIcon() {
- final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
- Point positionBeforeDrag =
- mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
- assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag);
-
- mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon);
-
- Point positionAfterDrag =
- mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME);
- assertNotNull("App not found in Workspace after dragging.", positionAfterDrag);
- assertEquals("App not returned to same position in Workspace after drag & cancel",
- positionBeforeDrag, positionAfterDrag);
- }
-
- @Test
- @PortraitLandscape
- public void testDeleteFromWorkspace() throws Exception {
- // test delete both built-in apps and user-installed app from workspace
- for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
- final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(appName);
- Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
- workspace.verifyWorkspaceAppIconIsGone(
- appName + " app was found after being deleted from workspace",
- appName);
- }
- }
-
- private void verifyAppUninstalledFromAllApps(Workspace workspace, String appName) {
- final HomeAllApps allApps = workspace.switchToAllApps();
- Wait.atMost(appName + " app was found on all apps after being uninstalled",
- () -> allApps.tryGetAppIcon(appName) == null,
- DEFAULT_UI_TIMEOUT, mLauncher);
- }
-
- @Test
- @PortraitLandscape
- // TODO(b/293944634): Remove Screenrecord after flaky debug, and add
- // @PlatinumTest(focusArea = "launcher") back
- @ScreenRecord
- public void testUninstallFromWorkspace() throws Exception {
- installDummyAppAndWaitForUIUpdate();
- try {
- verifyAppUninstalledFromAllApps(
- createShortcutInCenterIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testUninstallFromAllApps() throws Exception {
- installDummyAppAndWaitForUIUpdate();
- try {
- Workspace workspace = mLauncher.getWorkspace();
- final HomeAllApps allApps = workspace.switchToAllApps();
- workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
- verifyAppUninstalledFromAllApps(workspace, DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testDragAppIconToWorkspaceCell() throws Exception {
- long startTime, endTime, elapsedTime;
- Point[] targets = getCornersAndCenterPositions();
-
- for (Point target : targets) {
- startTime = SystemClock.uptimeMillis();
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
- } finally {
- allApps.unfreeze();
- }
- // Reset the workspace for the next shortcut creation.
- initialize(this, true);
- endTime = SystemClock.uptimeMillis();
- elapsedTime = endTime - startTime;
- Log.d("testDragAppIconToWorkspaceCellTime",
- "Milliseconds taken to drag app icon to workspace cell: " + elapsedTime);
- }
-
- // test to move a shortcut to other cell.
- final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
- for (Point target : targets) {
- startTime = SystemClock.uptimeMillis();
- launcherTestAppIcon.dragToWorkspace(target.x, target.y);
- endTime = SystemClock.uptimeMillis();
- elapsedTime = endTime - startTime;
- Log.d("testDragAppIconToWorkspaceCellTime",
- "Milliseconds taken to move shortcut to other cell: " + elapsedTime);
- }
- }
-
- /**
- * Adds three icons to the workspace and removes one of them by dragging to uninstall.
- */
- @Test
- @ScreenRecord // b/241821721
- @PlatinumTest(focusArea = "launcher")
- public void uninstallWorkspaceIcon() throws IOException {
- Point[] gridPositions = getCornersAndCenterPositions();
- StringBuilder sb = new StringBuilder();
- for (Point p : gridPositions) {
- sb.append(p).append(", ");
- }
- Log.d(ICON_MISSING, "allGridPositions: " + sb);
- createShortcutIfNotExist(STORE_APP_NAME, gridPositions[0]);
- createShortcutIfNotExist(MAPS_APP_NAME, gridPositions[1]);
- installDummyAppAndWaitForUIUpdate();
- try {
- createShortcutIfNotExist(DUMMY_APP_NAME, gridPositions[2]);
- Map<String, Point> initialPositions =
- mLauncher.getWorkspace().getWorkspaceIconsPositions();
- assertThat(initialPositions.keySet())
- .containsAtLeast(DUMMY_APP_NAME, MAPS_APP_NAME, STORE_APP_NAME);
-
- mLauncher.getWorkspace().getWorkspaceAppIcon(DUMMY_APP_NAME).uninstall();
- mLauncher.getWorkspace().verifyWorkspaceAppIconIsGone(
- DUMMY_APP_NAME + " was expected to disappear after uninstall.", DUMMY_APP_NAME);
-
- // Debug for b/288944469 I want to test if we are not waiting enough after removing
- // the icon to request the list of icons again, since the items are not removed
- // immediately. This should reduce the flake rate
- SystemClock.sleep(500);
- Map<String, Point> finalPositions =
- mLauncher.getWorkspace().getWorkspaceIconsPositions();
- assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- @Test
- @PortraitLandscape
- @PlatinumTest(focusArea = "launcher")
- public void testDragShortcutToWorkspaceCell() throws Exception {
- Point[] targets = getCornersAndCenterPositions();
-
- for (Point target : targets) {
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem(0)
- .dragToWorkspace(target.x, target.y);
- } finally {
- allApps.unfreeze();
- }
- }
- }
-
- @Test
- @PortraitLandscape
- public void testAddDeleteShortcutOnHotseat() {
- mLauncher.getWorkspace()
- .deleteAppIcon(mLauncher.getWorkspace().getHotseatAppIcon(0))
- .switchToAllApps()
- .getAppIcon(APP_NAME)
- .dragToHotseat(0);
- mLauncher.getWorkspace().deleteAppIcon(
- mLauncher.getWorkspace().getHotseatAppIcon(APP_NAME));
- }
-
- private void installDummyAppAndWaitForUIUpdate() throws IOException {
- TestUtil.installDummyApp();
- waitForLauncherUIUpdate();
- }
-
- private void waitForLauncherUIUpdate() {
- // Wait for model thread completion as it may be processing
- // the install event from the SystemService
- mLauncher.waitForModelQueueCleared();
- // Wait for Launcher UI thread completion, as it may be processing updating the UI in
- // response to the model update. Not that `waitForLauncherInitialized` is just a proxy
- // method, we can use any method which touches Launcher UI thread,
- mLauncher.waitForLauncherInitialized();
- }
-
- /**
- * @return List of workspace grid coordinates. Those are not pixels. See {@link
- * Workspace#getIconGridDimensions()}
- */
- private Point[] getCornersAndCenterPositions() {
- final Point dimensions = mLauncher.getWorkspace().getIconGridDimensions();
- return new Point[]{
- new Point(0, 1),
- new Point(0, dimensions.y - 2),
- new Point(dimensions.x - 1, 1),
- new Point(dimensions.x - 1, dimensions.y - 2),
- new Point(dimensions.x / 2, dimensions.y / 2)
- };
- }
-
- public static String getAppPackageName() {
- return getInstrumentation().getContext().getPackageName();
- }
-
- @Test
- public void testGetAppIconName() {
- HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- // getAppIcon() already verifies that the icon is not null and is the correct icon name.
- allApps.getAppIcon(APP_NAME);
- } finally {
- allApps.unfreeze();
- }
- }
}
diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index 5b9adcd..485ef94 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -15,12 +15,11 @@
*/
package com.android.launcher3.ui;
+import static com.android.launcher3.LauncherPrefs.WORK_EDU_STEP;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
import static com.android.launcher3.util.TestUtil.installDummyAppForUser;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -31,6 +30,7 @@
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.AllAppsPagedView;
@@ -39,7 +39,6 @@
import com.android.launcher3.allapps.WorkProfileManager;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.util.TestUtil;
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
import org.junit.After;
import org.junit.Before;
@@ -92,8 +91,8 @@
@After
public void removeWorkProfile() throws Exception {
- executeOnLauncher(launcher -> {
- if (launcher == null || launcher.getAppsView() == null) {
+ executeOnLauncherInTearDown(launcher -> {
+ if (launcher.getAppsView() == null) {
return;
}
launcher.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
@@ -103,8 +102,6 @@
}
private void waitForWorkTabSetup() {
- // Added for b/243688989 flake to determine if we really are in allApps or not at this point
- mLauncher.getAllApps();
waitForLauncherCondition("Work tab not setup", launcher -> {
if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
@@ -115,7 +112,6 @@
}
@Test
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/243688989
public void workTabExists() {
assumeTrue(mWorkProfileSetupSuccessful);
waitForWorkTabSetup();
@@ -176,12 +172,11 @@
}
@Test
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/243688989
public void testEdu() {
assumeTrue(mWorkProfileSetupSuccessful);
waitForWorkTabSetup();
executeOnLauncher(l -> {
- l.getSharedPrefs().edit().putInt(WorkProfileManager.KEY_WORK_EDU_STEP, 0).commit();
+ LauncherPrefs.get(l).putSync(WORK_EDU_STEP.to(0));
((AllAppsPagedView) l.getAppsView().getContentView()).setCurrentPage(WORK_PAGE);
l.getAppsView().getWorkManager().reset();
});
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 9dca24b..fd4b7f1 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.ui.widget;
-import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
-
import static org.junit.Assert.assertNotNull;
import android.platform.test.annotations.PlatinumTest;
@@ -96,4 +94,27 @@
mLauncher.getWorkspace().getWorkspaceAppIcon("Shortcut")
.launch(getAppPackageName());
}
+
+ /**
+ * Test dragging a widget to the workspace and resize it.
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testResizeWidget() throws Throwable {
+ new FavoriteItemsTransaction(mTargetContext).commitAndLoadHome(mLauncher);
+
+ waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading());
+
+ final LauncherAppWidgetProviderInfo widgetInfo =
+ TestViewHelpers.findWidgetProvider(false /* hasConfigureScreen */);
+
+ WidgetResizeFrame resizeFrame = mLauncher
+ .getWorkspace()
+ .openAllWidgets()
+ .getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager()))
+ .dragWidgetToWorkspace();
+
+ assertNotNull("Widget resize frame not shown after widget add", resizeFrame);
+ resizeFrame.resize();
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index a6b5369..5c753f9 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -48,7 +48,6 @@
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.Wait.Condition;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.ShellCommandRule;
import org.junit.Before;
@@ -85,7 +84,6 @@
public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetNoConfig() throws Throwable {
runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
@@ -94,7 +92,6 @@
}
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetNoConfig_customPreview() throws Throwable {
// Command to set custom preview
Intent command = RequestPinItemActivity.getCommandIntent(
@@ -108,7 +105,6 @@
}
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetWithConfig() throws Throwable {
runTest("pinWidgetWithConfig", true,
(info, view) -> info instanceof LauncherAppWidgetInfo &&
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
new file mode 100644
index 0000000..a5e9868
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.ui.widget;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.tapl.Widgets;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.util.rule.TestStabilityRule.Stability;
+import com.android.launcher3.widget.picker.WidgetsFullSheet;
+import com.android.launcher3.widget.picker.WidgetsRecyclerView;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This test run in both Out of process (Oop) and in-process (Ipc).
+ * Make sure the basic interactions with the WidgetPicker works.
+ */
+public class TaplWidgetPickerTest extends AbstractLauncherUiTest {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
+ return WidgetsFullSheet.getWidgetsView(launcher);
+ }
+
+ private int getWidgetsScroll(Launcher launcher) {
+ return getWidgetsView(launcher).computeVerticalScrollOffset();
+ }
+
+ /**
+ * Open Widget picker, make sure the widget picker can scroll and then go to home screen.
+ */
+ @Test
+ @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/293191790
+ @ScreenRecord
+ @PortraitLandscape
+ public void testWidgets() {
+ // Test opening widgets.
+ executeOnLauncher(launcher ->
+ assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
+ Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
+ assertNotNull("openAllWidgets() returned null", widgets);
+ widgets = mLauncher.getAllWidgets();
+ assertNotNull("getAllWidgets() returned null", widgets);
+ executeOnLauncher(launcher ->
+ assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
+ executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
+ 0, getWidgetsScroll(launcher)));
+
+ // Test flinging widgets.
+ widgets.flingForward();
+ Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
+ executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
+ flingForwardY > 0));
+
+ widgets.flingBackward();
+ executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
+ getWidgetsScroll(launcher) < flingForwardY));
+
+ mLauncher.goHome();
+ waitForLauncherCondition("Widgets were not closed",
+ launcher -> getWidgetsView(launcher) == null);
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
new file mode 100644
index 0000000..d776f21
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.ui.workspace;
+
+import static com.android.launcher3.ui.TaplTestsLauncher3.initialize;
+import static com.android.launcher3.util.TestConstants.AppNames.CHROME_APP_NAME;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.PlatinumTest;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.HomeAppIcon;
+import com.android.launcher3.tapl.Workspace;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.util.LauncherLayoutBuilder;
+import com.android.launcher3.util.TestUtil;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test the basic interactions of the Workspace, adding pages, moving the pages and removing pages.
+ */
+public class TaplWorkspaceTest extends AbstractLauncherUiTest {
+
+ private AutoCloseable mLauncherLayout;
+
+ private static boolean isWorkspaceScrollable(Launcher launcher) {
+ return launcher.getWorkspace().getPageCount() > launcher.getWorkspace().getPanelCount();
+ }
+
+ private int getCurrentWorkspacePage(Launcher launcher) {
+ return launcher.getWorkspace().getCurrentPage();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ initialize(this);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mLauncherLayout != null) {
+ mLauncherLayout.close();
+ }
+ }
+
+ /**
+ * Add an icon and add a page to ensure the Workspace is scrollable and also make sure we can
+ * move between workspaces. After, make sure we can launch an app from the Workspace.
+ * @throws Exception if we can't set the defaults icons that will appear at the beginning.
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testWorkspace() throws Exception {
+ // Set workspace that includes the chrome Activity app icon on the hotseat.
+ LauncherLayoutBuilder builder = new LauncherLayoutBuilder()
+ .atHotseat(0).putApp("com.android.chrome", "com.google.android.apps.chrome.Main");
+ mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, builder);
+ reinitializeLauncherData();
+
+ final Workspace workspace = mLauncher.getWorkspace();
+
+ // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
+ executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
+ isWorkspaceScrollable(launcher)));
+ assertEquals("Initial workspace doesn't have the correct page", workspace.pagesPerScreen(),
+ workspace.getPageCount());
+ workspace.verifyWorkspaceAppIconIsGone("Chrome app was found on empty workspace",
+ CHROME_APP_NAME);
+ workspace.ensureWorkspaceIsScrollable();
+
+ executeOnLauncher(
+ launcher -> assertEquals(
+ "Ensuring workspace scrollable didn't switch to next screen",
+ workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
+ executeOnLauncher(
+ launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
+ isWorkspaceScrollable(launcher)));
+ assertNotNull("ensureScrollable didn't add Chrome app",
+ workspace.getWorkspaceAppIcon(CHROME_APP_NAME));
+
+ // Test flinging workspace.
+ workspace.flingBackward();
+ assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
+ executeOnLauncher(
+ launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
+ 0, getCurrentWorkspacePage(launcher)));
+
+ workspace.flingForward();
+ executeOnLauncher(
+ launcher -> assertEquals("Flinging forward didn't switch workspace to next screen",
+ workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
+ assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
+
+ // Test starting a workspace app.
+ final HomeAppIcon app = workspace.getWorkspaceAppIcon(CHROME_APP_NAME);
+ assertNotNull("No Chrome app in workspace", app);
+ }
+
+
+ /**
+ * Similar to {@link TaplWorkspaceTest#testWorkspace} but here we also make sure we can delete
+ * the pages.
+ */
+ @PlatinumTest(focusArea = "launcher")
+ @Test
+ public void testAddAndDeletePageAndFling() {
+ Workspace workspace = mLauncher.getWorkspace();
+ // Get the first app from the hotseat
+ HomeAppIcon hotSeatIcon = workspace.getHotseatAppIcon(0);
+ String appName = hotSeatIcon.getIconName();
+
+ // Add one page by dragging app to page 1.
+ workspace.dragIcon(hotSeatIcon, workspace.pagesPerScreen());
+ assertEquals("Incorrect Page count Number",
+ workspace.pagesPerScreen() * 2,
+ workspace.getPageCount());
+
+ // Delete one page by dragging app to hot seat.
+ workspace.getWorkspaceAppIcon(appName).dragToHotseat(0);
+
+ // Refresh workspace to avoid using stale container error.
+ workspace = mLauncher.getWorkspace();
+ assertEquals("Incorrect Page count Number",
+ workspace.pagesPerScreen(),
+ workspace.getPageCount());
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
index 8e5e9cc..34c7707 100644
--- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.ui.workspace;
+import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -51,7 +53,6 @@
public class ThemeIconsTest extends AbstractLauncherUiTest {
private static final String APP_NAME = "IconThemedActivity";
- private static final String SHORTCUT_APP_NAME = "LauncherTestApp";
private static final String SHORTCUT_NAME = "Shortcut 1";
@Test
@@ -81,7 +82,7 @@
allApps.freeze();
try {
- HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME);
+ HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME);
HomeAppIconMenuItem shortcutItem =
(HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME);
shortcutItem.dragToWorkspace(false, false);
@@ -118,7 +119,7 @@
allApps.freeze();
try {
- HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME);
+ HomeAppIcon icon = allApps.getAppIcon(TEST_APP_NAME);
HomeAppIconMenuItem shortcutItem =
(HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME);
shortcutItem.dragToWorkspace(false, false);
diff --git a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
index 62a8179..35b4883 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
@@ -16,6 +16,11 @@
package com.android.launcher3.ui.workspace;
+import static com.android.launcher3.util.TestConstants.AppNames.CHROME_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.MESSAGES_APP_NAME;
+import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -76,14 +81,14 @@
executeOnLauncher(launcher -> {
launcher.enableHotseatEdu(false);
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
});
}
@After
public void tearDown() throws Exception {
- executeOnLauncher(launcher -> launcher.enableHotseatEdu(true));
+ executeOnLauncherInTearDown(launcher -> launcher.enableHotseatEdu(true));
if (mLauncherLayout != null) {
mLauncherLayout.close();
}
@@ -94,12 +99,12 @@
public void testDragIconToRightPanel() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Maps", "Play Store");
- assertItemsOnPage(launcher, 1, "Chrome");
+ assertItemsOnPage(launcher, 0, MAPS_APP_NAME, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, CHROME_APP_NAME);
});
}
@@ -108,52 +113,52 @@
public void testSinglePageDragIconWhenMultiplePageScrollingIsPossible() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 2);
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), -2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Chrome", "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
+ assertItemsOnPage(launcher, 0, CHROME_APP_NAME, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
});
}
@@ -162,13 +167,13 @@
public void testDragIconToPage2() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
+ assertItemsOnPage(launcher, 2, MAPS_APP_NAME);
assertPageEmpty(launcher, 3);
});
}
@@ -179,14 +184,14 @@
Workspace workspace = mLauncher.getWorkspace();
// b/299522368 sometimes the phone app is not present in the hotseat.
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 3);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
}
@@ -195,44 +200,44 @@
public void testMultiplePageDragIcon() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(MESSAGES_APP_NAME), 2);
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 5);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 5);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Messages");
+ assertItemsOnPage(launcher, 2, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), 4);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MESSAGES_APP_NAME), 4);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5, 6, 7);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- assertItemsOnPage(launcher, 6, "Messages");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 6, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 7);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), -3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MESSAGES_APP_NAME), -3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Messages");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MESSAGES_APP_NAME);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
+ assertItemsOnPage(launcher, 5, MAPS_APP_NAME);
});
}
@@ -241,38 +246,38 @@
public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 0);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 3);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 0);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
+ assertItemsOnPage(launcher, 3, MAPS_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), -1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
- assertItemsOnPage(launcher, 2, "Chrome");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 2, CHROME_APP_NAME);
assertPageEmpty(launcher, 3);
});
// Move Chrome to the right panel as well, to make sure pages are not deleted whichever
// page is the empty one
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 1, MAPS_APP_NAME);
assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
}
@@ -281,25 +286,25 @@
public void testEmptyPagesGetRemovedIfBothPagesAreEmpty() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(STORE_APP_NAME), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(CHROME_APP_NAME), 1);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Maps");
+ assertItemsOnPage(launcher, 0, MAPS_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Play Store");
- assertItemsOnPage(launcher, 3, "Chrome");
+ assertItemsOnPage(launcher, 2, STORE_APP_NAME);
+ assertItemsOnPage(launcher, 3, CHROME_APP_NAME);
});
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -1);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(CHROME_APP_NAME), -1);
workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), -2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(STORE_APP_NAME), -2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
- assertItemsOnPage(launcher, 1, "Chrome");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 1, CHROME_APP_NAME);
});
}
@@ -308,28 +313,28 @@
public void testMiddleEmptyPagesGetRemoved() {
Workspace workspace = mLauncher.getWorkspace();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 3);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
+ workspace.dragIcon(workspace.getHotseatAppIcon(MESSAGES_APP_NAME), 3);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
+ assertItemsOnPage(launcher, 2, MAPS_APP_NAME);
assertPageEmpty(launcher, 3);
assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Messages");
+ assertItemsOnPage(launcher, 5, MESSAGES_APP_NAME);
});
workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
+ workspace.dragIcon(workspace.getWorkspaceAppIcon(MAPS_APP_NAME), 2);
executeOnLauncher(launcher -> {
assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
+ assertItemsOnPage(launcher, 0, STORE_APP_NAME);
assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 4, "Maps");
- assertItemsOnPage(launcher, 5, "Messages");
+ assertItemsOnPage(launcher, 4, MAPS_APP_NAME);
+ assertItemsOnPage(launcher, 5, MESSAGES_APP_NAME);
});
}
diff --git a/tests/src/com/android/launcher3/util/CellContentDimensionsTest.kt b/tests/src/com/android/launcher3/util/CellContentDimensionsTest.kt
new file mode 100644
index 0000000..4770546
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/CellContentDimensionsTest.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util
+
+import android.content.Context
+import android.content.res.Configuration
+import android.util.DisplayMetrics
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CellContentDimensionsTest {
+ private var context: Context? = null
+ private val runningContext: Context = ApplicationProvider.getApplicationContext()
+ private lateinit var iconSizeSteps: IconSizeSteps
+
+ @Before
+ fun setup() {
+ // 160dp makes 1px = 1dp
+ val config =
+ Configuration(runningContext.resources.configuration).apply {
+ this.densityDpi = DisplayMetrics.DENSITY_DEFAULT
+ }
+ context = runningContext.createConfigurationContext(config)
+ iconSizeSteps = IconSizeSteps(context!!.resources)
+ }
+
+ @Test
+ fun dimensionsFitTheCell() {
+ val cellSize = Pair(80, 104)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(93)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(66)
+ assertThat(iconDrawablePaddingPx).isEqualTo(8)
+ assertThat(iconTextSizePx).isEqualTo(14)
+ }
+ }
+
+ @Test
+ fun decreasePadding() {
+ val cellSize = Pair(67, 87)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(87)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(66)
+ assertThat(iconDrawablePaddingPx).isEqualTo(2)
+ assertThat(iconTextSizePx).isEqualTo(14)
+ }
+ }
+
+ @Test
+ fun decreaseIcon() {
+ val cellSize = Pair(65, 84)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(82)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(63)
+ assertThat(iconDrawablePaddingPx).isEqualTo(0)
+ assertThat(iconTextSizePx).isEqualTo(14)
+ }
+ }
+
+ @Test
+ fun decreaseText() {
+ val cellSize = Pair(63, 81)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(81)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(63)
+ assertThat(iconDrawablePaddingPx).isEqualTo(0)
+ assertThat(iconTextSizePx).isEqualTo(13)
+ }
+ }
+
+ @Test
+ fun decreaseIconAndTextTwoSteps() {
+ val cellSize = Pair(60, 78)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(77)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(61)
+ assertThat(iconDrawablePaddingPx).isEqualTo(0)
+ assertThat(iconTextSizePx).isEqualTo(12)
+ }
+ }
+
+ @Test
+ fun decreaseIconAndTextToMinimum() {
+ val cellSize = Pair(52, 63)
+ val cellContentDimensions =
+ CellContentDimensions(iconSizePx = 66, iconDrawablePaddingPx = 8, iconTextSizePx = 14)
+
+ val contentHeight =
+ cellContentDimensions.resizeToFitCellHeight(cellSize.second, iconSizeSteps)
+
+ assertThat(contentHeight).isEqualTo(63)
+ cellContentDimensions.run {
+ assertThat(iconSizePx).isEqualTo(52)
+ assertThat(iconDrawablePaddingPx).isEqualTo(0)
+ assertThat(iconTextSizePx).isEqualTo(8)
+ }
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/DisplayControllerTest.kt b/tests/src/com/android/launcher3/util/DisplayControllerTest.kt
index 8e4e998..8670d40 100644
--- a/tests/src/com/android/launcher3/util/DisplayControllerTest.kt
+++ b/tests/src/com/android/launcher3/util/DisplayControllerTest.kt
@@ -30,8 +30,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.LauncherPrefs.Companion.TASKBAR_PINNING
import com.android.launcher3.util.DisplayController.CHANGE_DENSITY
import com.android.launcher3.util.DisplayController.CHANGE_ROTATION
+import com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener
import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext
import com.android.launcher3.util.window.CachedDisplayInfo
@@ -40,11 +42,13 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.doNothing
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.doNothing
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
import org.mockito.stubbing.Answer
/** Unit tests for {@link DisplayController} */
@@ -54,13 +58,13 @@
private val appContext: Context = ApplicationProvider.getApplicationContext()
- @Mock private lateinit var context: SandboxContext
- @Mock private lateinit var windowManagerProxy: WindowManagerProxy
- @Mock private lateinit var launcherPrefs: LauncherPrefs
- @Mock private lateinit var displayManager: DisplayManager
- @Mock private lateinit var display: Display
- @Mock private lateinit var resources: Resources
- @Mock private lateinit var displayInfoChangeListener: DisplayInfoChangeListener
+ private val context: SandboxContext = mock()
+ private val windowManagerProxy: WindowManagerProxy = mock()
+ private val launcherPrefs: LauncherPrefs = mock()
+ private val displayManager: DisplayManager = mock()
+ private val display: Display = mock()
+ private val resources: Resources = mock()
+ private val displayInfoChangeListener: DisplayInfoChangeListener = mock()
private lateinit var displayController: DisplayController
@@ -86,9 +90,9 @@
@Before
fun setUp() {
- MockitoAnnotations.initMocks(this)
whenever(context.getObject(eq(WindowManagerProxy.INSTANCE))).thenReturn(windowManagerProxy)
whenever(context.getObject(eq(LauncherPrefs.INSTANCE))).thenReturn(launcherPrefs)
+ whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(false)
// Mock WindowManagerProxy
val displayInfo =
@@ -107,11 +111,12 @@
bounds[i.getArgument<CachedDisplayInfo>(1).rotation]
}
+ whenever(windowManagerProxy.getNavigationMode(any())).thenReturn(NavigationMode.NO_BUTTON)
// Mock context
- whenever(context.createWindowContext(any(), any(), nullable())).thenReturn(context)
+ whenever(context.createWindowContext(any(), any(), anyOrNull())).thenReturn(context)
whenever(context.getSystemService(eq(DisplayManager::class.java)))
.thenReturn(displayManager)
- doNothing().`when`(context).registerComponentCallbacks(any())
+ doNothing().whenever(context).registerComponentCallbacks(any())
// Mock display
whenever(display.rotation).thenReturn(displayInfo.rotation)
@@ -156,4 +161,13 @@
verify(displayInfoChangeListener).onDisplayInfoChanged(any(), any(), eq(CHANGE_DENSITY))
}
+
+ @Test
+ @UiThreadTest
+ fun testTaskbarPinning() {
+ whenever(launcherPrefs.get(TASKBAR_PINNING)).thenReturn(true)
+ displayController.handleInfoChange(display)
+ verify(displayInfoChangeListener)
+ .onDisplayInfoChanged(any(), any(), eq(CHANGE_TASKBAR_PINNING))
+ }
}
diff --git a/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt b/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt
deleted file mode 100644
index c9c9616..0000000
--- a/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt
+++ /dev/null
@@ -1,119 +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.launcher3.util
-
-/**
- * Kotlin versions of popular mockito methods that can return null in situations when Kotlin expects
- * a non-null value. Kotlin will throw an IllegalStateException when this takes place ("x must not
- * be null"). To fix this, we can use methods that modify the return type to be nullable. This
- * causes Kotlin to skip the null checks.
- */
-import org.mockito.ArgumentCaptor
-import org.mockito.Mockito
-
-/**
- * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when null is
- * returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> eq(obj: T): T = Mockito.eq<T>(obj)
-
-/**
- * Returns Mockito.same() as nullable type to avoid java.lang.IllegalStateException when null is
- * returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> same(obj: T): T = Mockito.same<T>(obj)
-
-/**
- * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when null is
- * returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
-
-inline fun <reified T> any(): T = any(T::class.java)
-
-/** Kotlin type-inferred version of Mockito.nullable() */
-inline fun <reified T> nullable(): T? = Mockito.nullable(T::class.java)
-
-/**
- * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException when
- * null is returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
-
-/**
- * Helper function for creating an argumentCaptor in kotlin.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> argumentCaptor(): ArgumentCaptor<T> =
- ArgumentCaptor.forClass(T::class.java)
-
-/**
- * Helper function for creating new mocks, without the need to pass in a [Class] instance.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java)
-
-/**
- * A kotlin implemented wrapper of [ArgumentCaptor] which prevents the following exception when
- * kotlin tests are mocking kotlin objects and the methods take non-null parameters:
- * ```
- * java.lang.NullPointerException: capture() must not be null
- * ```
- */
-class KotlinArgumentCaptor<T> constructor(clazz: Class<T>) {
- private val wrapped: ArgumentCaptor<T> = ArgumentCaptor.forClass(clazz)
- fun capture(): T = wrapped.capture()
- val value: T
- get() = wrapped.value
-}
-
-/**
- * Helper function for creating an argumentCaptor in kotlin.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> kotlinArgumentCaptor(): KotlinArgumentCaptor<T> =
- KotlinArgumentCaptor(T::class.java)
-
-/**
- * Helper function for creating and using a single-use ArgumentCaptor in kotlin.
- *
- * ```
- * val captor = argumentCaptor<Foo>()
- * verify(...).someMethod(captor.capture())
- * val captured = captor.value
- * ```
- *
- * becomes:
- * ```
- * val captured = withArgCaptor<Foo> { verify(...).someMethod(capture()) }
- * ```
- *
- * NOTE: this uses the KotlinArgumentCaptor to avoid the NullPointerException.
- */
-inline fun <reified T : Any> withArgCaptor(block: KotlinArgumentCaptor<T>.() -> Unit): T =
- kotlinArgumentCaptor<T>().apply { block() }.value
diff --git a/tests/src/com/android/launcher3/util/LockedUserStateTest.kt b/tests/src/com/android/launcher3/util/LockedUserStateTest.kt
index 92ab2cb..2c4a54f 100644
--- a/tests/src/com/android/launcher3/util/LockedUserStateTest.kt
+++ b/tests/src/com/android/launcher3/util/LockedUserStateTest.kt
@@ -26,29 +26,27 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.`when`
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
/** Unit tests for {@link LockedUserState} */
@SmallTest
@RunWith(AndroidJUnit4::class)
class LockedUserStateTest {
- @Mock lateinit var userManager: UserManager
- @Mock lateinit var context: Context
+ private val userManager: UserManager = mock()
+ private val context: Context = mock()
@Before
fun setup() {
- MockitoAnnotations.initMocks(this)
- `when`(context.getSystemService(UserManager::class.java)).thenReturn(userManager)
+ whenever(context.getSystemService(UserManager::class.java)).thenReturn(userManager)
}
@Test
fun runOnUserUnlocked_runs_action_immediately_if_already_unlocked() {
- `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true)
+ whenever(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true)
val action: Runnable = mock()
LockedUserState(context).runOnUserUnlocked(action)
verify(action).run()
@@ -56,7 +54,7 @@
@Test
fun runOnUserUnlocked_waits_to_run_action_until_user_is_unlocked() {
- `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false)
+ whenever(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false)
val action: Runnable = mock()
val state = LockedUserState(context)
state.runOnUserUnlocked(action)
@@ -67,13 +65,13 @@
@Test
fun isUserUnlocked_returns_true_when_user_is_unlocked() {
- `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true)
+ whenever(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(true)
assertThat(LockedUserState(context).isUserUnlocked).isTrue()
}
@Test
fun isUserUnlocked_returns_false_when_user_is_locked() {
- `when`(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false)
+ whenever(userManager.isUserUnlocked(Process.myUserHandle())).thenReturn(false)
assertThat(LockedUserState(context).isUserUnlocked).isFalse()
}
}
diff --git a/tests/src/com/android/launcher3/util/ModelTestExtensions.kt b/tests/src/com/android/launcher3/util/ModelTestExtensions.kt
new file mode 100644
index 0000000..61ec669
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/ModelTestExtensions.kt
@@ -0,0 +1,30 @@
+package com.android.launcher3.util
+
+import com.android.launcher3.LauncherModel
+import com.android.launcher3.model.BgDataModel
+
+object ModelTestExtensions {
+ /** Clears and reloads Launcher db to cleanup the workspace */
+ fun LauncherModel.clearModelDb() {
+ // Load the model once so that there is no pending migration:
+ loadModelSync()
+ TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) {
+ modelDbController.run {
+ tryMigrateDB()
+ createEmptyDB()
+ clearEmptyDbFlag()
+ }
+ }
+ // Reload model
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) { forceReload() }
+ loadModelSync()
+ }
+
+ fun LauncherModel.loadModelSync() {
+ val mockCb: BgDataModel.Callbacks = object : BgDataModel.Callbacks {}
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) { addCallbacksAndLoad(mockCb) }
+ TestUtil.runOnExecutorSync(Executors.MODEL_EXECUTOR) {}
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) {}
+ TestUtil.runOnExecutorSync(Executors.MAIN_EXECUTOR) { removeCallbacks(mockCb) }
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/TestConstants.java b/tests/src/com/android/launcher3/util/TestConstants.java
new file mode 100644
index 0000000..6f3c63a
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/TestConstants.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+public class TestConstants {
+ public static class AppNames {
+
+ public static final String TEST_APP_NAME = "LauncherTestApp";
+ public static final String DUMMY_APP_NAME = "Aardwolf";
+ public static final String MAPS_APP_NAME = "Maps";
+ public static final String STORE_APP_NAME = "Play Store";
+ public static final String GMAIL_APP_NAME = "Gmail";
+ public static final String CHROME_APP_NAME = "Chrome";
+ public static final String MESSAGES_APP_NAME = "Messages";
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/TestUtil.java b/tests/src/com/android/launcher3/util/TestUtil.java
index 21059e6..957bf95 100644
--- a/tests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/src/com/android/launcher3/util/TestUtil.java
@@ -30,6 +30,7 @@
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.res.Resources;
+import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
@@ -46,6 +47,8 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FeatureFlags.BooleanFlag;
import com.android.launcher3.config.FeatureFlags.IntFlag;
+import com.android.launcher3.tapl.LauncherInstrumentation;
+import com.android.launcher3.tapl.Workspace;
import org.junit.Assert;
@@ -125,6 +128,21 @@
}
/**
+ * @return Grid coordinates from the center and corners of the Workspace. Those are not pixels.
+ * See {@link Workspace#getIconGridDimensions()}
+ */
+ public static Point[] getCornersAndCenterPositions(LauncherInstrumentation launcher) {
+ final Point dimensions = launcher.getWorkspace().getIconGridDimensions();
+ return new Point[]{
+ new Point(0, 1),
+ new Point(0, dimensions.y - 2),
+ new Point(dimensions.x - 1, 1),
+ new Point(dimensions.x - 1, dimensions.y - 2),
+ new Point(dimensions.x / 2, dimensions.y / 2)
+ };
+ }
+
+ /**
* Utility class to override a boolean flag during test. Note that the returned SafeCloseable
* must be closed to restore the original state
*/
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java b/tests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
similarity index 65%
copy from src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
copy to tests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
index 68843f2..d682456 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/flags/DeveloperOptionsFragment.java
+++ b/tests/src/com/android/launcher3/util/rule/SetFlagsRuleExt.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.uioverrides.flags;
-/**
- * Place holder class for developer options.
- */
-public class DeveloperOptionsFragment {
+package com.android.launcher3.util.rule
+
+import android.platform.test.flag.junit.SetFlagsRule
+
+fun SetFlagsRule.setFlags(enabled: Boolean, vararg flagName: String) {
+ if (enabled) enableFlags(*flagName) else disableFlags(*flagName)
}
diff --git a/tests/src/com/android/launcher3/util/rule/StaticMockitoRule.java b/tests/src/com/android/launcher3/util/rule/StaticMockitoRule.java
new file mode 100644
index 0000000..6b91474
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/StaticMockitoRule.java
@@ -0,0 +1,72 @@
+/*
+ * 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.launcher3.util.rule;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+
+/**
+ * Similar to {@link MockitoRule}, but uses {@link StaticMockitoSession}, which allows mocking
+ * static methods.
+ */
+public class StaticMockitoRule implements MethodRule {
+ private Class<?>[] mClasses;
+
+ public StaticMockitoRule(Class<?>... classes) {
+ mClasses = classes;
+ }
+
+ @Override
+ public Statement apply(Statement base, FrameworkMethod method, Object target) {
+ return new Statement() {
+ public void evaluate() throws Throwable {
+ StaticMockitoSessionBuilder builder =
+ mockitoSession()
+ .name(target.getClass().getSimpleName() + "." + method.getName())
+ .initMocks(target)
+ .strictness(Strictness.STRICT_STUBS);
+
+ for (Class<?> clazz : mClasses) {
+ builder.mockStatic(clazz);
+ }
+
+ StaticMockitoSession session = builder.startMocking();
+ Throwable testFailure = evaluateSafely(base);
+ session.finishMocking(testFailure);
+ if (testFailure != null) {
+ throw testFailure;
+ }
+ }
+
+ private Throwable evaluateSafely(Statement base) {
+ try {
+ base.evaluate();
+ return null;
+ } catch (Throwable throwable) {
+ return throwable;
+ }
+ }
+ };
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/TISBindRule.java b/tests/src/com/android/launcher3/util/rule/TISBindRule.java
deleted file mode 100644
index 3ec4a29..0000000
--- a/tests/src/com/android/launcher3/util/rule/TISBindRule.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util.rule;
-
-import android.app.UiAutomation;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-public class TISBindRule implements TestRule {
- public static String TAG = "TISBindRule";
- public static String INTENT_FILTER = "android.intent.action.QUICKSTEP_SERVICE";
- public static String TIS_PERMISSIONS = "android.permission.STATUS_BAR_SERVICE";
-
- private String getLauncherPackageName(Context context) {
- return ComponentName.unflattenFromString(context.getString(
- com.android.internal.R.string.config_recentsComponentName)).getPackageName();
- }
-
- private ServiceConnection createConnection() {
- return new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- Log.d(TAG, "Connected to TouchInteractionService");
- }
-
- @Override
- public void onServiceDisconnected(ComponentName componentName) {
- Log.d(TAG, "Disconnected from TouchInteractionService");
- }
- };
- }
-
- @NonNull
- @Override
- public Statement apply(@NonNull Statement base, @NonNull Description description) {
- return new Statement() {
-
- @Override
- public void evaluate() throws Throwable {
- Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- final ServiceConnection connection = createConnection();
- UiAutomation uiAutomation =
- InstrumentationRegistry.getInstrumentation().getUiAutomation();
- uiAutomation.adoptShellPermissionIdentity(TIS_PERMISSIONS);
- Intent launchIntent = new Intent(INTENT_FILTER);
- launchIntent.setPackage(getLauncherPackageName(context));
- context.bindService(launchIntent, connection, Context.BIND_AUTO_CREATE);
- uiAutomation.dropShellPermissionIdentity();
- try {
- base.evaluate();
- } finally {
- context.unbindService(connection);
- }
- }
- };
- }
-}
diff --git a/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
new file mode 100644
index 0000000..2b45902
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/TestIsolationRule.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util.rule;
+
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.UiDevice;
+
+import com.android.launcher3.tapl.LauncherInstrumentation;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Isolates tests from some of the state created by the previous test.
+ */
+public class TestIsolationRule implements TestRule {
+ private final LauncherInstrumentation mLauncher;
+ private final boolean mRequireOneActiveActivity;
+
+ public TestIsolationRule(LauncherInstrumentation launcher, boolean requireOneActiveActivity) {
+ mLauncher = launcher;
+ mRequireOneActiveActivity = requireOneActiveActivity;
+ }
+
+ @NonNull
+ @Override
+ public Statement apply(@NonNull Statement base, @NonNull Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ base.evaluate();
+ // Make sure that Launcher workspace looks correct.
+
+ UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).pressHome();
+ AbstractLauncherUiTest.checkDetectedLeaks(mLauncher, mRequireOneActiveActivity);
+ }
+ };
+ }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
index 38de071..b51045f 100644
--- a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
@@ -146,4 +146,8 @@
return sRunFlavor;
}
+
+ public static boolean isPresubmit() {
+ return getRunFlavor() == PLATFORM_PRESUBMIT;
+ }
}
diff --git a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
index ccbae4f..e70ea18 100644
--- a/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
+++ b/tests/src/com/android/launcher3/util/rule/ViewCaptureRule.kt
@@ -132,7 +132,9 @@
for (i in 0 until viewCaptureData!!.windowDataCount) {
frameCount += viewCaptureData!!.getWindowData(i).frameDataCount
}
- assertTrue("Empty ViewCapture data", frameCount > 0)
+
+ val mayProduceNoFrames = description.getAnnotation(MayProduceNoFrames::class.java) != null
+ assertTrue("Empty ViewCapture data", mayProduceNoFrames || frameCount > 0)
val anomalies: Map<String, String> = ViewCaptureAnalyzer.getAnomalies(viewCaptureData)
if (!anomalies.isEmpty()) {
@@ -159,4 +161,8 @@
)
}
}
+
+ @Retention(AnnotationRetention.RUNTIME)
+ @Target(AnnotationTarget.FUNCTION)
+ annotation class MayProduceNoFrames
}
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
index 4b65439..51b7b18 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/AlphaJumpDetector.java
@@ -62,18 +62,6 @@
+ "NexusOverviewActionsView:id/overview_actions_view|FrameLayout:id"
+ "/select_mode_buttons|ImageButton:id/close",
DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view|LinearLayout:id"
- + "/action_buttons|Button:id/action_screenshot",
- DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view|LinearLayout:id"
- + "/action_buttons|Button:id/action_select",
- DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view|LinearLayout:id"
- + "/action_buttons|Button:id/action_split",
- DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view|LinearLayout:id"
- + "/action_buttons|Space:id/action_split_space",
- DRAG_LAYER
+ "PopupContainerWithArrow:id/popup_container|LinearLayout:id"
+ "/deep_shortcuts_container|DeepShortcutView:id/deep_shortcut_material"
+ "|DeepShortcutTextView:id/bubble_text",
@@ -116,23 +104,14 @@
RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_screenshot",
+ + "|LinearLayout:id/action_buttons",
RECENTS_DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_screenshot",
+ + "|LinearLayout:id/action_buttons",
+ DRAG_LAYER + "IconView",
DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_select",
- RECENTS_DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_select",
- DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_split",
- RECENTS_DRAG_LAYER
- + "NexusOverviewActionsView:id/overview_actions_view"
- + "|LinearLayout:id/action_buttons|Button:id/action_split",
- DRAG_LAYER + "IconView"
+ + "OptionsPopupView:id/popup_container|DeepShortcutView:id/system_shortcut"
+ + "|BubbleTextView:id/bubble_text"
));
// Minimal increase or decrease of view's alpha between frames that triggers the error.
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
index 8b88ace..e333074 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/FlashDetector.java
@@ -38,7 +38,8 @@
private static final IgnoreNode IGNORED_NODES_ROOT = buildIgnoreNodesTree(List.of(
CONTENT + "LauncherRootView:id/launcher|FloatingIconView",
- DRAG_LAYER + "LauncherRecentsView:id/overview_panel|TaskView|TextView",
+ DRAG_LAYER + "LauncherRecentsView:id/overview_panel|TaskView",
+ DRAG_LAYER + "LauncherRecentsView:id/overview_panel|ClearAllButton:id/clear_all",
DRAG_LAYER
+ "LauncherAllAppsContainerView:id/apps_view|AllAppsRecyclerView:id"
+ "/apps_list_view|BubbleTextView:id/icon",
@@ -53,7 +54,9 @@
+ "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
+ "|ScrollView:id/widget_preview_scroll_view|WidgetCell:id/widget_cell"
+ "|WidgetCellPreview:id/widget_preview_container|ImageView:id/widget_badge",
- RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel|TaskView|IconView:id/icon",
+ RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel|TaskView",
+ RECENTS_DRAG_LAYER
+ + "FallbackRecentsView:id/overview_panel|ClearAllButton:id/clear_all",
DRAG_LAYER + "SearchContainerView:id/apps_view",
DRAG_LAYER + "LauncherDragView",
DRAG_LAYER + "FloatingTaskView|FloatingTaskThumbnailView:id/thumbnail",
@@ -64,7 +67,8 @@
+ "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container|LinearLayout:id"
+ "/linear_layout_container|FrameLayout:id/recycler_view_container"
+ "|FrameLayout:id/widgets_two_pane_sheet_recyclerview|WidgetsRecyclerView:id"
- + "/primary_widgets_list_view|WidgetsListHeader:id/widgets_list_header"
+ + "/primary_widgets_list_view|WidgetsListHeader:id/widgets_list_header",
+ DRAG_LAYER + "NexusOverviewActionsView:id/overview_actions_view"
));
// Per-AnalysisNode data that's specific to this detector.
diff --git a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
index a1ddcb0..5f2c68c 100644
--- a/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
+++ b/tests/src/com/android/launcher3/util/viewcapture_analysis/PositionJumpDetector.java
@@ -46,7 +46,7 @@
DRAG_LAYER + "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container",
DRAG_LAYER + "WidgetsFullSheet|SpringRelativeLayout:id/container",
DRAG_LAYER + "LauncherDragView",
- RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel|TaskView",
+ RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
CONTENT + "LauncherRootView:id/launcher|FloatingIconView",
DRAG_LAYER + "FloatingTaskView",
DRAG_LAYER + "LauncherRecentsView:id/overview_panel"
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index fb08ea4..dbb3cc3 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -16,6 +16,8 @@
package com.android.launcher3.tapl;
+import static android.view.KeyEvent.KEYCODE_META_RIGHT;
+
import static com.android.launcher3.tapl.LauncherInstrumentation.DEFAULT_POLL_INTERVAL;
import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS;
@@ -42,12 +44,15 @@
/**
* Operations on AllApps opened from Home. Also a parent for All Apps opened from Overview.
*/
-public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
+public abstract class AllApps extends LauncherInstrumentation.VisibleContainer
+ implements KeyboardQuickSwitchSource {
// Defer updates flag used to defer all apps updates by a test's request.
private static final int DEFER_UPDATES_TEST = 1 << 1;
private static final int MAX_SCROLL_ATTEMPTS = 40;
+ private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background";
+
private final int mHeight;
private final int mIconHeight;
@@ -63,6 +68,16 @@
.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+ @Override
+ public LauncherInstrumentation getLauncher() {
+ return mLauncher;
+ }
+
+ @Override
+ public LauncherInstrumentation.ContainerType getStartingContainerType() {
+ return getContainerType();
+ }
+
private boolean hasClickableIcon(UiObject2 allAppsContainer, UiObject2 appListRecycler,
BySelector appIconSelector, int displayBottom) {
final UiObject2 icon;
@@ -338,6 +353,39 @@
}
/**
+ * Taps outside bottom sheet to dismiss it. Available on tablets only.
+ * @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
+ */
+ public void dismissByTappingOutsideForTablet(boolean tapRight) {
+ mLauncher.assertTrue("Device must be a tablet", mLauncher.isTablet());
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to tap outside AllApps bottom sheet on the "
+ + (tapRight ? "right" : "left"))) {
+ final UiObject2 allAppsBottomSheet =
+ mLauncher.waitForLauncherObject(BOTTOM_SHEET_RES_ID);
+ mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
+ try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
+ "tapped outside AllApps bottom sheet")) {
+ verifyVisibleContainerOnDismiss();
+ }
+ }
+ }
+
+ /** Presses the meta keyboard shortcut to dismiss AllApps. */
+ public void dismissByKeyboardShortcut() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.getDevice().pressKeyCode(KEYCODE_META_RIGHT);
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "pressed meta key")) {
+ verifyVisibleContainerOnDismiss();
+ }
+ }
+ }
+
+ protected abstract void verifyVisibleContainerOnDismiss();
+
+ /**
* Return the QSB UI object on the AllApps screen.
* @return the QSB UI object.
*/
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 677f204..8713b68 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -39,7 +39,8 @@
* Indicates the base state with a UI other than Overview running as foreground. It can also
* indicate Launcher as long as Launcher is not in Overview state.
*/
-public abstract class Background extends LauncherInstrumentation.VisibleContainer {
+public abstract class Background extends LauncherInstrumentation.VisibleContainer
+ implements KeyboardQuickSwitchSource {
private static final int ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION = 500;
private static final Pattern SQUARE_BUTTON_EVENT = Pattern.compile("onOverviewToggle");
@@ -47,6 +48,16 @@
super(launcher);
}
+ @Override
+ public LauncherInstrumentation getLauncher() {
+ return mLauncher;
+ }
+
+ @Override
+ public LauncherInstrumentation.ContainerType getStartingContainerType() {
+ return getContainerType();
+ }
+
/**
* Swipes up or presses the square button to switch to Overview.
* Returns the base overview, which can be either in Launcher or the fallback recents.
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index aa5c770..770fe14 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -25,6 +25,7 @@
import androidx.test.uiautomator.UiObject2;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@@ -201,7 +202,8 @@
OverviewTask task = getCurrentTask();
mLauncher.assertNotNull("current task is null", task);
mLauncher.scrollLeftByDistance(verifyActiveContainer(),
- task.getVisibleWidth() + mLauncher.getOverviewPageSpacing());
+ mLauncher.getRealDisplaySize().x - task.getUiObject().getVisibleBounds().left
+ + mLauncher.getOverviewPageSpacing());
try (LauncherInstrumentation.Closable c2 =
mLauncher.addContextLayer("scrolled task off screen")) {
@@ -231,14 +233,14 @@
final List<UiObject2> taskViews = getTasks();
mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size());
- // taskViews contains up to 3 task views: the 'main' (having the widest visible part) one
- // in the center, and parts of its right and left siblings. Find the main task view by
- // its width.
- final UiObject2 widestTask = Collections.max(taskViews,
- (t1, t2) -> Integer.compare(mLauncher.getVisibleBounds(t1).width(),
- mLauncher.getVisibleBounds(t2).width()));
-
- return new OverviewTask(mLauncher, widestTask, this);
+ final List<OverviewTask> overviewTasks = taskViews.stream().map(
+ task -> new OverviewTask(mLauncher, task, this)).toList();
+ // The widest, and most top-right task should be the current task
+ return Collections.max(overviewTasks,
+ Comparator.comparingInt(OverviewTask::getVisibleWidth)
+ .thenComparingInt(OverviewTask::getTaskCenterX)
+ .thenComparing(
+ Comparator.comparing(OverviewTask::getTaskCenterY).reversed()));
}
/** Returns an overview task matching TestActivity {@param activityNumber}. */
@@ -366,8 +368,10 @@
}
int focusedTaskHeight = mLauncher.getFocusedTaskHeightForTablet();
for (UiObject2 task : taskViews) {
- if (task.getVisibleBounds().height() == focusedTaskHeight) {
- return new OverviewTask(mLauncher, task, this);
+ OverviewTask overviewTask = new OverviewTask(mLauncher, task, this);
+
+ if (overviewTask.getVisibleHeight() == focusedTaskHeight) {
+ return overviewTask;
}
}
return null;
diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java
index 252435b..85e28e8 100644
--- a/tests/tapl/com/android/launcher3/tapl/Home.java
+++ b/tests/tapl/com/android/launcher3/tapl/Home.java
@@ -62,4 +62,9 @@
protected boolean zeroButtonToOverviewGestureStateTransitionWhileHolding() {
return true;
}
+
+ @Override
+ public boolean isHomeState() {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
index 2951901..d9b179c 100644
--- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
@@ -23,7 +23,6 @@
import com.android.launcher3.testing.shared.TestProtocol;
public class HomeAllApps extends AllApps {
- private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background";
HomeAllApps(LauncherInstrumentation launcher) {
super(launcher);
@@ -98,25 +97,6 @@
.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- /**
- * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only.
- * @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
- */
- public Workspace dismissByTappingOutsideForTablet(boolean tapRight) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to tap outside AllApps bottom sheet on the "
- + (tapRight ? "right" : "left"))) {
- final UiObject2 allAppsBottomSheet =
- mLauncher.waitForLauncherObject(BOTTOM_SHEET_RES_ID);
- mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
- try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
- "tapped outside AllApps bottom sheet")) {
- return mLauncher.getWorkspace();
- }
- }
- }
-
@NonNull
@Override
public Qsb getQsb() {
@@ -128,4 +108,14 @@
return mLauncher.getTestInfo(TestProtocol.REQUEST_APPS_LIST_SCROLL_Y)
.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+
+ @Override
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getWorkspace();
+ }
+
+ @Override
+ public boolean isHomeState() {
+ return true;
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java
new file mode 100644
index 0000000..a1d8059
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.tapl;
+
+import static com.android.launcher3.tapl.LauncherInstrumentation.KEYBOARD_QUICK_SWITCH_RES_ID;
+
+import android.view.KeyEvent;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.testing.shared.TestProtocol;
+
+import java.util.regex.Pattern;
+
+/**
+ * Operations on the Keyboard Quick Switch View
+ */
+public final class KeyboardQuickSwitch {
+
+ private static final Pattern EVENT_ALT_TAB_DOWN = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_TAB"
+ + ".*?metaState=META_ALT_ON");
+ private static final Pattern EVENT_ALT_TAB_UP = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_UP.*?keyCode=KEYCODE_TAB"
+ + ".*?metaState=META_ALT_ON");
+ private static final Pattern EVENT_ALT_SHIFT_TAB_DOWN = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_TAB"
+ + ".*?metaState=META_ALT_ON|META_SHIFT_ON");
+ private static final Pattern EVENT_ALT_SHIFT_TAB_UP = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_UP.*?keyCode=KEYCODE_TAB"
+ + ".*?metaState=META_ALT_ON|META_SHIFT_ON");
+ private static final Pattern EVENT_ALT_ESC_DOWN = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_DOWN"
+ + ".*?keyCode=KEYCODE_ESCAPE.*?metaState=META_ALT_ON");
+ private static final Pattern EVENT_ALT_ESC_UP = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_UP"
+ + ".*?keyCode=KEYCODE_ESCAPE.*?metaState=META_ALT_ON");
+ private static final Pattern EVENT_KQS_ALT_LEFT_UP = Pattern.compile(
+ "KeyboardQuickSwitchView key event: KeyEvent.*?action=ACTION_UP"
+ + ".*?keyCode=KEYCODE_ALT_LEFT");
+ private static final Pattern EVENT_HOME_ALT_LEFT_UP = Pattern.compile(
+ "Key event: KeyEvent.*?action=ACTION_UP"
+ + ".*?keyCode=KEYCODE_ALT_LEFT");
+
+ private final LauncherInstrumentation mLauncher;
+ private final LauncherInstrumentation.ContainerType mStartingContainerType;
+ private final boolean mExpectHomeKeyEventsOnDismiss;
+
+ KeyboardQuickSwitch(
+ LauncherInstrumentation launcher,
+ LauncherInstrumentation.ContainerType startingContainerType,
+ boolean expectHomeKeyEventsOnDismiss) {
+ mLauncher = launcher;
+ mStartingContainerType = startingContainerType;
+ mExpectHomeKeyEventsOnDismiss = expectHomeKeyEventsOnDismiss;
+ }
+
+ /**
+ * Focuses the next task in the Keyboard quick switch view.
+ * <p>
+ * Tasks are ordered left-to-right in LTR, and vice versa in RLT, in a carousel.
+ * <ul>
+ * <li>If no task has been focused yet, and there is only one task, then that task will be
+ * focused</li>
+ * <li>If no task has been focused yet, and there are two or more tasks, then the second
+ * task will be focused</li>
+ * <li>If the currently-focused task is at the end of the list, the first task will be
+ * focused</li>
+ * </ul>
+ */
+ public KeyboardQuickSwitch moveFocusForward() {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to move keyboard quick switch focus forward");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_TAB_DOWN);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_TAB_UP);
+ mLauncher.assertTrue("Failed to press alt+tab",
+ mLauncher.getDevice().pressKeyCode(
+ KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_ON));
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "pressed alt+tab")) {
+ mLauncher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ return this;
+ }
+ }
+ }
+
+ /**
+ * Focuses the next task in the Keyboard quick switch view.
+ * <p>
+ * Tasks are ordered left-to-right in LTR, and vice versa in RLT, in a carousel.
+ * <ul>
+ * <li>If no task has been focused yet, and there is only one task, then that task will be
+ * focused</li>
+ * <li>If no task has been focused yet, and there are two or more tasks, then the second
+ * task will be focused</li>
+ * <li>If the currently-focused task is at the start of the list, the last task will be
+ * focused</li>
+ * </ul>
+ */
+ public KeyboardQuickSwitch moveFocusBackward() {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to move keyboard quick switch focus backward");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_SHIFT_TAB_DOWN);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_SHIFT_TAB_UP);
+ mLauncher.assertTrue("Failed to press alt+shift+tab",
+ mLauncher.getDevice().pressKeyCode(
+ KeyEvent.KEYCODE_TAB,
+ KeyEvent.META_ALT_ON | KeyEvent.META_SHIFT_ON));
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "pressed alt+shift+tab")) {
+ mLauncher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ return this;
+ }
+ }
+ }
+
+ /**
+ * Dismisses the Keyboard Quick Switch view without launching the focused task.
+ * <p>
+ * The device will return to the same state it started in before displaying the Keyboard Quick
+ * Switch view.
+ */
+ public void dismiss() {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to dismiss keyboard quick switch view");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_ESC_DOWN);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_ALT_ESC_UP);
+ mLauncher.assertTrue("Failed to press alt+tab",
+ mLauncher.getDevice().pressKeyCode(
+ KeyEvent.KEYCODE_ESCAPE, KeyEvent.META_ALT_ON));
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "pressed alt+esc")) {
+ mLauncher.waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ // Verify the final state is the same as the initial state
+ mLauncher.verifyContainerType(mStartingContainerType);
+
+ // Wait until the device has fully settled before unpressing the key code
+ if (mExpectHomeKeyEventsOnDismiss) {
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_HOME_ALT_LEFT_UP);
+ }
+ mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0);
+ }
+ }
+ }
+
+ /**
+ * Launches the currently-focused app task.
+ * <p>
+ * This method should only be used if the focused task is for a recent running app, otherwise
+ * use {@link #launchFocusedOverviewTask()}.
+ *
+ * @param expectedPackageName the package name of the expected launched app
+ */
+ public LaunchedAppState launchFocusedAppTask(@NonNull String expectedPackageName) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ return (LaunchedAppState) launchFocusedTask(expectedPackageName);
+ }
+ }
+
+ /**
+ * Launches the currently-focused overview task.
+ * <p>
+ * This method only should be used if the focused task is for overview, otherwise use
+ * {@link #launchFocusedAppTask(String)}.
+ */
+ public Overview launchFocusedOverviewTask() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ return (Overview) launchFocusedTask(null);
+ }
+ }
+
+ private LauncherInstrumentation.VisibleContainer launchFocusedTask(
+ @Nullable String expectedPackageName) {
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to launch focused task: "
+ + (expectedPackageName == null ? "Overview" : expectedPackageName))) {
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KQS_ALT_LEFT_UP);
+ mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "un-pressed left alt")) {
+ mLauncher.waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
+
+ if (expectedPackageName != null) {
+ mLauncher.assertAppLaunched(expectedPackageName);
+ return mLauncher.getLaunchedAppState();
+ } else {
+ return mLauncher.getOverview();
+ }
+ }
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitchSource.java b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitchSource.java
new file mode 100644
index 0000000..677ed04
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitchSource.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.tapl;
+
+import static com.android.launcher3.tapl.LauncherInstrumentation.KEYBOARD_QUICK_SWITCH_RES_ID;
+
+import android.view.KeyEvent;
+
+/**
+ * {@link com.android.launcher3.tapl.LauncherInstrumentation.VisibleContainer} that can be used to
+ * show the keyboard quick switch view.
+ */
+interface KeyboardQuickSwitchSource {
+
+ /**
+ * Shows the Keyboard Quick Switch view.
+ */
+ default KeyboardQuickSwitch showQuickSwitchView() {
+ LauncherInstrumentation launcher = getLauncher();
+
+ try (LauncherInstrumentation.Closable c1 = launcher.addContextLayer(
+ "want to show keyboard quick switch object");
+ LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
+ launcher.pressAndHoldKeyCode(KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_LEFT_ON);
+
+ try (LauncherInstrumentation.Closable c2 = launcher.addContextLayer(
+ "press and held alt+tab")) {
+ launcher.waitForLauncherObject(KEYBOARD_QUICK_SWITCH_RES_ID);
+ launcher.unpressKeyCode(KeyEvent.KEYCODE_TAB, 0);
+
+ return new KeyboardQuickSwitch(
+ launcher, getStartingContainerType(), isHomeState());
+ }
+ }
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ LauncherInstrumentation getLauncher();
+
+ /** This method requires public access, however should not be called in tests. */
+ LauncherInstrumentation.ContainerType getStartingContainerType();
+
+ /** This method requires public access, however should not be called in tests. */
+ boolean isHomeState();
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index a953fa9..f6fcfa64 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -16,15 +16,14 @@
package com.android.launcher3.tapl;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
import static com.android.launcher3.testing.shared.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
import android.graphics.Point;
import android.view.MotionEvent;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
import com.android.launcher3.testing.shared.TestProtocol;
@@ -53,7 +52,19 @@
*/
public LaunchedAppState launch(String expectedPackageName) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return launch(By.pkg(expectedPackageName));
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to launch an app from " + launchableType())) {
+ LauncherInstrumentation.log("Launchable.launch before click "
+ + mObject.getVisibleCenter() + " in "
+ + mLauncher.getVisibleBounds(mObject));
+
+ mLauncher.clickLauncherObject(mObject);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+ expectActivityStartEvents();
+ return mLauncher.assertAppLaunched(expectedPackageName);
+ }
+ }
}
}
@@ -61,21 +72,6 @@
protected abstract String launchableType();
- private LaunchedAppState launch(BySelector selector) {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to launch an app from " + launchableType())) {
- LauncherInstrumentation.log("Launchable.launch before click "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
- mLauncher.clickLauncherObject(mObject);
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
- expectActivityStartEvents();
- return assertAppLaunched(selector);
- }
- }
- }
-
/**
* Clicks a launcher object to initiate splitscreen, where the selected app will be one of two
* apps running on the screen. Should be called when Launcher is in a "split staging" state
@@ -83,12 +79,18 @@
* fired when the click is executed.
*/
public LaunchedAppState launchIntoSplitScreen() {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to launch split tasks from " + launchableType())) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "want to launch split tasks from " + launchableType())) {
LauncherInstrumentation.log("Launchable.launch before click "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
-
- mLauncher.clickLauncherObject(mObject);
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(
+ mObject));
+ mLauncher.executeAndWaitForLauncherEvent(
+ () -> mLauncher.clickLauncherObject(mObject),
+ accessibilityEvent ->
+ accessibilityEvent.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Unable to click object to launch split",
+ "Click launcher object to launch split");
try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, OverviewTask.SPLIT_START_EVENT);
@@ -97,14 +99,6 @@
}
}
- protected LaunchedAppState assertAppLaunched(BySelector selector) {
- mLauncher.assertTrue(
- "App didn't start: (" + selector + ")",
- mLauncher.getDevice().wait(Until.hasObject(selector),
- LauncherInstrumentation.WAIT_TIME_MS));
- return new LaunchedAppState(mLauncher);
- }
-
Point startDrag(long downTime, Runnable expectLongClickEvents, boolean runToSpringLoadedState) {
final Point iconCenter = getObject().getVisibleCenter();
final Point dragStartCenter = new Point(iconCenter.x,
diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
index 30417c0..efeb5f6 100644
--- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
+++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
@@ -34,7 +34,6 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
-import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Condition;
import androidx.test.uiautomator.UiDevice;
@@ -55,13 +54,13 @@
private static final int STASHED_TASKBAR_BOTTOM_EDGE_DP = 1;
private final Condition<UiDevice, Boolean> mStashedTaskbarHintScaleCondition =
- device -> mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
- TestProtocol.TEST_INFO_RESPONSE_FIELD) - UNSTASHED_TASKBAR_HANDLE_HINT_SCALE
+ device -> Math.abs(mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD) - UNSTASHED_TASKBAR_HANDLE_HINT_SCALE)
< 0.00001f;
private final Condition<UiDevice, Boolean> mStashedTaskbarDefaultScaleCondition =
- device -> mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
- TestProtocol.TEST_INFO_RESPONSE_FIELD) - 1f < 0.00001f;
+ device -> Math.abs(mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD) - 1f) < 0.00001f;
LaunchedAppState(LauncherInstrumentation launcher) {
super(launcher);
@@ -72,6 +71,11 @@
return LauncherInstrumentation.ContainerType.LAUNCHED_APP;
}
+ @Override
+ public boolean isHomeState() {
+ return false;
+ }
+
/**
* Returns the taskbar.
*
@@ -200,8 +204,8 @@
try (LauncherInstrumentation.Closable c4 = launcher.addContextLayer(
"dropped item")) {
- launchable.assertAppLaunched(By.pkg(expectedNewPackageName));
- launchable.assertAppLaunched(By.pkg(expectedExistingPackageName));
+ launcher.assertAppLaunched(expectedNewPackageName);
+ launcher.assertAppLaunched(expectedExistingPackageName);
}
}
}
@@ -280,7 +284,8 @@
Point stashedTaskbarHintArea = new Point(mLauncher.getRealDisplaySize().x / 2,
mLauncher.getRealDisplaySize().y - 1);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_ENTER,
- new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y), null);
+ new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y), null,
+ InputDevice.SOURCE_MOUSE);
mLauncher.getDevice().wait(mStashedTaskbarHintScaleCondition,
LauncherInstrumentation.WAIT_TIME_MS);
@@ -292,7 +297,7 @@
mLauncher.getRealDisplaySize().y - 500);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_EXIT,
new Point(outsideStashedTaskbarHintArea.x, outsideStashedTaskbarHintArea.y),
- null);
+ null, InputDevice.SOURCE_MOUSE);
mLauncher.getDevice().wait(mStashedTaskbarDefaultScaleCondition,
LauncherInstrumentation.WAIT_TIME_MS);
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index c58ae16..17169b3 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -20,21 +20,26 @@
import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
+import static android.view.KeyEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT;
import static com.android.launcher3.tapl.Folder.FOLDER_CONTENT_RES_ID;
import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL;
+import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_NUM_ALL_APPS_COLUMNS;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.UiAutomation;
+import android.app.UiModeManager;
import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Point;
@@ -48,6 +53,9 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.WindowManager;
@@ -169,10 +177,13 @@
private static final String OPEN_FOLDER_RES_ID = "folder_content";
static final String TASKBAR_RES_ID = "taskbar_view";
private static final String SPLIT_PLACEHOLDER_RES_ID = "split_placeholder";
+ static final String KEYBOARD_QUICK_SWITCH_RES_ID = "keyboard_quick_switch_view";
public static final int WAIT_TIME_MS = 30000;
static final long DEFAULT_POLL_INTERVAL = 1000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
+ private static final String ASSISTANT_PACKAGE = "com.google.android.googlequicksearchbox";
+ private static final String ASSISTANT_GO_HOME_RES_ID = "home_icon";
private static WeakReference<VisibleContainer> sActiveContainer = new WeakReference<>(null);
@@ -338,6 +349,16 @@
.getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
+ Insets getImeInsets() {
+ return getTestInfo(TestProtocol.REQUEST_IME_INSETS)
+ .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
+ public int getNumAllAppsColumns() {
+ return getTestInfo(REQUEST_NUM_ALL_APPS_COLUMNS).getInt(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
public boolean isTablet() {
return getTestInfo(TestProtocol.REQUEST_IS_TABLET)
.getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
@@ -689,6 +710,7 @@
/**
* Set the trackpad gesture type of the interaction.
+ *
* @param trackpadGestureType whether it's not from trackpad, two-finger, three-finger, or
* four-finger gesture.
*/
@@ -713,6 +735,10 @@
mExpectedRotationCheckEnabled = expectedRotationCheckEnabled;
}
+ public boolean getExpectedRotationCheckEnabled() {
+ return mExpectedRotationCheckEnabled;
+ }
+
public String getNavigationModeMismatchError(boolean waitForCorrectState) {
final int waitTime = waitForCorrectState ? WAIT_TIME_MS : 0;
final NavigationModel navigationModel = getNavigationModel();
@@ -743,7 +769,7 @@
return isTablet() ? getLauncherPackageName() : SYSTEMUI_PACKAGE;
}
- private UiObject2 verifyContainerType(ContainerType containerType) {
+ UiObject2 verifyContainerType(ContainerType containerType) {
waitForLauncherInitialized();
if (mExpectedRotationCheckEnabled && mExpectedRotation != null) {
@@ -772,6 +798,7 @@
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
if (is3PLauncher() && isTablet()) {
waitForSystemLauncherObject(TASKBAR_RES_ID);
@@ -786,6 +813,7 @@
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
if (is3PLauncher() && isTablet()) {
waitForSystemLauncherObject(TASKBAR_RES_ID);
@@ -801,6 +829,7 @@
waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID);
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
return waitForLauncherObject(APPS_RES_ID);
}
@@ -809,6 +838,7 @@
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
if (is3PLauncher() && isTablet()) {
waitForSystemLauncherObject(TASKBAR_RES_ID);
@@ -829,6 +859,7 @@
waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID);
}
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
return waitForSystemLauncherObject(OVERVIEW_RES_ID);
}
@@ -843,6 +874,7 @@
}
waitForSystemLauncherObject(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
return waitForSystemLauncherObject(OVERVIEW_RES_ID);
}
case LAUNCHED_APP: {
@@ -851,6 +883,7 @@
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+ waitUntilLauncherObjectGone(KEYBOARD_QUICK_SWITCH_RES_ID);
if (mIgnoreTaskbarVisibility) {
return null;
@@ -969,6 +1002,25 @@
}
/**
+ * Goes to home from immersive fullscreen app by first swiping up to bring navbar, and then
+ * performing {@code goHome()} action.
+ * Currently only supports gesture navigation mode.
+ *
+ * @return the Workspace object.
+ */
+ public Workspace goHomeFromImmersiveFullscreenApp() {
+ assertTrue("expected gesture navigation mode",
+ getNavigationModel() == NavigationModel.ZERO_BUTTON);
+ final Point displaySize = getRealDisplaySize();
+ linearGesture(
+ displaySize.x / 2, displaySize.y - 1,
+ displaySize.x / 2, 0,
+ ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
+ false, GestureScope.EXPECT_PILFER);
+ return goHome();
+ }
+
+ /**
* Goes to home by swiping up in zero-button mode or pressing Home button.
* Calling it after another TAPL call is safe because all TAPL methods wait for the animations
* to finish.
@@ -1024,7 +1076,7 @@
action = "clicking home button";
runToState(
- waitForNavigationUiObject("home")::click,
+ getHomeButton()::click,
NORMAL_STATE_ORDINAL,
!hasLauncherObject(WORKSPACE_RES_ID)
&& (hasLauncherObject(APPS_RES_ID)
@@ -1158,6 +1210,14 @@
}
}
+ LaunchedAppState assertAppLaunched(@NonNull String expectedPackageName) {
+ BySelector packageSelector = By.pkg(expectedPackageName);
+ assertTrue("App didn't start: (" + packageSelector + ")",
+ mDevice.wait(Until.hasObject(packageSelector),
+ LauncherInstrumentation.WAIT_TIME_MS));
+ return new LaunchedAppState(this);
+ }
+
void waitUntilLauncherObjectGone(String resId) {
waitUntilGoneBySelector(getLauncherObjectSelector(resId));
}
@@ -1205,6 +1265,28 @@
}
@NonNull
+ private UiObject2 getHomeButton() {
+ UiModeManager uiManager =
+ (UiModeManager) getContext().getSystemService(Context.UI_MODE_SERVICE);
+ if (uiManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
+ return waitForAssistantHomeButton();
+ } else {
+ return waitForNavigationUiObject("home");
+ }
+ }
+
+ /* Assistant Home button is present when system is in car mode. */
+ @NonNull
+ UiObject2 waitForAssistantHomeButton() {
+ final UiObject2 object = mDevice.wait(
+ Until.findObject(By.res(ASSISTANT_PACKAGE, ASSISTANT_GO_HOME_RES_ID)),
+ WAIT_TIME_MS);
+ assertNotNull(
+ "Can't find an assistant UI object with id: " + ASSISTANT_GO_HOME_RES_ID, object);
+ return object;
+ }
+
+ @NonNull
UiObject2 waitForNavigationUiObject(String resId) {
String resPackage = getNavigationButtonResPackage();
final UiObject2 object = mDevice.wait(
@@ -1268,6 +1350,16 @@
}
}
+ void waitForObjectFocused(UiObject2 object, String waitReason) {
+ try {
+ assertTrue("Timed out waiting for object to be focused for " + waitReason + " "
+ + object.getResourceName(),
+ object.wait(Until.focused(true), WAIT_TIME_MS));
+ } catch (StaleObjectException e) {
+ fail("The object disappeared from screen");
+ }
+ }
+
@NonNull
UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
return waitForObjectsInContainer(container, selector).get(0);
@@ -1516,8 +1608,11 @@
scroll(
container,
Direction.LEFT,
- new Rect(leftGestureMargin, 0,
- containerRect.width() - distance - rightGestureMarginInContainer, 0),
+ new Rect(leftGestureMargin,
+ 0,
+ Math.max(containerRect.width() - distance - leftGestureMargin,
+ rightGestureMarginInContainer),
+ 0),
10,
true);
}
@@ -1690,7 +1785,7 @@
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- boolean isGridOnlyOverviewEnabled() {
+ public boolean isGridOnlyOverviewEnabled() {
return getTestInfo(TestProtocol.REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW).getBoolean(
TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
@@ -1701,6 +1796,11 @@
InputDevice.SOURCE_TOUCHSCREEN);
}
+ private void injectEvent(InputEvent event) {
+ assertTrue("injectInputEvent failed: event=" + event,
+ mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
+ }
+
public void sendPointer(long downTime, long currentTime, int action, Point point,
GestureScope gestureScope, int source) {
final boolean hasTIS = hasTIS();
@@ -1731,16 +1831,46 @@
final MotionEvent event = isTrackpadGesture
? getTrackpadMotionEvent(
- downTime, currentTime, action, point.x, point.y, pointerCount,
- mTrackpadGestureType)
+ downTime, currentTime, action, point.x, point.y, pointerCount,
+ mTrackpadGestureType)
: getMotionEvent(downTime, currentTime, action, point.x, point.y, source);
if (action == MotionEvent.ACTION_BUTTON_PRESS
|| action == MotionEvent.ACTION_BUTTON_RELEASE) {
event.setActionButton(MotionEvent.BUTTON_PRIMARY);
}
- assertTrue("injectInputEvent failed",
- mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
- event.recycle();
+ injectEvent(event);
+ }
+
+ private KeyEvent createKeyEvent(int keyCode, int metaState, boolean actionDown) {
+ long eventTime = SystemClock.uptimeMillis();
+ return KeyEvent.obtain(
+ eventTime,
+ eventTime,
+ actionDown ? ACTION_DOWN : ACTION_UP,
+ keyCode,
+ /* repeat= */ 0,
+ metaState,
+ KeyCharacterMap.VIRTUAL_KEYBOARD,
+ /* scancode= */ 0,
+ /* flags= */ 0,
+ InputDevice.SOURCE_KEYBOARD,
+ /* characters =*/ null);
+ }
+
+ /**
+ * Sends a {@link KeyEvent} with {@link ACTION_DOWN} for the given key codes without sending
+ * a {@link KeyEvent} with {@link ACTION_UP}.
+ */
+ public void pressAndHoldKeyCode(int keyCode, int metaState) {
+ injectEvent(createKeyEvent(keyCode, metaState, true));
+ }
+
+
+ /**
+ * Sends a {@link KeyEvent} with {@link ACTION_UP} for the given key codes.
+ */
+ public void unpressKeyCode(int keyCode, int metaState) {
+ injectEvent(createKeyEvent(keyCode, metaState, false));
}
public long movePointer(long downTime, long startTime, long duration, Point from, Point to,
@@ -1932,6 +2062,12 @@
getTestInfo(TestProtocol.REQUEST_RECREATE_TASKBAR);
}
+ // TODO(b/270393900): Remove with ENABLE_ALL_APPS_SEARCH_IN_TASKBAR flag cleanup.
+ /** Refreshes the known overview target in TIS. */
+ public void refreshOverviewTarget() {
+ getTestInfo(TestProtocol.REQUEST_REFRESH_OVERVIEW_TARGET);
+ }
+
public List<String> getHotseatIconNames() {
return getTestInfo(TestProtocol.REQUEST_HOTSEAT_ICON_NAMES)
.getStringArrayList(TestProtocol.TEST_INFO_RESPONSE_FIELD);
@@ -1946,14 +2082,16 @@
return String.join(", ", getActivities());
}
- public boolean noLeakedActivities() {
+ /** Returns whether no leaked activities are detected. */
+ public boolean noLeakedActivities(boolean requireOneActiveActivity) {
final String[] activities = getActivities();
+
for (String activity : activities) {
if (activity.contains("(destroyed)")) {
return false;
}
}
- return activities.length <= 2;
+ return activities.length <= (requireOneActiveActivity ? 1 : 2);
}
public int getActivitiesCreated() {
@@ -2086,7 +2224,13 @@
? containerBounds.right + 1
: containerBounds.left - 1;
}
- int y = containerBounds.top + containerBounds.height() / 2;
+ // If IME is visible and overlaps the container bounds, touch above it.
+ int bottomBound = Math.min(
+ containerBounds.bottom,
+ getRealDisplaySize().y - getImeInsets().bottom);
+ int y = (bottomBound + containerBounds.top) / 2;
+ // Do not tap in the status bar.
+ y = Math.max(y, getWindowInsets().top);
final long downTime = SystemClock.uptimeMillis();
final Point tapTarget = new Point(x, y);
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index e4cfc52..8a34f0d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -36,6 +36,8 @@
*/
public final class OverviewTask {
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
+ private static final String TASK_SNAPSHOT_1 = "snapshot";
+ private static final String TASK_SNAPSHOT_2 = "bottomright_snapshot";
static final Pattern TASK_START_EVENT = Pattern.compile("startActivityFromRecentsAsync");
static final Pattern SPLIT_SELECT_EVENT = Pattern.compile("enterSplitSelect");
@@ -55,20 +57,75 @@
mOverview.verifyActiveContainer();
}
+ /**
+ * Returns the height of the visible task, or the combined height of two tasks in split with a
+ * divider between.
+ */
int getVisibleHeight() {
+ if (isTaskSplit()) {
+ return getCombinedSplitTaskHeight();
+ }
+
return mTask.getVisibleBounds().height();
}
+ /**
+ * Calculates the visible height for split tasks, containing 2 snapshot tiles and a divider.
+ */
+ private int getCombinedSplitTaskHeight() {
+ UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
+ UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+
+ // If the split task is partly off screen, taskSnapshot1 can be invisible.
+ if (taskSnapshot1 == null) {
+ return taskSnapshot2.getVisibleBounds().height();
+ }
+
+ int top = Math.min(
+ taskSnapshot1.getVisibleBounds().top, taskSnapshot2.getVisibleBounds().top);
+ int bottom = Math.max(
+ taskSnapshot1.getVisibleBounds().bottom, taskSnapshot2.getVisibleBounds().bottom);
+
+ return bottom - top;
+ }
+
+ /**
+ * Returns the width of the visible task, or the combined width of two tasks in split with a
+ * divider between.
+ */
int getVisibleWidth() {
+ if (isTaskSplit()) {
+ return getCombinedSplitTaskWidth();
+ }
+
return mTask.getVisibleBounds().width();
}
+ /**
+ * Calculates the visible width for split tasks, containing 2 snapshot tiles and a divider.
+ */
+ private int getCombinedSplitTaskWidth() {
+ UiObject2 taskSnapshot1 = findObjectInTask(TASK_SNAPSHOT_1);
+ UiObject2 taskSnapshot2 = findObjectInTask(TASK_SNAPSHOT_2);
+
+ int left = Math.min(
+ taskSnapshot1.getVisibleBounds().left, taskSnapshot2.getVisibleBounds().left);
+ int right = Math.max(
+ taskSnapshot1.getVisibleBounds().right, taskSnapshot2.getVisibleBounds().right);
+
+ return right - left;
+ }
+
int getTaskCenterX() {
- return mTask.getVisibleCenter().x;
+ return mTask.getParent().getVisibleCenter().x;
+ }
+
+ int getTaskCenterY() {
+ return mTask.getParent().getVisibleCenter().y;
}
float getExactCenterX() {
- return mTask.getVisibleBounds().exactCenterX();
+ return mTask.getParent().getVisibleBounds().exactCenterX();
}
UiObject2 getUiObject() {
@@ -92,7 +149,8 @@
boolean taskWasFocused = mLauncher.isTablet() && getVisibleHeight() == mLauncher
.getFocusedTaskHeightForTablet();
- List<Integer> originalTasksCenterX = getCurrentTasksCenterXList();
+ List<Integer> originalTasksCenterX =
+ getCurrentTasksCenterXList().stream().sorted().toList();
boolean isClearAllVisibleBeforeDismiss = mOverview.isClearAllVisible();
dismissBySwipingUp();
@@ -103,7 +161,8 @@
mOverview.getFocusedTaskForTablet());
}
if (!isClearAllVisibleBeforeDismiss) {
- List<Integer> currentTasksCenterX = getCurrentTasksCenterXList();
+ List<Integer> currentTasksCenterX =
+ getCurrentTasksCenterXList().stream().sorted().toList();
if (originalTasksCenterX.size() == currentTasksCenterX.size()) {
// Check for the same number of visible tasks before and after to
// avoid asserting on cases of shifting all tasks to close the distance
@@ -121,7 +180,7 @@
// Dismiss the task via flinging it up.
final Rect taskBounds = mLauncher.getVisibleBounds(mTask);
final int centerX = taskBounds.centerX();
- final int centerY = taskBounds.centerY();
+ final int centerY = taskBounds.bottom - 1;
mLauncher.executeAndWaitForLauncherEvent(
() -> mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER),
@@ -168,7 +227,7 @@
}
}
- /** Taps the task menu. */
+ /** Taps the task menu. Returns the task menu object. */
@NonNull
public OverviewTaskMenu tapMenu() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
@@ -184,7 +243,27 @@
}
}
+ /** Taps the task menu of the split task. Returns the split task's menu object. */
+ @NonNull
+ public OverviewTaskMenu tapSplitTaskMenu() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to tap the split task's menu")) {
+ mLauncher.clickLauncherObject(
+ mLauncher.waitForObjectInContainer(mTask.getParent(), "bottomRight_icon"));
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "tapped the split task's menu")) {
+ return new OverviewTaskMenu(mLauncher);
+ }
+ }
+ }
+
boolean isTaskSplit() {
- return mLauncher.findObjectInContainer(mTask.getParent(), "bottomright_snapshot") != null;
+ return findObjectInTask(TASK_SNAPSHOT_2) != null;
+ }
+
+ private UiObject2 findObjectInTask(String resName) {
+ return mTask.getParent().findObject(mLauncher.getOverviewObjectSelector(resName));
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
index 7c29a6c..38cc321 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
@@ -50,8 +50,10 @@
}
}
- /** Taps the app info item from the overview task menu and returns the LaunchedAppState
- * representing the App info settings page. */
+ /**
+ * Taps the app info item from the overview task menu and returns the LaunchedAppState
+ * representing the App info settings page.
+ */
@NonNull
public LaunchedAppState tapAppInfoMenuItem() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
@@ -81,4 +83,11 @@
return new OverviewTaskMenuItem(mLauncher,
mLauncher.waitForObjectInContainer(mMenu, By.text(menuItemName)));
}
+
+ /**
+ * Taps outside task menu to dismiss it.
+ */
+ public void touchOutsideTaskMenuToDismiss() {
+ mLauncher.touchOutsideContainer(mMenu, false);
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Qsb.java b/tests/tapl/com/android/launcher3/tapl/Qsb.java
index 7f3f61d..fe2a63d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Qsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/Qsb.java
@@ -22,13 +22,18 @@
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
+import java.util.regex.Pattern;
+
/**
* Operations on qsb from either Home screen or AllApp screen.
*/
-public abstract class Qsb {
+public abstract class Qsb implements SearchInputSource {
private static final String ASSISTANT_APP_PACKAGE = "com.google.android.googlequicksearchbox";
private static final String ASSISTANT_ICON_RES_ID = "mic_icon";
+ private static final String LENS_ICON_RES_ID = "lens_icon";
+ private static final Pattern LENS_APP_RES_PATTERN = Pattern.compile(
+ ASSISTANT_APP_PACKAGE + ":id/lens.*");
protected final LauncherInstrumentation mLauncher;
private final UiObject2 mContainer;
private final String mQsbResName;
@@ -76,6 +81,37 @@
}
/**
+ * Launches lens app by tapping lens icon on qsb.
+ */
+ @NonNull
+ public LaunchedAppState launchLens() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to click lens icon button");
+ LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ UiObject2 lensIcon = mLauncher.waitForLauncherObject(LENS_ICON_RES_ID);
+
+ LauncherInstrumentation.log("Qsb.launchLens before click "
+ + lensIcon.getVisibleCenter() + " in "
+ + mLauncher.getVisibleBounds(lensIcon));
+
+ mLauncher.clickLauncherObject(lensIcon);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
+ // Package name is not enough to check if the app is launched, because many
+ // elements are having googlequicksearchbox as package name. So it checks if the
+ // corresponding app resource is displayed
+ BySelector selector = By.res(LENS_APP_RES_PATTERN);
+ mLauncher.assertTrue(
+ "Lens app didn't start: (" + selector + ")",
+ mLauncher.getDevice().wait(Until.hasObject(selector),
+ LauncherInstrumentation.WAIT_TIME_MS)
+ );
+ return new LaunchedAppState(mLauncher);
+ }
+ }
+ }
+
+ /**
* Show search result page from tapping qsb.
*/
public SearchResultFromQsb showSearchResult() {
@@ -92,6 +128,16 @@
}
}
+ @Override
+ public LauncherInstrumentation getLauncher() {
+ return mLauncher;
+ }
+
+ @Override
+ public SearchResultFromQsb getSearchResultForInput() {
+ return createSearchResult();
+ }
+
protected SearchResultFromQsb createSearchResult() {
return new SearchResultFromQsb(mLauncher);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchInputSource.java b/tests/tapl/com/android/launcher3/tapl/SearchInputSource.java
new file mode 100644
index 0000000..032948f
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/SearchInputSource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+import com.android.launcher3.testing.shared.TestProtocol;
+
+/**
+ * Container that can be used to input a search query and retrieve a {@link SearchResultFromQsb}
+ * instance.
+ */
+interface SearchInputSource {
+ String INPUT_RES = "input";
+
+ /** Set the already focused search input edit text and update search results. */
+ default SearchResultFromQsb searchForInput(String input) {
+ LauncherInstrumentation launcher = getLauncher();
+ try (LauncherInstrumentation.Closable c = launcher.addContextLayer(
+ "want to search for result with an input");
+ LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
+ launcher.executeAndWaitForLauncherEvent(
+ () -> {
+ UiObject2 editText = launcher.waitForLauncherObject(INPUT_RES);
+ launcher.waitForObjectFocused(editText, "search input");
+ editText.setText(input);
+ },
+ event -> TestProtocol.SEARCH_RESULT_COMPLETE.equals(event.getClassName()),
+ () -> "Didn't receive a search result completed message", "searching");
+ return getSearchResultForInput();
+ }
+ }
+
+ /** This method requires public access, however should not be called in tests. */
+ LauncherInstrumentation getLauncher();
+
+ /** This method requires public access, however should not be called in tests. */
+ SearchResultFromQsb getSearchResultForInput();
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
index d02e747..f0a8aa2 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
@@ -25,9 +25,7 @@
/**
* Operations on search result page opened from qsb.
*/
-public class SearchResultFromQsb {
- // The input resource id in the search box.
- private static final String INPUT_RES = "input";
+public class SearchResultFromQsb implements SearchInputSource {
private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background";
// This particular ID change should happen with caution
@@ -39,15 +37,6 @@
mLauncher.waitForLauncherObject("search_container_all_apps");
}
- /** Set the input to the search input edit text and update search results. */
- public void searchForInput(String input) {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to search for result with an input");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.waitForLauncherObject(INPUT_RES).setText(input);
- }
- }
-
/** Find the app from search results with app name. */
public AppIcon findAppIcon(String appName) {
UiObject2 icon = mLauncher.waitForLauncherObject(By.clazz(TextView.class).text(appName));
@@ -91,7 +80,7 @@
* Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only.
* @param tapRight Tap on the right of bottom sheet if true, or left otherwise.
*/
- public Workspace dismissByTappingOutsideForTablet(boolean tapRight) {
+ public void dismissByTappingOutsideForTablet(boolean tapRight) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to tap outside AllApps bottom sheet on the "
@@ -101,8 +90,22 @@
mLauncher.touchOutsideContainer(allAppsBottomSheet, tapRight);
try (LauncherInstrumentation.Closable tapped = mLauncher.addContextLayer(
"tapped outside AllApps bottom sheet")) {
- return mLauncher.getWorkspace();
+ verifyVisibleContainerOnDismiss();
}
}
}
+
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getWorkspace();
+ }
+
+ @Override
+ public LauncherInstrumentation getLauncher() {
+ return mLauncher;
+ }
+
+ @Override
+ public SearchResultFromQsb getSearchResultForInput() {
+ return this;
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
index 6c6ab05..00291a3 100644
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
+++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromTaskbarQsb.java
@@ -45,4 +45,9 @@
protected TaskbarSearchWebSuggestion createWebSuggestion(UiObject2 webSuggestion) {
return new TaskbarSearchWebSuggestion(mLauncher, webSuggestion);
}
+
+ @Override
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getLaunchedAppState().assertTaskbarVisible();
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java b/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java
index ce1c3c0..2870877 100644
--- a/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java
+++ b/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.tapl;
-/** Launchable that can serve as a source for dragging and dropping to splitscreen. */
+/** {@link Launchable} that can serve as a source for dragging and dropping to splitscreen. */
interface SplitscreenDragSource {
/**
@@ -35,5 +35,6 @@
}
}
+ /** This method requires public access, however should not be called in tests. */
Launchable getLaunchable();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Taskbar.java b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
index 8671738..da26694 100644
--- a/tests/tapl/com/android/launcher3/tapl/Taskbar.java
+++ b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.tapl;
+import static android.view.KeyEvent.KEYCODE_META_RIGHT;
+
import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING;
import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING;
@@ -92,7 +94,7 @@
/**
* Opens the Taskbar all apps page.
*/
- public AllAppsFromTaskbar openAllApps() {
+ public TaskbarAllApps openAllApps() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to open taskbar all apps");
LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
@@ -101,7 +103,26 @@
mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID),
getAllAppsButtonSelector()));
- return new AllAppsFromTaskbar(mLauncher);
+ return getAllApps();
+ }
+ }
+
+ /** Opens the Taskbar all apps page with the meta keyboard shortcut. */
+ public TaskbarAllApps openAllAppsFromKeyboardShortcut() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ mLauncher.getDevice().pressKeyCode(KEYCODE_META_RIGHT);
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "pressed meta key")) {
+ return getAllApps();
+ }
+ }
+ }
+
+ /** Returns {@link TaskbarAllApps} if it is open, otherwise fails. */
+ public TaskbarAllApps getAllApps() {
+ try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to get taskbar all apps object")) {
+ return new TaskbarAllApps(mLauncher);
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
similarity index 86%
rename from tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
rename to tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
index 0e0291f..3d39041 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
+++ b/tests/tapl/com/android/launcher3/tapl/TaskbarAllApps.java
@@ -23,9 +23,9 @@
/**
* Operations on AllApps opened from the Taskbar.
*/
-public class AllAppsFromTaskbar extends AllApps {
+public class TaskbarAllApps extends AllApps {
- AllAppsFromTaskbar(LauncherInstrumentation launcher) {
+ TaskbarAllApps(LauncherInstrumentation launcher) {
super(launcher);
}
@@ -68,4 +68,14 @@
public TaskbarAllAppsQsb getQsb() {
return new TaskbarAllAppsQsb(mLauncher, verifyActiveContainer());
}
+
+ @Override
+ protected void verifyVisibleContainerOnDismiss() {
+ mLauncher.getLaunchedAppState().assertTaskbarVisible();
+ }
+
+ @Override
+ public boolean isHomeState() {
+ return false;
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
index 8f51d04..ec1cbd8 100644
--- a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
+++ b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
@@ -15,6 +15,16 @@
*/
package com.android.launcher3.tapl;
+import static com.android.launcher3.tapl.Launchable.DEFAULT_DRAG_STEPS;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.view.MotionEvent;
+
+import androidx.test.uiautomator.UiObject2;
+
/** The resize frame that is shown for a widget on the workspace. */
public class WidgetResizeFrame {
@@ -34,4 +44,36 @@
mLauncher.getDevice().pressHome();
}
}
+
+ /** Resizes the widget to double its height, and returns the resize frame. */
+ public WidgetResizeFrame resize() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to resize the widget frame.")) {
+ UiObject2 widget = mLauncher.waitForLauncherObject("widget_resize_frame");
+ UiObject2 bottomResizeHandle =
+ mLauncher.waitForLauncherObject("widget_resize_bottom_handle");
+ Rect originalWidgetSize = widget.getVisibleBounds();
+ Point targetStart = bottomResizeHandle.getVisibleCenter();
+ Point targetDest = bottomResizeHandle.getVisibleCenter();
+ targetDest.offset(0, originalWidgetSize.height());
+
+ final long downTime = SystemClock.uptimeMillis();
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetStart,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+ mLauncher.movePointer(targetStart, targetDest, DEFAULT_DRAG_STEPS,
+ true, downTime, downTime, true,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+ mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, targetDest,
+ LauncherInstrumentation.GestureScope.DONT_EXPECT_PILFER);
+
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "want to return resized widget resize frame")) {
+ float newHeight = mLauncher.waitForLauncherObject(
+ "widget_resize_frame").getVisibleBounds().height();
+ assertTrue("Widget not resized.", newHeight >= originalWidgetSize.height() * 2);
+ return this;
+ }
+ }
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 79b54ba..105bc3b 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -34,7 +34,8 @@
/**
* All widgets container.
*/
-public final class Widgets extends LauncherInstrumentation.VisibleContainer {
+public final class Widgets extends LauncherInstrumentation.VisibleContainer
+ implements KeyboardQuickSwitchSource {
private static final int FLING_STEPS = 10;
private static final int SCROLL_ATTEMPTS = 60;
@@ -43,6 +44,21 @@
verifyActiveContainer();
}
+ @Override
+ public LauncherInstrumentation getLauncher() {
+ return mLauncher;
+ }
+
+ @Override
+ public LauncherInstrumentation.ContainerType getStartingContainerType() {
+ return getContainerType();
+ }
+
+ @Override
+ public boolean isHomeState() {
+ return true;
+ }
+
/**
* Flings forward (down) and waits the fling's end.
*/
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 6f6f292..2a2a83f 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -16,6 +16,7 @@
package com.android.launcher3.tapl;
+import static android.view.KeyEvent.KEYCODE_META_RIGHT;
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED;
import static com.android.launcher3.testing.shared.TestProtocol.ALL_APPS_STATE_ORDINAL;
@@ -114,6 +115,20 @@
}
}
+ /** Opens the Launcher all apps page with the meta keyboard shortcut. */
+ public HomeAllApps openAllAppsFromKeyboardShortcut() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c =
+ mLauncher.addContextLayer("want to open all apps search")) {
+ verifyActiveContainer();
+ mLauncher.getDevice().pressKeyCode(KEYCODE_META_RIGHT);
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "pressed meta key")) {
+ return new HomeAllApps(mLauncher);
+ }
+ }
+ }
+
/**
* Returns the home qsb.
*
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
index 141476c..5a4d562 100644
--- a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
+++ b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
@@ -19,7 +19,7 @@
import java.util.function.Supplier;
-/** Launchable that can serve as a source for dragging and dropping to the workspace. */
+/** {@link Launchable} that can serve as a source for dragging and dropping to the workspace. */
interface WorkspaceDragSource {
/**