Merge "Support simple A-Z search in Taskbar All Apps." into udc-dev
diff --git a/quickstep/res/layout/keyboard_quick_switch_view.xml b/quickstep/res/layout/keyboard_quick_switch_view.xml
index 5c20a2d..64d3f67 100644
--- a/quickstep/res/layout/keyboard_quick_switch_view.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_view.xml
@@ -25,7 +25,8 @@
android:clipToOutline="true"
android:alpha="0"
android:visibility="invisible"
- android:focusableInTouchMode="true">
+ android:focusableInTouchMode="true"
+ app:layout_ignoreInsets="true">
<HorizontalScrollView
android:id="@+id/scroll_view"
diff --git a/quickstep/res/layout/taskbar_edu_tooltip.xml b/quickstep/res/layout/taskbar_edu_tooltip.xml
index 3fcd713..657066c 100644
--- a/quickstep/res/layout/taskbar_edu_tooltip.xml
+++ b/quickstep/res/layout/taskbar_edu_tooltip.xml
@@ -20,7 +20,6 @@
android:layout_marginBottom="16dp"
android:clipChildren="false"
android:clipToPadding="false"
- android:fitsSystemWindows="true"
android:focusable="true"
android:importantForAccessibility="yes"
android:gravity="center"
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 72e7a42..3df50c9 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -53,8 +53,7 @@
<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>
- <!-- no translation found for back_gesture_tutorial_title (1944737946101059789) -->
- <skip />
+ <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>
@@ -73,12 +72,11 @@
<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>
- <!-- no translation found for overview_gesture_tutorial_title (4125835002668708720) -->
- <skip />
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"Apps wechseln"</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>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Wiederholen"</string>
+ <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Noch einmal versuchen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Sehr gut!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Anleitung <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
<string name="allset_title" msgid="5021126669778966707">"Fertig!"</string>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index a0f23cb..4badb49 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -53,8 +53,7 @@
<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>
- <!-- no translation found for back_gesture_tutorial_title (1944737946101059789) -->
- <skip />
+ <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>
@@ -73,8 +72,7 @@
<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>
- <!-- no translation found for overview_gesture_tutorial_title (4125835002668708720) -->
- <skip />
+ <string name="overview_gesture_tutorial_title" msgid="4125835002668708720">"ऐप्लिकेशन के बीच स्विच करें"</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>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 2134d14..5ac931d 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/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">"< 1 ր"</string>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 6782013..6f30fe6 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -100,7 +100,7 @@
<string name="taskbar_edu_opened" msgid="3950252793551919129">"タスクバーの説明を開きました"</string>
<string name="taskbar_edu_closed" msgid="126643734478892862">"タスクバーの説明を閉じました"</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">"[設定] でジェスチャー ナビゲーションを ON にすると、タスクバーを自動的に非表示にできます"</string>
<string name="taskbar_edu_features" msgid="3320337287472848162">"タスクバーの各種機能"</string>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 66ffae5..a88d5e1 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/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">"< 1 мин"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index de3b511..fa6e5d2 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -109,7 +109,7 @@
<string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</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_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>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 79aba94..34285b7 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -114,7 +114,7 @@
<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_quick_settings" msgid="227662894293189391">"Ыкчам жөндөөлөр"</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>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index fe0aff2..fe4e954 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -109,7 +109,7 @@
<string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</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_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>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 4c69b2b..d12513d 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -109,7 +109,7 @@
<string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</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_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>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index ae3c445..0433177 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -24,7 +24,7 @@
<string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ilovadan foydalanish sozlamalari"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Hammasini tozalash"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Yaqinda ishlatilgan ilovalar"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"Oxirgi ilovalar"</string>
<string name="task_view_closed" msgid="9170038230110856166">"Vazifalar yopildi"</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 daqiqa"</string>
@@ -109,7 +109,7 @@
<string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
<string name="taskbar_edu_done" msgid="6880178093977704569">"Tayyor"</string>
<string name="taskbar_button_home" msgid="2151398979630664652">"Bosh ekran"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Maxsus imkoniyatlar"</string>
+ <string name="taskbar_button_a11y" msgid="5241161324875094465">"Qulayliklar"</string>
<string name="taskbar_button_back" msgid="8558862226461164514">"Orqaga"</string>
<string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME tugmasi"</string>
<string name="taskbar_button_recents" msgid="7273376136216613134">"Oxirgilar"</string>
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
index c165750..ed4a212 100644
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.Utilities.isRunningInTestHarness;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
@@ -80,10 +81,13 @@
* Currently this animation just force stashes the taskbar in Overview.
*/
public Animator createAnimToRecentsState(RecentsState toState, long duration) {
- boolean useStashedLauncherState = toState.hasOverviewActions();
- boolean stashedLauncherState =
- useStashedLauncherState && FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get()
- && toState == RecentsState.MODAL_TASK;
+ // Force stash the taskbar in overview modal state or when going home. We do not force
+ // stash on home when running in a test as 3p launchers rely on taskbar instead of hotseat.
+ boolean isGoingHome = toState == RecentsState.HOME && !isRunningInTestHarness();
+ boolean useStashedLauncherState = toState.hasOverviewActions() || isGoingHome;
+ boolean stashedLauncherState = useStashedLauncherState && (
+ (FeatureFlags.ENABLE_GRID_ONLY_OVERVIEW.get() && toState == RecentsState.MODAL_TASK)
+ || isGoingHome);
TaskbarStashController stashController = mControllers.taskbarStashController;
// Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected.
// For all other states, just use the current stashed-in-app setting (e.g. if long clicked).
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 941b4b0..c4255bf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -49,7 +49,8 @@
public static final int ALPHA_INDEX_STASHED = 0;
public static final int ALPHA_INDEX_HOME_DISABLED = 1;
public static final int ALPHA_INDEX_ASSISTANT_INVOKED = 2;
- private static final int NUM_ALPHA_CHANNELS = 3;
+ public static final int ALPHA_INDEX_HIDDEN_WHILE_DREAMING = 3;
+ private static final int NUM_ALPHA_CHANNELS = 4;
/**
* The SharedPreferences key for whether the stashed handle region is dark.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 60b5c0d..77f681e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -53,6 +53,10 @@
// Translation property for taskbar background.
private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset);
+ // Used to fade in/out the entirety of the taskbar, for a smooth transition before/after sysui
+ // changes the inset visibility.
+ private final AnimatedFloat mTaskbarAlpha = new AnimatedFloat(this::updateTaskbarAlpha);
+
// Initialized in init.
private TaskbarControllers mControllers;
private TaskbarStashViaTouchController mTaskbarStashViaTouchController;
@@ -83,6 +87,9 @@
mAssistantBgTaskbar.value = 1;
mBgOverride.value = 1;
updateBackgroundAlpha();
+
+ mTaskbarAlpha.value = 1;
+ updateTaskbarAlpha();
}
public void onDestroy() {
@@ -127,6 +134,10 @@
return mBgOffset;
}
+ public AnimatedFloat getTaskbarAlpha() {
+ return mTaskbarAlpha;
+ }
+
/**
* Make updates when configuration changes.
*/
@@ -165,6 +176,10 @@
updateOnBackgroundNavButtonColorIntensity();
}
+ private void updateTaskbarAlpha() {
+ mTaskbarDragLayer.setAlpha(mTaskbarAlpha.value);
+ }
+
@Override
public void setCornerRoundness(float cornerRoundness) {
mTaskbarDragLayer.setCornerRoundness(cornerRoundness);
@@ -197,6 +212,7 @@
pw.println(prefix + "TaskbarDragLayerController:");
pw.println(prefix + "\tmBgOffset=" + mBgOffset.value);
+ pw.println(prefix + "\tmTaskbarAlpha=" + mTaskbarAlpha.value);
pw.println(prefix + "\tmFolderMargin=" + mFolderMargin);
pw.println(prefix + "\tmLastSetBackgroundAlpha=" + mLastSetBackgroundAlpha);
pw.println(prefix + "\t\tmBgOverride=" + mBgOverride.value);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index edcd4c8..03d08eb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -1,17 +1,17 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.systemui.shared.system.QuickStepContract.SCREEN_STATE_OFF;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_STATE_MASK;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK;
+import static com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_ASLEEP;
import android.app.KeyguardManager;
@@ -29,7 +29,7 @@
| SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING
| SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED
| SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
- | SYSUI_STATE_SCREEN_STATE_MASK;
+ | SYSUI_STATE_WAKEFULNESS_MASK;
// If any of these SysUi flags (via QuickstepContract) is set, the device to be considered
// locked.
@@ -75,13 +75,13 @@
keyguardOccluded);
updateIconsForBouncer();
- boolean screenOffOrTransitioningOff = (systemUiStateFlags & SYSUI_STATE_SCREEN_ON) == 0;
- boolean closeFloatingViews = keyguardShowing || screenOffOrTransitioningOff;
+ boolean asleepOrGoingToSleep = (systemUiStateFlags & SYSUI_STATE_AWAKE) == 0;
+ boolean closeFloatingViews = keyguardShowing || asleepOrGoingToSleep;
if (closeFloatingViews) {
- // animate the closing of the views, unless the screen is already fully turned off.
+ // animate the closing of the views, unless the screen is already asleep.
boolean animateViewClosing =
- (systemUiStateFlags & SYSUI_STATE_SCREEN_STATE_MASK) != SCREEN_STATE_OFF;
+ (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_ASLEEP;
AbstractFloatingView.closeOpenViews(mContext, animateViewClosing, TYPE_ALL);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index cf8148e..9bc8cdd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -22,12 +22,16 @@
import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
import static com.android.systemui.animation.Interpolators.EMPHASIZED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK;
+import static com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_AWAKE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.os.SystemClock;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -81,21 +85,37 @@
*
* This is cleared as soon as the screen begins to transition off.
*/
- private static final int FLAG_SCREEN_ON = 1 << 3;
+ private static final int FLAG_AWAKE = 1 << 3;
/**
- * Captures whether the launcher was active at the time the FLAG_SCREEN_ON was cleared.
- * Always cleared when FLAG_SCREEN_ON is set.
+ * Captures whether the launcher was active at the time the FLAG_AWAKE was cleared.
+ * Always cleared when FLAG_AWAKE is set.
* <p>
- * FLAG_RESUMED will be cleared when the screen is off, since all apps get paused at this point.
- * Thus, this flag indicates whether the launcher will be shown when the screen gets turned on
+ * FLAG_RESUMED will be cleared when the device is asleep, since all apps get paused at this
+ * point. Thus, this flag indicates whether the launcher will be shown when the device wakes up
* again.
*/
- private static final int FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF = 1 << 4;
+ private static final int FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE = 1 << 4;
- /** Whether the device is currently locked. */
+ /**
+ * Whether the device is currently locked.
+ * <ul>
+ * <li>While locked, the taskbar is always stashed.<li/>
+ * <li>Navbar animations on FLAG_DEVICE_LOCKED transitions will get special treatment.</li>
+ * </ul>
+ */
private static final int FLAG_DEVICE_LOCKED = 1 << 5;
+ /**
+ * Whether the complete taskbar is completely hidden (neither visible stashed or unstashed).
+ * This is tracked to allow a nice transition of the taskbar before SysUI forces it away by
+ * hiding the inset.
+ *
+ * This flag is predominanlty set while FLAG_DEVICE_LOCKED is set, thus the taskbar's invisible
+ * resting state while hidden is stashed.
+ */
+ private static final int FLAG_TASKBAR_HIDDEN = 1 << 6;
+
private static final int FLAGS_LAUNCHER_ACTIVE = FLAG_RESUMED | FLAG_TRANSITION_TO_RESUMED;
/** Equivalent to an int with all 1s for binary operation purposes */
private static final int FLAGS_ALL = ~0;
@@ -104,11 +124,21 @@
private static final float TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
private static final float TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT = 0.25f;
+ /**
+ * Delay for the taskbar fade-in.
+ *
+ * Helps to avoid visual noise when unlocking successfully via SFPS, and the device transitions
+ * to launcher directly. The delay avoids the navbar to become briefly visible. The duration
+ * is the same as in SysUI, see http://shortn/_uNSbDoRUSr.
+ */
+ private static final long TASKBAR_SHOW_DELAY_MS = 250;
+
private final AnimatedFloat mIconAlignment =
new AnimatedFloat(this::onIconAlignmentRatioChanged);
private TaskbarControllers mControllers;
private AnimatedFloat mTaskbarBackgroundAlpha;
+ private AnimatedFloat mTaskbarAlpha;
private AnimatedFloat mTaskbarCornerRoundness;
private MultiProperty mIconAlphaForHome;
private QuickstepLauncher mLauncher;
@@ -117,6 +147,9 @@
private int mState;
private LauncherState mLauncherState = LauncherState.NORMAL;
+ // Time when FLAG_TASKBAR_HIDDEN was last cleared, SystemClock.elapsedRealtime (milliseconds).
+ private long mLastUnlockTimeMs = 0;
+
private @Nullable TaskBarRecentsAnimationListener mTaskBarRecentsAnimationListener;
private boolean mIsAnimatingToLauncher;
@@ -187,6 +220,7 @@
mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController
.getTaskbarBackgroundAlpha();
+ mTaskbarAlpha = mControllers.taskbarDragLayerController.getTaskbarAlpha();
mTaskbarCornerRoundness = mControllers.getTaskbarCornerRoundness();
mIconAlphaForHome = mControllers.taskbarViewController
.getTaskbarIconAlpha().get(ALPHA_INDEX_HOME);
@@ -265,20 +299,29 @@
/** SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values. */
public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) {
- final boolean prevScreenIsOn = hasAnyFlag(FLAG_SCREEN_ON);
- final boolean currScreenIsOn = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_ON);
+ final boolean prevIsAwake = hasAnyFlag(FLAG_AWAKE);
+ final boolean currIsAwake = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_AWAKE);
- updateStateForFlag(FLAG_SCREEN_ON, currScreenIsOn);
- if (prevScreenIsOn != currScreenIsOn) {
+ updateStateForFlag(FLAG_AWAKE, currIsAwake);
+ if (prevIsAwake != currIsAwake) {
// The screen is switching between on/off. When turning off, capture whether the
// launcher is active and memoize this state.
- updateStateForFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF,
- prevScreenIsOn && hasAnyFlag(FLAGS_LAUNCHER_ACTIVE));
+ updateStateForFlag(FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE,
+ prevIsAwake && hasAnyFlag(FLAGS_LAUNCHER_ACTIVE));
}
boolean isDeviceLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED);
updateStateForFlag(FLAG_DEVICE_LOCKED, isDeviceLocked);
+ // Taskbar is hidden whenever the device is dreaming. The dreaming state includes the
+ // interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in
+ // when the device is asleep, the second condition extends ensures that the transition from
+ // and to the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar
+ // hide/reveal animation timings.
+ boolean isTaskbarHidden = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_DEVICE_DREAMING)
+ || (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_AWAKE;
+ updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden);
+
if (skipAnim) {
applyState(0);
} else {
@@ -377,7 +420,7 @@
}
}
- if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE | FLAG_SCREEN_ON)) {
+ if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE | FLAG_AWAKE)) {
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -406,6 +449,41 @@
AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext);
}
+ if (hasAnyFlag(changedFlags, FLAG_TASKBAR_HIDDEN) && !hasAnyFlag(FLAG_TASKBAR_HIDDEN)) {
+ // Take note of the current time, as the taskbar is made visible again.
+ mLastUnlockTimeMs = SystemClock.elapsedRealtime();
+ }
+
+ boolean isHidden = hasAnyFlag(FLAG_TASKBAR_HIDDEN);
+ float taskbarAlpha = isHidden ? 0 : 1;
+ if (mTaskbarAlpha.isAnimating() || mTaskbarAlpha.value != taskbarAlpha) {
+ Animator taskbarVisibility = mTaskbarAlpha.animateToValue(taskbarAlpha);
+
+ taskbarVisibility.setDuration(duration);
+ if (isHidden) {
+ // Stash the transient taskbar once the taskbar is not visible. This reduces
+ // visual noise when unlocking the device afterwards.
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ TaskbarStashController stashController =
+ mControllers.taskbarStashController;
+ stashController.updateAndAnimateTransientTaskbar(
+ /* stash */ true, /* duration */ 0);
+ }
+ });
+ } else {
+ // delay the fade in animation a bit to reduce visual noise when waking up a device
+ // with a fingerprint reader. This should only be done when the device was woken
+ // up via fingerprint reader, however since this information is currently not
+ // available, opting to always delay the fade-in a bit.
+ long durationSinceLastUnlockMs = SystemClock.elapsedRealtime() - mLastUnlockTimeMs;
+ taskbarVisibility.setStartDelay(
+ Math.max(0, TASKBAR_SHOW_DELAY_MS - durationSinceLastUnlockMs));
+ }
+ animatorSet.play(taskbarVisibility);
+ }
+
float backgroundAlpha = isInLauncher && isTaskbarAlignedWithHotseat() ? 0 : 1;
// Don't animate if background has reached desired value.
@@ -573,10 +651,10 @@
/** Whether the launcher is considered active. */
private boolean isInLauncher() {
- if (hasAnyFlag(FLAG_SCREEN_ON)) {
+ if (hasAnyFlag(FLAG_AWAKE)) {
return hasAnyFlag(FLAGS_LAUNCHER_ACTIVE);
} else {
- return hasAnyFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF);
+ return hasAnyFlag(FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE);
}
}
@@ -677,9 +755,9 @@
appendFlag(result, flags, FLAG_TRANSITION_TO_RESUMED, "transition_to_resumed");
appendFlag(result, flags, FLAG_LAUNCHER_IN_STATE_TRANSITION,
"launcher_in_state_transition");
- appendFlag(result, flags, FLAG_SCREEN_ON, "screen_on");
- appendFlag(result, flags, FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF,
- "launcher_active_at_screen_off");
+ appendFlag(result, flags, FLAG_AWAKE, "awake");
+ appendFlag(result, flags, FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE,
+ "was_active_while_awake");
appendFlag(result, flags, FLAG_DEVICE_LOCKED, "device_locked");
return result.toString();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index c537106..3d8bf9e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.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.TASKBAR_NOT_DESTROYED_TAG;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
@@ -63,6 +64,7 @@
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
import java.io.PrintWriter;
+import java.util.StringJoiner;
/**
* Class to manage taskbar lifecycle
@@ -147,6 +149,8 @@
@Override
public void onConfigurationChanged(Configuration newConfig) {
+ debugWhyTaskbarNotDestroyed(
+ "TaskbarManager#mComponentCallbacks.onConfigurationChanged: " + newConfig);
DeviceProfile dp = mUserUnlocked
? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext)
: null;
@@ -179,6 +183,9 @@
}
}
+ debugWhyTaskbarNotDestroyed("ComponentCallbacks#onConfigurationChanged() "
+ + "configDiffForRecreate="
+ + Configuration.configurationDiffToString(configDiffForRecreate));
if ((configDiffForRecreate & configsRequiringRecreate) != 0) {
recreateTaskbar();
} else {
@@ -207,6 +214,8 @@
mNavMode = info.navigationMode;
recreateTaskbar();
}
+ debugWhyTaskbarNotDestroyed("DisplayInfoChangeListener#"
+ + mDisplayController.getChangeFlagsString(flags));
};
mNavMode = mDisplayController.getInfo().navigationMode;
mDisplayController.addChangeListener(mDispInfoChangeListener);
@@ -227,10 +236,13 @@
new IntentFilter(ACTION_SHOW_TASKBAR),
RECEIVER_NOT_EXPORTED);
});
+
+ debugWhyTaskbarNotDestroyed("TaskbarManager created");
recreateTaskbar();
}
private void destroyExistingTaskbar() {
+ debugWhyTaskbarNotDestroyed("destroyExistingTaskbar: " + mTaskbarActivityContext);
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.onDestroy();
if (!FLAG_HIDE_NAVBAR_WINDOW) {
@@ -274,7 +286,12 @@
if (mActivity == activity) {
return;
}
+ if (mActivity != null) {
+ mActivity.removeOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
+ }
mActivity = activity;
+ debugWhyTaskbarNotDestroyed("Set mActivity=" + mActivity);
+ mActivity.addOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
getUnfoldTransitionProgressProviderForActivity(activity);
mUnfoldProgressProvider.setSourceProvider(unfoldTransitionProgressProvider);
@@ -318,7 +335,9 @@
*/
public void clearActivity(@NonNull StatefulActivity activity) {
if (mActivity == activity) {
+ mActivity.removeOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
mActivity = null;
+ debugWhyTaskbarNotDestroyed("clearActivity");
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.setUIController(TaskbarUIController.DEFAULT);
}
@@ -338,8 +357,12 @@
destroyExistingTaskbar();
- boolean isTaskBarEnabled = dp != null && isTaskbarPresent(dp);
- if (!isTaskBarEnabled) {
+ boolean isTaskbarEnabled = dp != null && isTaskbarPresent(dp);
+ debugWhyTaskbarNotDestroyed("recreateTaskbar: isTaskbarEnabled=" + isTaskbarEnabled
+ + " [dp != null (i.e. mUserUnlocked)]=" + (dp != null)
+ + " FLAG_HIDE_NAVBAR_WINDOW=" + FLAG_HIDE_NAVBAR_WINDOW
+ + " dp.isTaskbarPresent=" + (dp == null ? "null" : dp.isTaskbarPresent));
+ if (!isTaskbarEnabled) {
SystemUiProxy.INSTANCE.get(mContext)
.notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
return;
@@ -440,6 +463,11 @@
* Called when the manager is no longer needed
*/
public void destroy() {
+ debugWhyTaskbarNotDestroyed("TaskbarManager#destroy()");
+ if (mActivity != null) {
+ mActivity.removeOnDeviceProfileChangeListener(mDebugActivityDeviceProfileChanged);
+ }
+
UI_HELPER_EXECUTOR.execute(
() -> mTaskbarBroadcastReceiver.unregisterReceiverSafely(mContext));
destroyExistingTaskbar();
@@ -464,4 +492,46 @@
mTaskbarActivityContext.dumpLogs(prefix + "\t", pw);
}
}
+
+ /** Temp logs for b/254119092. */
+ public void debugWhyTaskbarNotDestroyed(String debugReason) {
+ StringJoiner log = new StringJoiner("\n");
+ log.add(debugReason);
+
+ boolean activityTaskbarPresent = mActivity != null
+ && mActivity.getDeviceProfile().isTaskbarPresent;
+ boolean contextTaskbarPresent = mUserUnlocked
+ && LauncherAppState.getIDP(mContext).getDeviceProfile(mContext).isTaskbarPresent;
+ if (activityTaskbarPresent == contextTaskbarPresent) {
+ log.add("mActivity and mContext agree taskbarIsPresent=" + contextTaskbarPresent);
+ Log.d(TASKBAR_NOT_DESTROYED_TAG, log.toString());
+ return;
+ }
+
+ log.add("mActivity and mContext device profiles have different values, add more logs.");
+
+ log.add("\tmActivity logs:");
+ log.add("\t\tmActivity=" + mActivity);
+ if (mActivity != null) {
+ log.add("\t\tmActivity.getResources().getConfiguration()="
+ + mActivity.getResources().getConfiguration());
+ log.add("\t\tmActivity.getDeviceProfile().isTaskbarPresent="
+ + activityTaskbarPresent);
+ }
+ log.add("\tmContext logs:");
+ log.add("\t\tmContext=" + mContext);
+ log.add("\t\tmContext.getResources().getConfiguration()="
+ + mContext.getResources().getConfiguration());
+ if (mUserUnlocked) {
+ log.add("\t\tLauncherAppState.getIDP().getDeviceProfile(mContext).isTaskbarPresent="
+ + contextTaskbarPresent);
+ } else {
+ log.add("\t\tCouldn't get DeviceProfile because !mUserUnlocked");
+ }
+
+ Log.d(TASKBAR_NOT_DESTROYED_TAG, log.toString());
+ }
+
+ private final DeviceProfile.OnDeviceProfileChangeListener mDebugActivityDeviceProfileChanged =
+ dp -> debugWhyTaskbarNotDestroyed("mActivity onDeviceProfileChanged");
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index c43b621..5f11740 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -50,6 +50,7 @@
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
+import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -68,6 +69,8 @@
import com.android.quickstep.SystemUiProxy;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.StringJoiner;
import java.util.function.IntPredicate;
@@ -184,6 +187,36 @@
// Auto stashes when user has not interacted with the Taskbar after X ms.
private static final long NO_TOUCH_TIMEOUT_TO_STASH_MS = 5000;
+ /**
+ * The default stash animation, morphing the taskbar into the navbar.
+ */
+ private static final int TRANSITION_DEFAULT = 0;
+ /**
+ * Transitioning from launcher to app. Same as TRANSITION_DEFAULT, differs in internal
+ * animation timings.
+ */
+ private static final int TRANSITION_HOME_TO_APP = 1;
+ /**
+ * Fading the navbar in and out, where the taskbar jumpcuts in and out at the very begin/end of
+ * the transition. Used to transition between the hotseat and navbar` without the stash/unstash
+ * transition.
+ */
+ private static final int TRANSITION_HANDLE_FADE = 2;
+ /**
+ * Same as TRANSITION_DEFAULT, but exclusively used during an "navbar unstash to hotseat
+ * animation" bound to the progress of a swipe gesture. It differs from TRANSITION_DEFAULT
+ * by not scaling the height of the taskbar background.
+ */
+ private static final int TRANSITION_UNSTASH_SUW_MANUAL = 3;
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ TRANSITION_DEFAULT,
+ TRANSITION_HOME_TO_APP,
+ TRANSITION_HANDLE_FADE,
+ TRANSITION_UNSTASH_SUW_MANUAL,
+ })
+ private @interface StashAnimation {}
+
private final TaskbarActivityContext mActivity;
private final SharedPreferences mPrefs;
private final int mStashedHeight;
@@ -472,9 +505,16 @@
}
/**
- * Stash or unstashes the transient taskbar.
+ * Stash or unstashes the transient taskbar, using the default TASKBAR_STASH_DURATION.
*/
public void updateAndAnimateTransientTaskbar(boolean stash) {
+ updateAndAnimateTransientTaskbar(stash, TASKBAR_STASH_DURATION);
+ }
+
+ /**
+ * Stash or unstashes the transient taskbar.
+ */
+ public void updateAndAnimateTransientTaskbar(boolean stash, long duration) {
if (!DisplayController.isTransientTaskbar(mActivity)) {
return;
}
@@ -553,8 +593,7 @@
createAnimToIsStashed(
/* isStashed= */ false,
placeholderDuration,
- /* animateBg= */ false,
- /* changedFlags=*/ 0);
+ TRANSITION_UNSTASH_SUW_MANUAL);
animation.play(mAnimator);
}
@@ -562,10 +601,15 @@
* Create a stash animation and save to {@link #mAnimator}.
* @param isStashed whether it's a stash animation or an unstash animation
* @param duration duration of the animation
- * @param animateBg whether the taskbar's background should be animated
+ * @param animationType what transition type to play.
*/
- private void createAnimToIsStashed(boolean isStashed, long duration, boolean animateBg,
- int changedFlags) {
+ private void createAnimToIsStashed(boolean isStashed, long duration,
+ @StashAnimation int animationType) {
+ if (animationType == TRANSITION_UNSTASH_SUW_MANUAL && isStashed) {
+ // The STASH_ANIMATION_SUW_MANUAL must only be used during an unstash animation.
+ Log.e(TAG, "Illegal arguments:Using TRANSITION_UNSTASH_SUW_MANUAL to stash taskbar");
+ }
+
if (mAnimator != null) {
mAnimator.cancel();
}
@@ -591,23 +635,10 @@
return;
}
- // If Hotseat is not the top element during animation to/from Launcher, fade in/out a
- // already stashed Taskbar.
- boolean hotseatTopElement = mControllers.uiController.isHotseatIconOnTopWhenAligned()
- || !hasAnyFlag(changedFlags, FLAG_IN_APP);
- // If transitioning to unlocked device, do not play a stash animation.
- // Keep isUnlockTransition in sync with its counterpart in
- // TaskbarLauncherStateController#onStateChangeApplied.
- boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
- && !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
- boolean skipStashAnimation = !hotseatTopElement || isUnlockTransition;
-
if (isTransientTaskbar) {
- createTransientAnimToIsStashed(mAnimator, isStashed, duration, animateBg, changedFlags,
- skipStashAnimation);
+ createTransientAnimToIsStashed(mAnimator, isStashed, duration, animationType);
} else {
- createAnimToIsStashed(mAnimator, isStashed, duration, animateBg, skipStashAnimation,
- stashTranslation);
+ createAnimToIsStashed(mAnimator, isStashed, duration, stashTranslation, animationType);
}
mAnimator.addListener(new AnimatorListenerAdapter() {
@@ -636,7 +667,7 @@
}
private void createAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
- boolean animateBg, boolean skipStashAnimation, float stashTranslation) {
+ float stashTranslation, @StashAnimation int animationType) {
AnimatorSet fullLengthAnimatorSet = new AnimatorSet();
// Not exactly half and may overlap. See [first|second]HalfDurationScale below.
AnimatorSet firstHalfAnimatorSet = new AnimatorSet();
@@ -650,12 +681,7 @@
secondHalfDurationScale = 0.5f;
fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation));
- if (animateBg) {
- fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
- } else {
- fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
- () -> mTaskbarBackgroundOffset.updateValue(1)));
- }
+ fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
firstHalfAnimatorSet.playTogether(
mIconAlphaForStash.animateToValue(0),
@@ -666,7 +692,7 @@
mTaskbarStashedHandleAlpha.animateToValue(1)
);
- if (skipStashAnimation) {
+ if (animationType == TRANSITION_HANDLE_FADE) {
fullLengthAnimatorSet.setInterpolator(INSTANT);
firstHalfAnimatorSet.setInterpolator(INSTANT);
}
@@ -677,6 +703,8 @@
fullLengthAnimatorSet.playTogether(
mIconScaleForStash.animateToValue(1),
mIconTranslationYForStash.animateToValue(0));
+
+ final boolean animateBg = animationType != TRANSITION_UNSTASH_SUW_MANUAL;
if (animateBg) {
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(0));
} else {
@@ -691,7 +719,7 @@
mIconAlphaForStash.animateToValue(1)
);
- if (skipStashAnimation) {
+ if (animationType == TRANSITION_HANDLE_FADE) {
fullLengthAnimatorSet.setInterpolator(FINAL_FRAME);
secondHalfAnimatorSet.setInterpolator(FINAL_FRAME);
}
@@ -714,18 +742,13 @@
}
private void createTransientAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
- boolean animateBg, int changedFlags, boolean skipStashAnimation) {
+ @StashAnimation int animationType) {
Interpolator skipInterpolator = null;
if (isStashed) {
- if (animateBg) {
- play(as, mTaskbarBackgroundOffset.animateToValue(1), 0, duration, EMPHASIZED);
- } else {
- as.addListener(AnimatorListeners.forEndCallback(
- () -> mTaskbarBackgroundOffset.updateValue(1)));
- }
+ play(as, mTaskbarBackgroundOffset.animateToValue(1), 0, duration, EMPHASIZED);
- long alphaStartDelay = duration == 0 ? 0 : (changedFlags == FLAG_IN_APP)
+ long alphaStartDelay = duration == 0 ? 0 : animationType == TRANSITION_HOME_TO_APP
? TASKBAR_STASH_ICON_ALPHA_HOME_TO_APP_START_DELAY
: TASKBAR_STASH_ALPHA_START_DELAY;
long alphaDuration = duration == 0 ? 0 : TASKBAR_STASH_ALPHA_DURATION;
@@ -736,10 +759,11 @@
play(as, mControllers.taskbarSpringOnStashController.createSpringToStash(), 0, duration,
LINEAR);
- if (skipStashAnimation) {
+ if (animationType == TRANSITION_HANDLE_FADE) {
skipInterpolator = INSTANT;
}
} else {
+ final boolean animateBg = animationType != TRANSITION_UNSTASH_SUW_MANUAL;
if (animateBg) {
play(as, mTaskbarBackgroundOffset.animateToValue(0), 0, duration, EMPHASIZED);
} else {
@@ -752,7 +776,7 @@
play(as, mIconAlphaForStash.animateToValue(1), alphaStartDelay, alphaDuration, LINEAR);
play(as, mTaskbarStashedHandleAlpha.animateToValue(0), 0, alphaDuration, LINEAR);
- if (skipStashAnimation) {
+ if (animationType == TRANSITION_HANDLE_FADE) {
skipInterpolator = FINAL_FRAME;
}
}
@@ -928,16 +952,8 @@
hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));
boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED);
- boolean wasLocked = hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);
- if (isLocked && !wasLocked && DisplayController.isTransientTaskbar(mActivity)) {
- // Stash the transient taskbar when locking the device. This improves the transition
- // to AoD (otherwise the taskbar stays a bit too long above the collapsing AoD scrim),
- // and ensures the taskar state is reset when unlocking the device afterwards.
- updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, true);
- }
-
// Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING);
mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING);
@@ -1150,7 +1166,7 @@
private final IntPredicate mStashCondition;
private boolean mIsStashed;
- private boolean mIsHotseatIconOnTopWhenAligned;
+ private @StashAnimation int mLastStartedTransitionType = TRANSITION_DEFAULT;
private int mPrevFlags;
StatePropertyHolder(IntPredicate stashCondition) {
@@ -1182,28 +1198,64 @@
onStateChangeApplied(changedFlags);
mPrevFlags = flags;
}
- boolean isHotseatIconOnTopWhenAligned =
- mControllers.uiController.isHotseatIconOnTopWhenAligned();
- // If an animation has started and mIsHotseatIconOnTopWhenAligned is changed, we need
- // to restart the animation with new parameters.
- if (mIsStashed != isStashed
- || (mIsHotseatIconOnTopWhenAligned != isHotseatIconOnTopWhenAligned
- && mAnimator != null && mAnimator.isStarted())) {
+
+ @StashAnimation int animationType = computeTransitionType(changedFlags);
+
+ // Allow re-starting animation if upgrading from default animation type, otherwise
+ // stick with the already started transition.
+ boolean transitionTypeChanged = mAnimator != null && mAnimator.isStarted()
+ && mLastStartedTransitionType == TRANSITION_DEFAULT
+ && animationType != TRANSITION_DEFAULT;
+
+ if (mIsStashed != isStashed || transitionTypeChanged) {
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
- "setState: mIsStashed=%b, isStashed=%b, duration=%d",
+ "setState: mIsStashed=%b, isStashed=%b, "
+ + "mAnimationType=%d, animationType=%d, duration=%d",
mIsStashed,
isStashed,
+ mLastStartedTransitionType,
+ animationType,
duration));
}
mIsStashed = isStashed;
- mIsHotseatIconOnTopWhenAligned = isHotseatIconOnTopWhenAligned;
+ mLastStartedTransitionType = animationType;
// This sets mAnimator.
- createAnimToIsStashed(mIsStashed, duration, /* animateBg= */ true, changedFlags);
+ createAnimToIsStashed(mIsStashed, duration, animationType);
return mAnimator;
}
return null;
}
+
+ private @StashAnimation int computeTransitionType(int changedFlags) {
+ boolean hotseatHiddenDuringAppLaunch =
+ !mControllers.uiController.isHotseatIconOnTopWhenAligned()
+ && hasAnyFlag(changedFlags, FLAG_IN_APP);
+ if (hotseatHiddenDuringAppLaunch) {
+ // When launching an app from the all-apps drawer, the hotseat is hidden behind the
+ // drawer. In this case, the navbar must just fade in, without a stash transition,
+ // as the taskbar stash animation would otherwise be visible above the all-apps
+ // drawer once the hotseat is detached.
+ return TRANSITION_HANDLE_FADE;
+ }
+
+ boolean isUnlockTransition = hasAnyFlag(changedFlags, FLAG_STASHED_DEVICE_LOCKED)
+ && !hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
+ if (isUnlockTransition) {
+ // When transitioning to unlocked device, the hotseat will already be visible on
+ // the homescreen, thus do not play an un-stash animation.
+ // Keep isUnlockTransition in sync with its counterpart in
+ // TaskbarLauncherStateController#onStateChangeApplied.
+ return TRANSITION_HANDLE_FADE;
+ }
+
+ boolean homeToApp = hasAnyFlag(changedFlags, FLAG_IN_APP) && hasAnyFlag(FLAG_IN_APP);
+ if (homeToApp) {
+ return TRANSITION_HOME_TO_APP;
+ }
+
+ return TRANSITION_DEFAULT;
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 4ab093f..6eb409e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -286,7 +286,7 @@
}
private ValueAnimator createRevealAnimForView(View view, boolean isStashed, float newWidth,
- boolean shouldStartAlign) {
+ boolean isQsb) {
Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight());
int centerY = viewBounds.centerY();
int halfHandleHeight = mStashedHandleHeight / 2;
@@ -295,7 +295,8 @@
final int left;
final int right;
- if (shouldStartAlign) {
+ // QSB will crop from the 'start' whereas all other icons will crop from the center.
+ if (isQsb) {
if (mIsRtl) {
right = viewBounds.right;
left = (int) (right - newWidth);
@@ -311,7 +312,10 @@
}
Rect stashedRect = new Rect(left, top, right, bottom);
- float radius = viewBounds.height() / 2f;
+ // QSB radius can be > 0 since it does not have any UI elements outside of it bounds.
+ float radius = isQsb
+ ? viewBounds.height() / 2f
+ : 0f;
float stashedRadius = stashedRect.height() / 2f;
return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect)
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
index 1728681..623e234 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
-import android.view.WindowInsets;
import com.android.launcher3.R;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
@@ -38,12 +37,6 @@
}
@Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect());
- return super.onApplyWindowInsets(insets);
- }
-
- @Override
protected View inflateSearchBox() {
if (isSearchSupported()) {
return super.inflateSearchBox();
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index ec64128..2c3e1ac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -120,7 +120,9 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- return updateInsetsDueToStashing(insets);
+ insets = updateInsetsDueToStashing(insets);
+ setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect());
+ return insets;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 6475b74..b2b0623 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -641,7 +641,7 @@
PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration());
RectF startingTaskRect = new RectF();
final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(this,
- source.view, null /* thumbnail */, source.drawable, startingTaskRect);
+ source.getView(), null /* thumbnail */, source.getDrawable(), startingTaskRect);
floatingTaskView.setAlpha(1);
floatingTaskView.addStagingAnimation(anim, startingTaskRect, tempRect,
false /* fadeWithThumbnail */, true /* isStagedTask */);
@@ -745,6 +745,10 @@
@Override
protected void registerBackDispatcher() {
+ if (!FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
+ super.registerBackDispatcher();
+ return;
+ }
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT,
new OnBackAnimationCallback() {
@@ -1241,6 +1245,9 @@
Trace.instantForTrack(TRACE_TAG_APP, "QuickstepLauncher#DeviceProfileChanged",
getDeviceProfile().toSmallString());
SystemUiProxy.INSTANCE.get(this).setLauncherAppIconSize(mDeviceProfile.iconSizePx);
+ if (mTaskbarManager != null) {
+ mTaskbarManager.debugWhyTaskbarNotDestroyed("QuickstepLauncher#onDeviceProfileChanged");
+ }
}
/**
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 1f99d6e..73f05c2 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -218,29 +218,15 @@
mUnfoldAnimation = unfoldAnimation;
linkToDeath();
// re-attach the listeners once missing due to setProxy has not been initialized yet.
- if (mPipAnimationListener != null && mPip != null) {
- setPipAnimationListener(mPipAnimationListener);
- }
- if (mSplitScreenListener != null && mSplitScreen != null) {
- registerSplitScreenListener(mSplitScreenListener);
- }
- if (mStartingWindowListener != null && mStartingWindow != null) {
- setStartingWindowListener(mStartingWindowListener);
- }
- if (mSysuiUnlockAnimationController != null && mLauncherUnlockAnimationController != null) {
- setLauncherUnlockAnimationController(mLauncherUnlockAnimationController);
- }
+ setPipAnimationListener(mPipAnimationListener);
+ registerSplitScreenListener(mSplitScreenListener);
+ setStartingWindowListener(mStartingWindowListener);
+ setLauncherUnlockAnimationController(mLauncherUnlockAnimationController);
new LinkedHashMap<>(mRemoteTransitions).forEach(this::registerRemoteTransition);
setupTransactionQueue();
- if (mRecentTasksListener != null && mRecentTasks != null) {
- registerRecentTasksListener(mRecentTasksListener);
- }
- if (mBackAnimation != null && mBackToLauncherCallback != null) {
- setBackToLauncherCallback(mBackToLauncherCallback, mBackToLauncherRunner);
- }
- if (unfoldAnimation != null && mUnfoldAnimationListener != null) {
- setUnfoldAnimationListener(mUnfoldAnimationListener);
- }
+ registerRecentTasksListener(mRecentTasksListener);
+ setBackToLauncherCallback(mBackToLauncherCallback, mBackToLauncherRunner);
+ setUnfoldAnimationListener(mUnfoldAnimationListener);
}
public void clearProxy() {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 5e14d19..9102f2f 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -22,6 +22,7 @@
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
+import static com.android.launcher3.Launcher.INTENT_ACTION_ALL_APPS_TOGGLE;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -514,7 +515,7 @@
if (isHomeAndOverviewSame) {
Intent intent = new Intent(mOverviewComponentObserver.getHomeIntent())
- .setAction(Intent.ACTION_ALL_APPS);
+ .setAction(INTENT_ACTION_ALL_APPS_TOGGLE);
RemoteAction allAppsAction = new RemoteAction(
Icon.createWithResource(this, R.drawable.ic_apps),
getString(R.string.all_apps_label),
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index 6dd67de..b76fe5c 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -24,6 +24,7 @@
import com.android.launcher3.DeviceProfile
import com.android.launcher3.anim.PendingAnimation
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
+import com.android.quickstep.views.IconView
import com.android.quickstep.views.TaskThumbnailView
import com.android.quickstep.views.TaskView
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
@@ -52,21 +53,22 @@
* depending on the state of the surface from which the split was initiated
*/
fun getFirstAnimInitViews(taskViewSupplier: Supplier<TaskView>,
- splitSelectSourceSupplier: Supplier<SplitSelectSource>)
+ splitSelectSourceSupplier: Supplier<SplitSelectSource?>)
: SplitAnimInitProps {
+ val splitSelectSource = splitSelectSourceSupplier.get()
if (!splitSelectStateController.isAnimateCurrentTaskDismissal) {
// Initiating from home
- val splitSelectSource = splitSelectSourceSupplier.get()
- return SplitAnimInitProps(splitSelectSource.view, originalBitmap = null,
+ return SplitAnimInitProps(splitSelectSource!!.view, originalBitmap = null,
splitSelectSource.drawable, fadeWithThumbnail = false, isStagedTask = true,
iconView = null)
} else if (splitSelectStateController.isDismissingFromSplitPair) {
// Initiating split from overview, but on a split pair
val taskView = taskViewSupplier.get()
for (container : TaskIdAttributeContainer in taskView.taskIdAttributeContainers) {
- if (container.task.key.id == splitSelectStateController.initialTaskId) {
+ if (container.task.getKey().getId() == splitSelectStateController.initialTaskId) {
+ val drawable = getDrawable(container.iconView, splitSelectSource)
return SplitAnimInitProps(container.thumbnailView,
- container.thumbnailView.thumbnail, container.iconView.drawable!!,
+ container.thumbnailView.thumbnail, drawable!!,
fadeWithThumbnail = true, isStagedTask = true,
iconView = container.iconView
)
@@ -77,14 +79,28 @@
} else {
// Initiating split from overview on fullscreen task TaskView
val taskView = taskViewSupplier.get()
+ val drawable = getDrawable(taskView.iconView, splitSelectSource)
return SplitAnimInitProps(taskView.thumbnail, taskView.thumbnail.thumbnail,
- taskView.iconView.drawable!!, fadeWithThumbnail = true, isStagedTask = true,
+ drawable!!, fadeWithThumbnail = true, isStagedTask = true,
taskView.iconView
)
}
}
/**
+ * Returns the drawable that's provided in iconView, however if that
+ * is null it falls back to the drawable that's in splitSelectSource.
+ * 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? {
+ if (iconView.drawable == null && splitSelectSource != null) {
+ return splitSelectSource.drawable
+ }
+ return iconView.drawable
+ }
+
+ /**
* When selecting first app from split pair, second app's thumbnail remains. This animates
* the second thumbnail by expanding it to take up the full taskViewWidth/Height and overlaying
* it with [TaskThumbnailView]'s splashView. Adds animations to the provided builder.
diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
new file mode 100644
index 0000000..7e07b81
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt
@@ -0,0 +1,165 @@
+/*
+ * 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.graphics.Bitmap
+import android.graphics.drawable.Drawable
+import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.quickstep.views.GroupedTaskView
+import com.android.quickstep.views.IconView
+import com.android.quickstep.views.TaskThumbnailView
+import com.android.quickstep.views.TaskView
+import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
+import com.android.systemui.shared.recents.model.Task
+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
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidJUnit4::class)
+class SplitAnimationControllerTest {
+
+ private val taskId = 9
+
+ @Mock lateinit var mockSplitSelectStateController: SplitSelectStateController
+ // 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
+ // GroupedTaskView
+ @Mock lateinit var mockGroupedTaskView: GroupedTaskView
+ @Mock lateinit var mockTask: Task
+ @Mock lateinit var mockTaskKey: Task.TaskKey
+ @Mock lateinit var mockTaskIdAttributeContainer: TaskIdAttributeContainer
+
+ // SplitSelectSource
+ @Mock lateinit var splitSelectSource: SplitConfigurationOptions.SplitSelectSource
+ @Mock lateinit var mockSplitSourceDrawable: Drawable
+ @Mock lateinit var mockSplitSourceView: View
+
+ 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)
+ whenever(mockIconView.drawable).thenReturn(mockTaskViewDrawable)
+
+ whenever(splitSelectSource.drawable).thenReturn(mockSplitSourceDrawable)
+ whenever(splitSelectSource.view).thenReturn(mockSplitSourceView)
+
+ splitAnimationController = SplitAnimationController(mockSplitSelectStateController)
+ }
+
+ @Test
+ fun getFirstAnimInitViews_nullTaskViewIcon_useSplitSourceIcon() {
+ // Hit fullscreen task dismissal state
+ whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
+ whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
+
+ // Missing taskView icon
+ whenever(mockIconView.drawable).thenReturn(null)
+
+ val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews(
+ { mockTaskView }, { splitSelectSource })
+
+ assertEquals("Did not fallback to use splitSource icon drawable",
+ mockSplitSourceDrawable, splitAnimInitProps.iconDrawable)
+ }
+
+ @Test
+ fun getFirstAnimInitViews_validTaskViewIcon_useTaskViewIcon() {
+ // Hit fullscreen task dismissal state
+ whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
+ whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
+
+ val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews(
+ { mockTaskView }, { splitSelectSource })
+
+ assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
+ splitAnimInitProps.iconDrawable)
+ }
+
+ @Test
+ fun getFirstAnimInitViews_validTaskViewNullSplitSource_useTaskViewIcon() {
+ // Hit fullscreen task dismissal state
+ whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
+ whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
+
+ // Set split source to null
+ whenever(splitSelectSource.drawable).thenReturn(null)
+
+ val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews(
+ { mockTaskView }, { splitSelectSource })
+
+ assertEquals("Did not use taskView icon drawable", mockTaskViewDrawable,
+ splitAnimInitProps.iconDrawable)
+ }
+
+ @Test
+ fun getFirstAnimInitViews_nullTaskViewValidSplitSource_noTaskDismissal() {
+ // Hit initiating split from home
+ whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(false)
+ whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(false)
+
+ val splitAnimInitProps : SplitAnimationController.Companion.SplitAnimInitProps =
+ splitAnimationController.getFirstAnimInitViews(
+ { mockTaskView }, { splitSelectSource })
+
+ assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
+ splitAnimInitProps.iconDrawable)
+ }
+
+ @Test
+ fun getFirstAnimInitViews_nullTaskViewValidSplitSource_groupedTaskView() {
+ // Hit groupedTaskView dismissal
+ whenever(mockSplitSelectStateController.isAnimateCurrentTaskDismissal).thenReturn(true)
+ whenever(mockSplitSelectStateController.isDismissingFromSplitPair).thenReturn(true)
+
+ // Remove icon view from GroupedTaskView
+ whenever(mockIconView.drawable).thenReturn(null)
+
+ whenever(mockTaskIdAttributeContainer.task).thenReturn(mockTask)
+ whenever(mockTaskIdAttributeContainer.iconView).thenReturn(mockIconView)
+ whenever(mockTaskIdAttributeContainer.thumbnailView).thenReturn(mockThumbnailView)
+ whenever(mockTask.getKey()).thenReturn(mockTaskKey)
+ 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 })
+
+ assertEquals("Did not use splitSource icon drawable", mockSplitSourceDrawable,
+ splitAnimInitProps.iconDrawable)
+ }
+}
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_large_screen.xml b/res/drawable/bg_widgets_header_two_pane.xml
similarity index 100%
rename from res/drawable/bg_widgets_header_large_screen.xml
rename to res/drawable/bg_widgets_header_two_pane.xml
diff --git a/res/layout/widgets_list_row_header_two_pane.xml b/res/layout/widgets_list_row_header_two_pane.xml
index 6465db5..c0a6ea8 100644
--- a/res/layout/widgets_list_row_header_two_pane.xml
+++ b/res/layout/widgets_list_row_header_two_pane.xml
@@ -24,7 +24,7 @@
android:focusable="true"
launcher:appIconSize="48dp"
android:descendantFocusability="afterDescendants"
- android:background="@drawable/bg_widgets_header_large_screen" >
+ android:background="@drawable/bg_widgets_header_two_pane" >
<ImageView
android:id="@+id/app_icon"
diff --git a/res/layout/widgets_full_sheet_large_screen.xml b/res/layout/widgets_two_pane_sheet.xml
similarity index 97%
rename from res/layout/widgets_full_sheet_large_screen.xml
rename to res/layout/widgets_two_pane_sheet.xml
index f563baa..4333a80 100644
--- a/res/layout/widgets_full_sheet_large_screen.xml
+++ b/res/layout/widgets_two_pane_sheet.xml
@@ -42,7 +42,7 @@
android:layout_marginTop="24dp"
android:gravity="center_horizontal"
android:layout_below="@id/collapse_handle"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:text="@string/widget_button_text"
android:textColor="?android:attr/textColorSecondary"
android:textSize="24sp" />
@@ -76,7 +76,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:visibility="gone" />
</FrameLayout>
@@ -85,8 +85,8 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.67"
- android:layout_marginEnd="@dimen/widget_list_horizontal_margin_large_screen"
- android:paddingTop="@dimen/widget_list_horizontal_margin_large_screen"
+ android:layout_marginEnd="@dimen/widget_list_horizontal_margin_two_pane"
+ android:paddingTop="@dimen/widget_list_horizontal_margin_two_pane"
android:gravity="end"
android:layout_gravity="end"
android:orientation="horizontal">
@@ -118,7 +118,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal=
- "@dimen/widget_list_horizontal_margin_large_screen"
+ "@dimen/widget_list_horizontal_margin_two_pane"
android:visibility="gone" />
</LinearLayout>
</ScrollView>
diff --git a/res/layout/widgets_full_sheet_paged_view_large_screen.xml b/res/layout/widgets_two_pane_sheet_paged_view.xml
similarity index 96%
rename from res/layout/widgets_full_sheet_paged_view_large_screen.xml
rename to res/layout/widgets_two_pane_sheet_paged_view.xml
index f729981..5cc2406 100644
--- a/res/layout/widgets_full_sheet_paged_view_large_screen.xml
+++ b/res/layout/widgets_two_pane_sheet_paged_view.xml
@@ -17,7 +17,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
- android:id="@+id/widgets_full_sheet_paged_view_large_screen"
+ android:id="@+id/widgets_two_pane_sheet_paged_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start"
@@ -29,7 +29,7 @@
android:layout_height="match_parent"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
launcher:pageIndicator="@+id/tabs" >
<com.android.launcher3.widget.picker.WidgetsRecyclerView
@@ -62,7 +62,7 @@
android:clipToPadding="false"
android:elevation="0.1dp"
android:paddingBottom="8dp"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
launcher:layout_sticky="true">
<include layout="@layout/widgets_search_bar" />
@@ -73,7 +73,7 @@
android:layout_height="match_parent"
android:id="@+id/suggestions_header"
android:layout_marginTop="8dp"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:orientation="horizontal">
</LinearLayout>
@@ -84,7 +84,7 @@
android:gravity="center_horizontal"
android:orientation="horizontal"
android:paddingVertical="8dp"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:background="?android:attr/colorBackground"
style="@style/TextHeadline"
launcher:layout_sticky="true">
diff --git a/res/layout/widgets_full_sheet_recyclerview_large_screen.xml b/res/layout/widgets_two_pane_sheet_recyclerview.xml
similarity index 93%
rename from res/layout/widgets_full_sheet_recyclerview_large_screen.xml
rename to res/layout/widgets_two_pane_sheet_recyclerview.xml
index 8fef303..09cef88 100644
--- a/res/layout/widgets_full_sheet_recyclerview_large_screen.xml
+++ b/res/layout/widgets_two_pane_sheet_recyclerview.xml
@@ -17,7 +17,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
- android:id="@+id/widgets_full_sheet_recyclerview_large_screen"
+ android:id="@+id/widgets_two_pane_sheet_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start"
@@ -28,7 +28,7 @@
android:id="@+id/primary_widgets_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:clipToPadding="false" />
<!-- SearchAndRecommendationsView without the tab layout as well -->
@@ -47,7 +47,7 @@
android:clipToPadding="false"
android:elevation="0.1dp"
android:paddingBottom="8dp"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:paddingHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
launcher:layout_sticky="true">
<include layout="@layout/widgets_search_bar" />
@@ -58,7 +58,7 @@
android:layout_height="match_parent"
android:id="@+id/suggestions_header"
android:layout_marginTop="8dp"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_large_screen"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin_two_pane"
android:orientation="horizontal">
</LinearLayout>
</com.android.launcher3.views.StickyHeaderLayout>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 5c4313a..99cbd53 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Tuis"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index df4525e..5b10654 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"መነሻ"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"የተከፈለ ማያ ገጽ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"የመተግበሪያ መረጃ ለ%1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 9155e7b..8f55646 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"الشاشة الرئيسية"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"تقسيم الشاشة"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"معلومات تطبيق %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index dc7ed51..2378f23 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"গৃহ স্ক্ৰীন"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"বিভাজিত স্ক্ৰীন"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sৰ বাবে এপৰ তথ্য"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 6b1d484..c24b9a5 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Əsas səhifə"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 4e3ec96..197b3b0 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Početni ekran"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 05d58f7..cff40b6 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Галоўны экран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Падзелены экран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Інфармацыя пра праграму для: %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b847083..4d94341 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Начален екран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделен екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Информация за приложението за %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 9351f9b..d277a3a 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"হোম"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"স্প্লিট স্ক্রিন"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-এর জন্য অ্যাপ সম্পর্কিত তথ্য"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 6ce2412..45fb7f1 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Početni ekran"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index d5eeec5..be80552 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Inici"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 9e4faeb..3402b75 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Domů"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdělená obrazovka"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Informace o aplikaci %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 26185c7..b8aa02f 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Startskærm"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1fba8e7..199bf54 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Startbildschirm"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Geteilter Bildschirm"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"App-Info für %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 34556c0..31fa51e 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Αρχική οθόνη"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Διαχωρισμός οθόνης"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Πληροφορίες εφαρμογής για %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 02f3396..c7b55d7 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index a36f39a..7a4e094 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 02f3396..c7b55d7 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 02f3396..c7b55d7 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 9719a96..5324bdf 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 48c422c..1ff063d 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Pantalla principal"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index ddde58f..777f4c9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index be889cc..91d9352 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Avakuva"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index c11b9ca..66b8679 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Hasierako pantaila"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Zatitu pantaila"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s aplikazioari buruzko informazioa"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index f33f9a6..42d44ee 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"صفحه اصلی"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"صفحهٔ دونیمه"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"اطلاعات برنامه %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 9ef7b4b..a6ecd8b 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Etusivu"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 78470a1..ad60e26 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Accueil"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b8debf7..983d5a9 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Accueil"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 8ac5b81..c11c514 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index f6bd907..4b48e7a 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"હોમ સ્ક્રીન"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s માટે ઍપ માહિતી"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 32ea26f..be64ff1 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"होम स्क्रीन"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s के लिए ऐप्लिकेशन की जानकारी"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c6180a9..b757619 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Početni zaslon"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index e084231..d499022 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Kezdőképernyő"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index fd75fb2..6881661 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Հիմնական էկրան"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Տրոհել էկրանը"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Տեղեկություններ %1$s հավելվածի մասին"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 4a6a225..beff9ea 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Layar utama"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index f7824dd..29b11aa 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Heim"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 06d86fe..519cd5c 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 07f325b..ca3230c 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"בית"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"מסך מפוצל"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"פרטים על האפליקציה %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 471b523..2948525 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ホーム"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割画面"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s のアプリ情報"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 750edce..9937836 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"მთავარი გვერდი"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ეკრანის გაყოფა"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-ის აპის ინფო"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index f0bfaef..a1730eb 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Негізгі экран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлу"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s қолданбасы туралы ақпарат"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 3e87275..b993eaa 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"អេក្រង់ដើម"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"មុខងារបំបែកអេក្រង់"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ព័ត៌មានកម្មវិធីសម្រាប់ %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 7237e4e..06af44c 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ಹೋಮ್"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ಗಾಗಿ ಆ್ಯಪ್ ಮಾಹಿತಿ"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 8fe07c4..29933e1 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"홈"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"화면 분할"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 앱 정보"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 149c2c1..ecae23a 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Башкы экран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлүү"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s колдонмосу жөнүндө маалымат"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 74f4e85..7158916 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ໂຮມສະກຣີນ"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ແບ່ງໜ້າຈໍ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ຂໍ້ມູນແອັບສຳລັບ %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index e251fd0..81164bd 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Pagrindinis"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 89a5423..e8e25b8 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Sākums"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 9859c8e..1b95dcf 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Почетен екран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Поделен екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Податоци за апликација за %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 0af89d3..ab04493 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ഹോം"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"സ്ക്രീൻ വിഭജന മോഡ്"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s എന്നതിന്റെ ആപ്പ് വിവരങ്ങൾ"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index f535bce..511718c 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Нүүр"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Дэлгэцийг хуваах"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-н аппын мэдээлэл"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index ec197d2..893d041 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"होम"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s साठी ॲपशी संबंधित माहिती"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index bc90305..55befdd 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Rumah"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 102ddbc..ccdb08e 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ပင်မစာမျက်နှာ"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s အတွက် အက်ပ်အချက်အလက်"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index c78425a..bb05261 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Startskjerm"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index b8ddced..3547557 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"होम"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रिन"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s का हकमा एपसम्बन्धी जानकारी"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index f167111..f4c1017 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Startscherm"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index b9b69ae..52560c1 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ହୋମ"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ସ୍କ୍ରିନକୁ ସ୍ପ୍ଲିଟ୍ କରନ୍ତୁ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ପାଇଁ ଆପ ସୂଚନା"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index a559c47..0f65479 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ਮੁੱਖ ਪੰਨਾ"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ਲਈ ਐਪ ਜਾਣਕਾਰੀ"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 19de527..d8645f0 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Ekran główny"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 73caaa7..e74feac 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Página inicial"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 9cffd85..4373c06 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Início"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 983bb42..295809d 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Pagina de pornire"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index b3dd441..d2dd2d6 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Главный экран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделить экран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Сведения о приложении \"%1$s\""</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index e6e067b..bde8ca8 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"මුල් පිටුව"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"බෙදුම් තිරය"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s සඳහා යෙදුම් තතු"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 1fdd277..3bcc7a2 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Domov"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 345e25a..b5d3eb1 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Začetni zaslon"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index b590455..02169c8 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Ekrani bazë"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 7a9e50d..f924fe7 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Почетни екран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Подељени екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Информације о апликацији за: %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5454c66..c5b4ae2 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Startskärm"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index f49256e..f4621a1 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Skrini ya kwanza"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index b89910d..4d0ac38 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -31,7 +31,7 @@
<!-- Widget picker-->
<dimen name="widget_list_horizontal_margin">49dp</dimen>
- <dimen name="widget_list_horizontal_margin_large_screen">24dp</dimen>
+ <dimen name="widget_list_horizontal_margin_two_pane">24dp</dimen>
<!-- Bottom sheet-->
<dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index b22ee7c..56b9a8c 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"முகப்பு"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"திரைப் பிரிப்பு"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sக்கான ஆப்ஸ் தகவல்கள்"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 274310e..16b5f5a 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"మొదటి ట్యాబ్"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"స్క్రీన్ను విభజించు"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s కోసం యాప్ సమాచారం"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 619fee0..45c3914 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"หน้าแรก"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"แบ่งหน้าจอ"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"ข้อมูลแอปสำหรับ %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index c15b6e5..2d43182 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Home"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 01aa4aa..b886cf2 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Ana ekran"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 8288aa4..5758c75 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Головний екран"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"Розділити екран"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"Інформація про додаток для %1$s"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 4e09d54..5a5dcc5 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"ہوم"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"اسپلٹ اسکرین"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s کے لیے ایپ کی معلومات"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 5df3238..5595179 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Bosh ekran"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
@@ -106,7 +108,7 @@
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon burilganda"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Bildirishnoma belgilari"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Yoniq"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"Yoqilmagan"</string>
+ <string name="notification_dots_desc_off" msgid="1760796511504341095">"Oʻchiq"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Bildirishnomalarga ruxsat berilmagan"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Bildirishnoma belgilarini ko‘rsatish uchun <xliff:g id="NAME">%1$s</xliff:g> ilovasida bildirishnomalarni yoqing"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Sozlamalarni o‘zgartirish"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 43bdf04..32ea78e 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Màn hình chính"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3e66cb9..2c06691 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"主屏幕"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分屏"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的应用信息"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index fac5dc3..d7954de 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"主畫面"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割螢幕"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的應用程式資料"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8b96553..30d7860 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"主畫面"</string>
<string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割畫面"</string>
<string name="split_app_info_accessibility" msgid="5475288491241414932">"「%1$s」的應用程式資訊"</string>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 97fffd5..ba195b2 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -29,6 +29,8 @@
<string name="home_screen" msgid="5629429142036709174">"Ikhaya"</string>
<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>
+ <!-- no translation found for save_app_pair (5647523853662686243) -->
+ <skip />
<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>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 68e668f..923883b 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -193,7 +193,7 @@
<dimen name="widget_list_header_view_vertical_padding">20dp</dimen>
<dimen name="widget_list_entry_spacing">2dp</dimen>
<dimen name="widget_list_horizontal_margin">16dp</dimen>
- <dimen name="widget_list_horizontal_margin_large_screen">24dp</dimen>
+ <dimen name="widget_list_horizontal_margin_two_pane">24dp</dimen>
<dimen name="widget_preview_shadow_blur">0.5dp</dimen>
<dimen name="widget_preview_key_shadow_distance">1dp</dimen>
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 0c19e4b..485b36c 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -41,7 +41,6 @@
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
-import android.util.TypedValue;
import android.util.Xml;
import android.view.Display;
@@ -58,11 +57,9 @@
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LockedUserState;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Partner;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.util.window.WindowManagerProxy;
@@ -76,6 +73,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.stream.Collectors;
public class InvariantDeviceProfile {
@@ -151,8 +149,6 @@
public float[] transientTaskbarIconSize;
- private SparseArray<TypedValue> mExtraAttrs;
-
/**
* Number of icons inside the hotseat area.
*/
@@ -360,8 +356,6 @@
inlineNavButtonsEndSpacing = closestProfile.inlineNavButtonsEndSpacing;
- mExtraAttrs = closestProfile.extraAttrs;
-
iconSize = displayOption.iconSizes;
float maxIconSize = iconSize[0];
for (int i = 1; i < iconSize.length; i++) {
@@ -495,9 +489,8 @@
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser),
- deviceType);
- if (gridOption.isEnabled || allowDisabledGrid) {
+ GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser));
+ if (gridOption.isEnabled(deviceType) || allowDisabledGrid) {
final int displayDepth = parser.getDepth();
while (((type = parser.next()) != XmlPullParser.END_TAG
|| parser.getDepth() > displayDepth)
@@ -519,7 +512,7 @@
if (!TextUtils.isEmpty(gridName)) {
for (DisplayOption option : profiles) {
if (gridName.equals(option.grid.name)
- && (option.grid.isEnabled || allowDisabledGrid)) {
+ && (option.grid.isEnabled(deviceType) || allowDisabledGrid)) {
filteredProfiles.add(option);
}
}
@@ -542,6 +535,16 @@
* @return all the grid options that can be shown on the device
*/
public List<GridOption> parseAllGridOptions(Context context) {
+ return parseAllDefinedGridOptions(context)
+ .stream()
+ .filter(go -> go.isEnabled(deviceType))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * @return all the grid options that can be shown on the device
+ */
+ public static List<GridOption> parseAllDefinedGridOptions(Context context) {
List<GridOption> result = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
@@ -551,11 +554,7 @@
|| parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption option =
- new GridOption(context, Xml.asAttributeSet(parser), deviceType);
- if (option.isEnabled) {
- result.add(option);
- }
+ result.add(new GridOption(context, Xml.asAttributeSet(parser)));
}
}
} catch (IOException | XmlPullParserException e) {
@@ -774,7 +773,7 @@
public final int numRows;
public final int numColumns;
public final int numSearchContainerColumns;
- public final boolean isEnabled;
+ public final int deviceCategory;
private final int numFolderRows;
private final int numFolderColumns;
@@ -800,9 +799,7 @@
private final boolean isScalable;
private final int devicePaddingId;
- private final SparseArray<TypedValue> extraAttrs;
-
- public GridOption(Context context, AttributeSet attrs, @DeviceType int deviceType) {
+ public GridOption(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.GridDisplayOption);
name = a.getString(R.styleable.GridDisplayOption_name);
@@ -859,16 +856,8 @@
R.styleable.GridDisplayOption_isScalable, false);
devicePaddingId = a.getResourceId(
R.styleable.GridDisplayOption_devicePaddingId, INVALID_RESOURCE_HANDLE);
-
- int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
+ deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
DEVICE_CATEGORY_ALL);
- isEnabled = (deviceType == TYPE_PHONE
- && ((deviceCategory & DEVICE_CATEGORY_PHONE) == DEVICE_CATEGORY_PHONE))
- || (deviceType == TYPE_TABLET
- && ((deviceCategory & DEVICE_CATEGORY_TABLET) == DEVICE_CATEGORY_TABLET))
- || (deviceType == TYPE_MULTI_DISPLAY
- && ((deviceCategory & DEVICE_CATEGORY_MULTI_DISPLAY)
- == DEVICE_CATEGORY_MULTI_DISPLAY));
int inlineForRotation = a.getInt(R.styleable.GridDisplayOption_inlineQsb,
DONT_INLINE_QSB);
@@ -884,8 +873,20 @@
== INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE;
a.recycle();
- extraAttrs = Themes.createValueMap(context, attrs,
- IntArray.wrap(R.styleable.GridDisplayOption));
+ }
+
+ public boolean isEnabled(@DeviceType int deviceType) {
+ switch (deviceType) {
+ case TYPE_PHONE:
+ return (deviceCategory & DEVICE_CATEGORY_PHONE) == DEVICE_CATEGORY_PHONE;
+ case TYPE_TABLET:
+ return (deviceCategory & DEVICE_CATEGORY_TABLET) == DEVICE_CATEGORY_TABLET;
+ case TYPE_MULTI_DISPLAY:
+ return (deviceCategory & DEVICE_CATEGORY_MULTI_DISPLAY)
+ == DEVICE_CATEGORY_MULTI_DISPLAY;
+ default:
+ return false;
+ }
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7beac0b..8fcc08d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -288,6 +288,9 @@
// Type PendingSplitSelectInfo<Parcelable>
protected static final String PENDING_SPLIT_SELECT_INFO = "launcher.pending_split_select_info";
+ public static final String INTENT_ACTION_ALL_APPS_TOGGLE =
+ "launcher.intent_action_all_apps_toggle";
+
public static final String ON_CREATE_EVT = "Launcher.onCreate";
public static final String ON_START_EVT = "Launcher.onStart";
public static final String ON_RESUME_EVT = "Launcher.onResume";
@@ -1687,6 +1690,8 @@
handleGestureContract(intent);
} else if (Intent.ACTION_ALL_APPS.equals(intent.getAction())) {
showAllAppsFromIntent(alreadyOnHome);
+ } else if (INTENT_ACTION_ALL_APPS_TOGGLE.equals(intent.getAction())) {
+ toggleAllAppsFromIntent(alreadyOnHome);
} else if (Intent.ACTION_SHOW_WORK_APPS.equals(intent.getAction())) {
showAllAppsWorkTabFromIntent(alreadyOnHome);
}
@@ -1694,6 +1699,14 @@
TraceHelper.INSTANCE.endSection(traceToken);
}
+ protected void toggleAllAppsFromIntent(boolean alreadyOnHome) {
+ if (getStateManager().isInStableState(ALL_APPS)) {
+ getStateManager().goToState(NORMAL, alreadyOnHome);
+ } else {
+ showAllAppsFromIntent(alreadyOnHome);
+ }
+ }
+
protected void showAllAppsFromIntent(boolean alreadyOnHome) {
AbstractFloatingView.closeAllOpenViews(this);
getStateManager().goToState(ALL_APPS, alreadyOnHome);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index ea9e39d..db4e6b9 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -113,7 +113,7 @@
"ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps.");
public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851,
- "ENABLE_TWOLINE_DEVICESEARCH", DISABLED,
+ "ENABLE_TWOLINE_DEVICESEARCH", TEAMFOOD,
"Enable two line label for icons with labels on device search.");
public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = getReleaseFlag(
@@ -344,6 +344,10 @@
"LARGE_SCREEN_WIDGET_PICKER", ENABLED, "Enable new widget picker that takes "
+ "advantage of large screen 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 ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(270396257,
"ENABLE_NEW_GESTURE_NAV_TUTORIAL", ENABLED,
"Enable the redesigned gesture navigation tutorial");
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 3c63f26..1e3b003 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -46,10 +46,10 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.core.util.Pair;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherFiles;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.cache.BaseIconCache;
@@ -105,10 +105,6 @@
private int mPendingIconRequestCount = 0;
- public IconCache(Context context, InvariantDeviceProfile idp) {
- this(context, idp, LauncherFiles.APP_ICONS_DB, new IconProvider(context));
- }
-
public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName,
IconProvider iconProvider) {
super(context, dbFileName, MODEL_EXECUTOR.getLooper(),
@@ -254,30 +250,37 @@
* Returns the badging info for the shortcut
*/
public BitmapInfo getShortcutInfoBadge(ShortcutInfo shortcutInfo) {
- ComponentName cn = shortcutInfo.getActivity();
- if (cn != null) {
- // Get the app info for the source activity.
- AppInfo appInfo = new AppInfo();
- appInfo.user = shortcutInfo.getUserHandle();
- appInfo.componentName = cn;
- appInfo.intent = new Intent(Intent.ACTION_MAIN)
- .addCategory(Intent.CATEGORY_LAUNCHER)
- .setComponent(cn);
- getTitleAndIcon(appInfo, false);
- return appInfo.bitmap;
+ return getShortcutInfoBadgeItem(shortcutInfo).bitmap;
+ }
+
+ @VisibleForTesting
+ protected ItemInfoWithIcon getShortcutInfoBadgeItem(ShortcutInfo shortcutInfo) {
+ // Check for badge override first.
+ String pkg = shortcutInfo.getPackage();
+ String override = shortcutInfo.getExtras() == null ? null
+ : shortcutInfo.getExtras().getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE);
+ if (!TextUtils.isEmpty(override)
+ && InstallSessionHelper.INSTANCE.get(mContext)
+ .isTrustedPackage(pkg, shortcutInfo.getUserHandle())) {
+ pkg = override;
} else {
- String pkg = shortcutInfo.getPackage();
- String override = shortcutInfo.getExtras() == null ? null
- : shortcutInfo.getExtras().getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE);
- if (!TextUtils.isEmpty(override)
- && InstallSessionHelper.INSTANCE.get(mContext)
- .isTrustedPackage(pkg, shortcutInfo.getUserHandle())) {
- pkg = override;
+ // Try component based badge before trying the normal package badge
+ ComponentName cn = shortcutInfo.getActivity();
+ if (cn != null) {
+ // Get the app info for the source activity.
+ AppInfo appInfo = new AppInfo();
+ appInfo.user = shortcutInfo.getUserHandle();
+ appInfo.componentName = cn;
+ appInfo.intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setComponent(cn);
+ getTitleAndIcon(appInfo, false);
+ return appInfo;
}
- PackageItemInfo pkgInfo = new PackageItemInfo(pkg, shortcutInfo.getUserHandle());
- getTitleAndIconForApp(pkgInfo, false);
- return pkgInfo.bitmap;
}
+ PackageItemInfo pkgInfo = new PackageItemInfo(pkg, shortcutInfo.getUserHandle());
+ getTitleAndIconForApp(pkgInfo, false);
+ return pkgInfo;
}
/**
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 7ca3b11..125b4ce 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -181,9 +181,10 @@
public boolean isTrustedPackage(String pkg, UserHandle user) {
synchronized (mSessionVerifiedMap) {
if (!mSessionVerifiedMap.containsKey(pkg)) {
- boolean hasSystemFlag = new PackageManagerHelper(mAppContext).getApplicationInfo(
- pkg, user, ApplicationInfo.FLAG_SYSTEM) != null;
- mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
+ boolean hasSystemFlag = DEBUG || mAppContext.getPackageName().equals(pkg)
+ || new PackageManagerHelper(mAppContext)
+ .getApplicationInfo(pkg, user, ApplicationInfo.FLAG_SYSTEM) != null;
+ mSessionVerifiedMap.put(pkg, hasSystemFlag);
}
}
return mSessionVerifiedMap.get(pkg);
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 3d455d8..02ebb15 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -23,6 +23,7 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_TRANSIENT_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
@@ -55,6 +56,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.StringJoiner;
/**
* Utility class to cache properties of default display to avoid a system RPC on every call.
@@ -66,6 +68,9 @@
private static final boolean DEBUG = false;
private static boolean sTransientTaskbarStatusForTests;
+ // TODO(b/254119092) remove all logs with this tag
+ public static final String TASKBAR_NOT_DESTROYED_TAG = "b/254119092";
+
public static final MainThreadInitializedObject<DisplayController> INSTANCE =
new MainThreadInitializedObject<>(DisplayController::new);
@@ -206,6 +211,7 @@
@Override
@TargetApi(Build.VERSION_CODES.S)
public final void onConfigurationChanged(Configuration config) {
+ Log.d(TASKBAR_NOT_DESTROYED_TAG, "DisplayController#onConfigurationChanged: " + config);
Display display = mWindowContext.getDisplay();
if (config.densityDpi != mInfo.densityDpi
|| config.fontScale != mInfo.fontScale
@@ -272,7 +278,7 @@
change |= CHANGE_SUPPORTED_BOUNDS;
}
if (DEBUG) {
- Log.d(TAG, "handleInfoChange - change: 0b" + Integer.toBinaryString(change));
+ Log.d(TAG, "handleInfoChange - change: " + getChangeFlagsString(change));
}
if (change != 0) {
@@ -386,12 +392,33 @@
return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()), densityDpi);
}
+ /**
+ * Returns all displays for the device
+ */
+ public Set<CachedDisplayInfo> getAllDisplays() {
+ return Collections.unmodifiableSet(mPerDisplayBounds.keySet());
+ }
+
public int getDensityDpi() {
return densityDpi;
}
}
/**
+ * Returns the given binary flags as a human-readable string.
+ * @see #CHANGE_ALL
+ */
+ public String getChangeFlagsString(int change) {
+ StringJoiner result = new StringJoiner("|");
+ appendFlag(result, change, CHANGE_ACTIVE_SCREEN, "CHANGE_ACTIVE_SCREEN");
+ appendFlag(result, change, CHANGE_ROTATION, "CHANGE_ROTATION");
+ 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");
+ return result.toString();
+ }
+
+ /**
* Dumps the current state information
*/
public void dump(PrintWriter pw) {
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 8c5e782..1ae43d0 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -200,8 +200,8 @@
/** Keep in sync w/ ActivityTaskManager#INVALID_TASK_ID (unreference-able) */
private static final int INVALID_TASK_ID = -1;
- public final View view;
- public final Drawable drawable;
+ private View view;
+ private Drawable drawable;
public final Intent intent;
public final SplitPositionOption position;
public final ItemInfo itemInfo;
@@ -224,5 +224,13 @@
this.itemInfo = itemInfo;
this.splitEvent = splitEvent;
}
+
+ public Drawable getDrawable() {
+ return drawable;
+ }
+
+ public View getView() {
+ return view;
+ }
}
}
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 5d90291..3fa5799 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,11 +16,13 @@
package com.android.launcher3.util;
+import android.util.Log;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewTreeObserver.OnDrawListener;
import com.android.launcher3.Launcher;
+import com.android.launcher3.testing.shared.TestProtocol;
import java.util.function.Consumer;
@@ -42,12 +44,21 @@
private boolean mCancelled;
public ViewOnDrawExecutor(RunnableList tasks) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "Initialize ViewOnDrawExecutor");
+ }
mTasks = tasks;
}
public void attachTo(Launcher launcher) {
mOnClearCallback = launcher::clearPendingExecutor;
mAttachedView = launcher.getWorkspace();
+
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.attachTo: launcher=" + launcher
+ + ", isAttachedToWindow=" + mAttachedView.isAttachedToWindow());
+ }
+
mAttachedView.addOnAttachStateChangeListener(this);
if (mAttachedView.isAttachedToWindow()) {
@@ -56,6 +67,10 @@
}
private void attachObserver() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING,
+ "ViewOnDrawExecutor.attachObserver: mCompleted=" + mCompleted);
+ }
if (!mCompleted) {
mAttachedView.getViewTreeObserver().addOnDrawListener(this);
}
@@ -63,6 +78,9 @@
@Override
public void onViewAttachedToWindow(View v) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.onViewAttachedToWindow");
+ }
attachObserver();
}
@@ -71,11 +89,19 @@
@Override
public void onDraw() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.onDraw");
+ }
mFirstDrawCompleted = true;
mAttachedView.post(this);
}
public void onLoadAnimationCompleted() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING,
+ "ViewOnDrawExecutor.onLoadAnimationCompleted: mAttachedView != null="
+ + (mAttachedView != null));
+ }
mLoadAnimationCompleted = true;
if (mAttachedView != null) {
mAttachedView.post(this);
@@ -84,6 +110,12 @@
@Override
public void run() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING,
+ "ViewOnDrawExecutor.run: mLoadAnimationCompleted=" + mLoadAnimationCompleted
+ + ", mFirstDrawCompleted=" + mFirstDrawCompleted
+ + ", mCompleted=" + mCompleted);
+ }
// Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
markCompleted();
@@ -94,6 +126,12 @@
* Executes all tasks immediately
*/
public void markCompleted() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING,
+ "ViewOnDrawExecutor.markCompleted: mCancelled=" + mCancelled
+ + ", mOnClearCallback != null=" + (mOnClearCallback != null)
+ + ", mAttachedView != null=" + (mAttachedView != null));
+ }
if (!mCancelled) {
mTasks.executeAllAndDestroy();
}
@@ -108,6 +146,9 @@
}
public void cancel() {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FLAKY_BINDING, "ViewOnDrawExecutor.cancel");
+ }
mCancelled = true;
markCompleted();
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 2325376..5e165df 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -683,12 +683,13 @@
public static WidgetsFullSheet show(Launcher launcher, boolean animate) {
boolean isTwoPane = LARGE_SCREEN_WIDGET_PICKER.get()
&& launcher.getDeviceProfile().isTablet
- && launcher.getDeviceProfile().isLandscape;
+ && launcher.getDeviceProfile().isLandscape
+ && !launcher.getDeviceProfile().isTwoPanels;
WidgetsFullSheet sheet;
if (isTwoPane) {
sheet = (WidgetsTwoPaneSheet) launcher.getLayoutInflater().inflate(
- R.layout.widgets_full_sheet_large_screen,
+ R.layout.widgets_two_pane_sheet,
launcher.getDragLayer(),
false);
} else {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
index 46aae9d..d85737b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
@@ -64,7 +64,7 @@
0,
view.getMeasuredWidth(),
view.getMeasuredHeight() - getResources().getDimensionPixelSize(
- R.dimen.widget_list_horizontal_margin_large_screen),
+ R.dimen.widget_list_horizontal_margin_two_pane),
view.getResources().getDimensionPixelSize(
R.dimen.widget_list_top_bottom_corner_radius)
);
@@ -91,8 +91,8 @@
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
- int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_full_sheet_paged_view_large_screen
- : R.layout.widgets_full_sheet_recyclerview_large_screen;
+ int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_two_pane_sheet_paged_view
+ : R.layout.widgets_two_pane_sheet_recyclerview;
layoutInflater.inflate(contentLayoutRes, findViewById(R.id.recycler_view_container), true);
setupViews();
diff --git a/tests/res/raw/devices.json b/tests/res/raw/devices.json
deleted file mode 100644
index a78dd86..0000000
--- a/tests/res/raw/devices.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "pixel6pro": {
- "width": 1440,
- "height": 3120,
- "density": 560,
- "name": "pixel6pro",
- "cutout": "0, 130, 0, 0",
- "grids": [
- "normal",
- "reasonable",
- "practical",
- "big",
- "crazy_big"
- ],
- "resourceOverrides": {
- "status_bar_height": 98,
- "navigation_bar_height_landscape": 56,
- "navigation_bar_height": 56,
- "navigation_bar_width": 56
- }
- },
- "test": {
- "data needs updating": 0
- },
- "pixel5": {
- "width": 1080,
- "height": 2340,
- "density": 440,
- "name": "pixel5",
- "cutout": "0, 136, 0, 0",
- "grids": [
- "normal",
- "reasonable",
- "practical",
- "big",
- "crazy_big"
- ],
- "resourceOverrides": {
- "status_bar_height": 66,
- "navigation_bar_height_landscape": 44,
- "navigation_bar_height": 44,
- "navigation_bar_width": 44
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java b/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java
deleted file mode 100644
index e2ed65f..0000000
--- a/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java
+++ /dev/null
@@ -1,93 +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.deviceemulator;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
-
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.launcher3.deviceemulator.models.DeviceEmulationData;
-import com.android.launcher3.tapl.LauncherInstrumentation;
-import com.android.launcher3.util.window.WindowManagerProxy;
-
-import java.util.concurrent.Callable;
-
-
-public class DisplayEmulator {
- Context mContext;
- LauncherInstrumentation mLauncher;
- DisplayEmulator(Context context, LauncherInstrumentation launcher) {
- mContext = context;
- mLauncher = launcher;
- }
-
- /**
- * By changing the WindowManagerProxy we can override the window insets information
- **/
- private IWindowManager changeWindowManagerInstance(DeviceEmulationData deviceData) {
- WindowManagerProxy.INSTANCE.initializeForTesting(new TestWindowManagerProxy(deviceData));
- return WindowManagerGlobal.getWindowManagerService();
- }
-
- public <T> T emulate(DeviceEmulationData device, String grid, Callable<T> runInEmulation)
- throws Exception {
- WindowManagerProxy original = WindowManagerProxy.INSTANCE.get(mContext);
- // Set up emulation
- final int userId = UserHandle.myUserId();
- WindowManagerProxy.INSTANCE.initializeForTesting(new TestWindowManagerProxy(device));
- IWindowManager wm = changeWindowManagerInstance(device);
- // Change density twice to force display controller to reset its state
- wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, device.density / 2, userId);
- wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, device.density, userId);
- wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, device.width, device.height);
- wm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
-
- // Set up grid
- setGrid(grid);
- try {
- return runInEmulation.call();
- } finally {
- // Clear emulation
- WindowManagerProxy.INSTANCE.initializeForTesting(original);
- UiDevice.getInstance(getInstrumentation()).executeShellCommand("cmd window reset");
- }
- }
-
- private void setGrid(String gridType) {
- // When the grid changes, the desktop arrangement get stored in SQL and we need to wait to
- // make sure there is no SQL operations running and get SQL_BUSY error, that's why we need
- // to call mLauncher.waitForLauncherInitialized();
- mLauncher.waitForLauncherInitialized();
- String testProviderAuthority = mContext.getPackageName() + ".grid_control";
- Uri gridUri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority(testProviderAuthority)
- .appendPath("default_grid")
- .build();
- ContentValues values = new ContentValues();
- values.put("name", gridType);
- mContext.getContentResolver().update(gridUri, values, null, null);
- }
-}
diff --git a/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java b/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java
deleted file mode 100644
index 2d6bbcc..0000000
--- a/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java
+++ /dev/null
@@ -1,72 +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.deviceemulator;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.WindowInsets;
-
-import com.android.launcher3.deviceemulator.models.DeviceEmulationData;
-import com.android.launcher3.util.RotationUtils;
-import com.android.launcher3.util.WindowBounds;
-import com.android.launcher3.util.window.CachedDisplayInfo;
-import com.android.launcher3.util.window.WindowManagerProxy;
-
-public class TestWindowManagerProxy extends WindowManagerProxy {
-
- private final DeviceEmulationData mDevice;
-
- public TestWindowManagerProxy(DeviceEmulationData device) {
- super(true);
- mDevice = device;
- }
-
- @Override
- protected int getDimenByName(Resources res, String resName) {
- Integer mock = mDevice.resourceOverrides.get(resName);
- return mock != null ? mock : super.getDimenByName(res, resName);
- }
-
- @Override
- protected int getDimenByName(Resources res, String resName, String fallback) {
- return getDimenByName(res, resName);
- }
-
- @Override
- public CachedDisplayInfo getDisplayInfo(Context displayInfoContext) {
- int rotation = getRotation(displayInfoContext);
- Point size = new Point(mDevice.width, mDevice.height);
- RotationUtils.rotateSize(size, rotation);
- Rect cutout = new Rect(mDevice.cutout);
- RotationUtils.rotateRect(cutout, rotation);
- return new CachedDisplayInfo(size, rotation, cutout);
- }
-
- @Override
- public WindowBounds getRealBounds(Context displayInfoContext, CachedDisplayInfo info) {
- return estimateInternalDisplayBounds(displayInfoContext).get(
- getDisplayInfo(displayInfoContext))[getDisplay(displayInfoContext).getRotation()];
- }
-
- @Override
- public WindowInsets normalizeWindowInsets(Context context, WindowInsets oldInsets,
- Rect outInsets) {
- outInsets.set(getRealBounds(context, getDisplayInfo(context)).insets);
- return oldInsets;
- }
-}
diff --git a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java b/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
deleted file mode 100644
index 55b7bf1..0000000
--- a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
+++ /dev/null
@@ -1,154 +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.deviceemulator.models;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT;
-import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT_LANDSCAPE;
-import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
-import static com.android.launcher3.testing.shared.ResourceUtils.getDimenByName;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.os.Build;
-import android.util.ArrayMap;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.IOUtils;
-import com.android.launcher3.util.IntArray;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Map;
-
-public class DeviceEmulationData {
-
- public final int width;
- public final int height;
- public final int density;
- public final String name;
- public final String[] grids;
- public final Rect cutout;
- public final Map<String, Integer> resourceOverrides;
-
- private static final String[] EMULATED_SYSTEM_RESOURCES = new String[]{
- NAVBAR_HEIGHT,
- NAVBAR_HEIGHT_LANDSCAPE,
- NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE,
- "status_bar_height",
- };
-
- public DeviceEmulationData(int width, int height, int density, Rect cutout, String name,
- String[] grid,
- Map<String, Integer> resourceOverrides) {
- this.width = width;
- this.height = height;
- this.density = density;
- this.name = name;
- this.grids = grid;
- this.cutout = cutout;
- this.resourceOverrides = resourceOverrides;
- }
-
- public static DeviceEmulationData deviceFromJSON(JSONObject json) throws JSONException {
- int width = json.getInt("width");
- int height = json.getInt("height");
- int density = json.getInt("density");
- String name = json.getString("name");
-
- JSONArray gridArray = json.getJSONArray("grids");
- String[] grids = new String[gridArray.length()];
- for (int i = 0, count = grids.length; i < count; i++) {
- grids[i] = gridArray.getString(i);
- }
-
- IntArray deviceCutout = IntArray.fromConcatString(json.getString("cutout"));
- Rect cutout = new Rect(deviceCutout.get(0), deviceCutout.get(1), deviceCutout.get(2),
- deviceCutout.get(3));
-
-
- JSONObject resourceOverridesJson = json.getJSONObject("resourceOverrides");
- Map<String, Integer> resourceOverrides = new ArrayMap<>();
- for (String key : resourceOverridesJson.keySet()) {
- resourceOverrides.put(key, resourceOverridesJson.getInt(key));
- }
- return new DeviceEmulationData(width, height, density, cutout, name, grids,
- resourceOverrides);
- }
-
- @Override
- public String toString() {
- JSONObject json = new JSONObject();
- try {
- json.put("width", width);
- json.put("height", height);
- json.put("density", density);
- json.put("name", name);
- json.put("cutout", IntArray.wrap(
- cutout.left, cutout.top, cutout.right, cutout.bottom).toConcatString());
-
- JSONArray gridArray = new JSONArray();
- Arrays.stream(grids).forEach(gridArray::put);
- json.put("grids", gridArray);
-
-
- JSONObject resourceOverrides = new JSONObject();
- for (Map.Entry<String, Integer> e : this.resourceOverrides.entrySet()) {
- resourceOverrides.put(e.getKey(), e.getValue());
- }
- json.put("resourceOverrides", resourceOverrides);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return json.toString();
- }
-
- public static DeviceEmulationData getCurrentDeviceData(Context context) {
- DisplayController.Info info = DisplayController.INSTANCE.get(context).getInfo();
- String[] grids = InvariantDeviceProfile.INSTANCE.get(context)
- .parseAllGridOptions(context).stream()
- .map(go -> go.name).toArray(String[]::new);
- String code = Build.MODEL.replaceAll("\\s", "").toLowerCase();
-
- Map<String, Integer> resourceOverrides = new ArrayMap<>();
- for (String s : EMULATED_SYSTEM_RESOURCES) {
- resourceOverrides.put(s, getDimenByName(s, context.getResources(), 0));
- }
- return new DeviceEmulationData(info.currentSize.x, info.currentSize.y,
- info.getDensityDpi(), info.cutout, code, grids, resourceOverrides);
- }
-
- public static DeviceEmulationData getDevice(String deviceCode) throws Exception {
- return DeviceEmulationData.deviceFromJSON(readJSON().getJSONObject(deviceCode));
- }
-
- private static JSONObject readJSON() throws Exception {
- Context context = getInstrumentation().getContext();
- Resources myRes = context.getResources();
- int resId = myRes.getIdentifier("devices", "raw", context.getPackageName());
- try (InputStream is = myRes.openRawResource(resId)) {
- return new JSONObject(new String(IOUtils.toByteArray(is)));
- }
- }
-
-}
diff --git a/tests/src/com/android/launcher3/icons/IconCacheTest.java b/tests/src/com/android/launcher3/icons/IconCacheTest.java
new file mode 100644
index 0000000..08d6df3
--- /dev/null
+++ b/tests/src/com/android/launcher3/icons/IconCacheTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.icons;
+
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutInfo.Builder;
+import android.os.PersistableBundle;
+import android.text.TextUtils;
+
+import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.settings.SettingsActivity;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class IconCacheTest {
+
+ private Context mContext;
+ private IconCache mIconCache;
+
+ private ComponentName mMyComponent;
+
+ @Before
+ public void setup() {
+ mContext = getInstrumentation().getTargetContext();
+ mMyComponent = new ComponentName(mContext, SettingsActivity.class);
+
+ // In memory icon cache
+ mIconCache = new IconCache(mContext,
+ InvariantDeviceProfile.INSTANCE.get(mContext), null,
+ new LauncherIconProvider(mContext));
+ }
+
+ @Test
+ public void getShortcutInfoBadge_nullComponent_overrideAllowed() throws Exception {
+ String overridePackage = "com.android.settings";
+ ItemInfoWithIcon item = getBadgingInfo(mContext, null, overridePackage);
+ assertTrue(item instanceof PackageItemInfo);
+ assertEquals(((PackageItemInfo) item).packageName, overridePackage);
+ }
+
+ @Test
+ public void getShortcutInfoBadge_withComponent_overrideAllowed() throws Exception {
+ String overridePackage = "com.android.settings";
+ ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, overridePackage);
+ assertTrue(item instanceof PackageItemInfo);
+ assertEquals(((PackageItemInfo) item).packageName, overridePackage);
+ }
+
+ @Test
+ public void getShortcutInfoBadge_nullComponent() throws Exception {
+ ItemInfoWithIcon item = getBadgingInfo(mContext, null, null);
+ assertTrue(item instanceof PackageItemInfo);
+ assertEquals(((PackageItemInfo) item).packageName, mContext.getPackageName());
+ }
+
+ @Test
+ public void getShortcutInfoBadge_withComponent() throws Exception {
+ ItemInfoWithIcon item = getBadgingInfo(mContext, mMyComponent, null);
+ assertTrue(item instanceof AppInfo);
+ assertEquals(((AppInfo) item).componentName, mMyComponent);
+ }
+
+ @Test
+ public void getShortcutInfoBadge_overrideNotAllowed() throws Exception {
+ String overridePackage = "com.android.settings";
+ String otherPackage = mContext.getPackageName() + ".does.not.exist";
+ Context otherContext = new ContextWrapper(mContext) {
+ @Override
+ public String getPackageName() {
+ return otherPackage;
+ }
+ };
+ ItemInfoWithIcon item = getBadgingInfo(otherContext, null, overridePackage);
+ assertTrue(item instanceof PackageItemInfo);
+ // Badge is set to the original package, and not the override package
+ assertEquals(((PackageItemInfo) item).packageName, otherPackage);
+ }
+
+ private ItemInfoWithIcon getBadgingInfo(Context context,
+ @Nullable ComponentName cn, @Nullable String badgeOverride) throws Exception {
+ Builder builder = new Builder(context, "test-shortcut")
+ .setIntent(new Intent(Intent.ACTION_VIEW))
+ .setTitle("Test");
+ if (cn != null) {
+ builder.setActivity(cn);
+ }
+ if (!TextUtils.isEmpty(badgeOverride)) {
+ PersistableBundle extras = new PersistableBundle();
+ extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, badgeOverride);
+ builder.setExtras(extras);
+ }
+ ShortcutInfo info = builder.build();
+ return MODEL_EXECUTOR.submit(() -> mIconCache.getShortcutInfoBadgeItem(info)).get();
+ }
+}