Merge "Revert "Don't crash on dialer app target search results"" into sc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1fad72d..8066816 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml
index d2575b6..6a8f715 100644
--- a/go/AndroidManifest-launcher.xml
+++ b/go/AndroidManifest-launcher.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density|uiMode"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/go/quickstep/res/drawable/ic_listen.xml b/go/quickstep/res/drawable/ic_listen.xml
index a8e6c93..16bb597 100644
--- a/go/quickstep/res/drawable/ic_listen.xml
+++ b/go/quickstep/res/drawable/ic_listen.xml
@@ -13,20 +13,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
<path
- android:pathData="M10.5,15.17c2.58,0 4.67,-2.09 4.67,-4.67s-2.09,-4.67 -4.67,-4.67c-2.58,0 -4.67,2.09 -4.67,4.67S7.92,15.17 10.5,15.17zM10.5,8.17c1.28,0 2.33,1.05 2.33,2.33s-1.05,2.33 -2.33,2.33c-1.28,0 -2.33,-1.05 -2.33,-2.33S9.22,8.17 10.5,8.17z"
- android:fillColor="#4285F4"/>
- <path
- android:pathData="M10.5,17.5c-3.11,0 -9.33,1.56 -9.33,4.67v2.33h18.67v-2.33C19.83,19.06 13.62,17.5 10.5,17.5zM3.5,22.17c0.26,-0.84 3.86,-2.33 7,-2.33c3.15,0 6.77,1.5 7,2.33H3.5z"
- android:fillColor="#4285F4"/>
- <path
- android:pathData="M25.67,10.5c0,0.36 -0.02,0.71 -0.05,1.05c-0.01,0.15 -0.03,0.29 -0.05,0.43c-0.02,0.18 -0.05,0.36 -0.08,0.54c-0.04,0.2 -0.07,0.39 -0.12,0.58c-0.01,0.06 -0.03,0.11 -0.04,0.17c-0.59,2.34 -1.81,4.01 -2.52,4.82c-0.09,0.1 -0.18,0.2 -0.28,0.3c-0.17,0.18 -0.27,0.27 -0.27,0.27l-1.65,-1.63c1.34,-1.33 2.27,-3.07 2.6,-5.01c0.01,-0.08 0.02,-0.16 0.04,-0.24c0.06,-0.42 0.1,-0.85 0.1,-1.29c0,-0.44 -0.04,-0.88 -0.1,-1.3c-0.01,-0.06 -0.02,-0.13 -0.03,-0.19c-0.32,-1.95 -1.25,-3.7 -2.6,-5.04l1.65,-1.63c0,0 0.11,0.1 0.27,0.27c0.09,0.1 0.19,0.2 0.28,0.3c0.71,0.82 1.93,2.48 2.52,4.82c0.01,0.06 0.03,0.11 0.04,0.17c0.04,0.19 0.08,0.38 0.12,0.58c0.03,0.18 0.06,0.36 0.08,0.54c0.02,0.14 0.04,0.28 0.05,0.43C25.65,9.79 25.67,10.14 25.67,10.5z"
- android:fillColor="#EA4335"/>
- <path
- android:pathData="M20.61,8.4C20.85,9.06 21,9.76 21,10.5s-0.15,1.44 -0.39,2.1c-0.28,0.77 -0.71,1.46 -1.25,2.05l-1.66,-1.64c0.56,-0.63 0.91,-1.44 0.95,-2.34c0,-0.06 0.02,-0.11 0.02,-0.17s-0.01,-0.11 -0.02,-0.17c-0.04,-0.9 -0.39,-1.71 -0.95,-2.34l1.66,-1.64C19.9,6.94 20.32,7.63 20.61,8.4z"
- android:fillColor="#FBBC04"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M15.08,7.05c0.84,1.18 0.84,2.71 0,3.89l1.68,1.69c2.02,-2.02 2.02,-5.07 0,-7.27l-1.68,1.69zM20.07,2l-1.63,1.63c2.77,3.02 2.77,7.56 0,10.74L20.07,16c3.9,-3.89 3.91,-9.95 0,-14zM9,13c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM9,7c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2zM9,14c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4zM15,19L3,19v-0.99C3.2,17.29 6.3,16 9,16s5.8,1.29 6,2v1z"/>
</vector>
diff --git a/go/quickstep/res/drawable/ic_search.xml b/go/quickstep/res/drawable/ic_search.xml
index 4307330..ce290d9 100644
--- a/go/quickstep/res/drawable/ic_search.xml
+++ b/go/quickstep/res/drawable/ic_search.xml
@@ -13,20 +13,24 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
<path
- android:pathData="M24.5,22.75l-6.84,-6.84c1,-1.35 1.59,-3.02 1.59,-4.83h-2.33c0,3.22 -2.62,5.83 -5.83,5.83v2.33c1.81,0 3.47,-0.6 4.83,-1.59l6.84,6.84L24.5,22.75z"
- android:fillColor="#4285F4"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M16,3h-2v2h2c1.65,0 3,1.35 3,3v2h2V8C21,5.24 18.76,3 16,3z"/>
<path
- android:pathData="M11.08,2.92v2.33c3.22,0 5.83,2.62 5.83,5.83h2.33C19.25,6.57 15.59,2.92 11.08,2.92z"
- android:fillColor="#34A853"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M5,16v-2H3v2c0,2.76 2.24,5 5,5h2v-2H8C6.35,19 5,17.65 5,16z"/>
<path
- android:pathData="M5.25,11.08H2.92c0,4.51 3.66,8.17 8.17,8.17v-2.33C7.87,16.92 5.25,14.3 5.25,11.08z"
- android:fillColor="#EA4335"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M12,8.5c-1.93,0 -3.5,1.57 -3.5,3.5s1.57,3.5 3.5,3.5s3.5,-1.57 3.5,-3.5S13.93,8.5 12,8.5z"/>
<path
- android:pathData="M2.92,11.08h2.33c0,-3.22 2.62,-5.83 5.83,-5.83V2.92C6.57,2.92 2.92,6.57 2.92,11.08z"
- android:fillColor="#FBBC04"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M18,18m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5,8c0,-1.65 1.35,-3 3,-3h2V3H8C5.24,3 3,5.24 3,8v2h2V8z"/>
</vector>
diff --git a/go/quickstep/res/drawable/ic_translate.xml b/go/quickstep/res/drawable/ic_translate.xml
index 1247807..e3df56f 100644
--- a/go/quickstep/res/drawable/ic_translate.xml
+++ b/go/quickstep/res/drawable/ic_translate.xml
@@ -13,20 +13,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28"
- android:viewportHeight="28">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
<path
- android:pathData="M12.28,15.19l-0.07,-0.05c-0.61,-0.49 -1.15,-1.05 -1.65,-1.63c-1.05,-1.22 -1.88,-2.63 -2.39,-4.17H5.83c0.54,2.17 1.58,4.16 3.01,5.85l-5.93,5.23l1.75,1.75l5.91,-5.26c0.05,0.04 0.1,0.09 0.15,0.13l3.42,2.79l1.02,-2.33L12.28,15.19z"
- android:fillColor="#FBBC04"/>
- <path
- android:pathData="M21.58,11.67h-2.33l-5.25,14h2.33l1.31,-3.5h5.54l1.32,3.5h2.33L21.58,11.67zM18.53,19.83l1.89,-5.05l1.89,5.05H18.53z"
- android:fillColor="#4285F4"/>
- <path
- android:pathData="M11.67,2.33l-2.34,0l0,2.34l-8.16,0l0,2.33l10.5,0l0,-2.33z"
- android:fillColor="#EA4335"/>
- <path
- android:pathData="M11.67,4.67V7H14c-0.61,2.42 -1.79,4.65 -3.44,6.5c0.5,0.59 1.04,1.15 1.65,1.63l0.07,0.05c2.03,-2.32 3.44,-5.14 4.05,-8.19h3.5V4.67H11.67z"
- android:fillColor="#34A853"/>
+ android:fillColor="@android:color/white"
+ android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
</vector>
diff --git a/go/quickstep/res/drawable/round_rect_button.xml b/go/quickstep/res/drawable/round_rect_button.xml
new file mode 100644
index 0000000..b276686
--- /dev/null
+++ b/go/quickstep/res/drawable/round_rect_button.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="@dimen/go_button_corner_radius" />
+</shape>
diff --git a/go/quickstep/res/layout/overview_actions_container.xml b/go/quickstep/res/layout/overview_actions_container.xml
index 4aa7774..6a331ea 100644
--- a/go/quickstep/res/layout/overview_actions_container.xml
+++ b/go/quickstep/res/layout/overview_actions_container.xml
@@ -25,7 +25,7 @@
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center"
+ android:layout_gravity="top|center_horizontal"
android:orientation="horizontal">
<Space
@@ -33,62 +33,75 @@
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
- android:id="@+id/action_translate"
- style="@style/GoOverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_translate"
- android:drawablePadding="1dp"
- android:text="@string/action_translate"
- android:theme="@style/ThemeControlHighlightWorkspaceColor" />
+ <LinearLayout
+ style="@style/GoOverviewActionButtonContainer">
+ <ImageButton
+ android:id="@+id/action_translate"
+ style="@style/GoOverviewActionButton"
+ android:src="@drawable/ic_translate"
+ android:contentDescription="@string/action_translate" />
+ <TextView
+ style="@style/GoOverviewActionButtonCaption"
+ android:text="@string/action_translate" />
+ </LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
- android:id="@+id/action_listen"
- style="@style/GoOverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_listen"
- android:drawablePadding="1dp"
- android:text="@string/action_listen"
- android:theme="@style/ThemeControlHighlightWorkspaceColor" />
+ <LinearLayout
+ style="@style/GoOverviewActionButtonContainer">
+ <ImageButton
+ android:id="@+id/action_listen"
+ style="@style/GoOverviewActionButton"
+ android:src="@drawable/ic_listen"
+ android:contentDescription="@string/action_listen"
+ android:background="@drawable/round_rect_button" />
+ <TextView
+ style="@style/GoOverviewActionButtonCaption"
+ android:text="@string/action_listen" />
+ </LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
- android:id="@+id/action_screenshot"
- style="@style/GoOverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_screenshot"
- android:drawablePadding="1dp"
- android:text="@string/action_screenshot"
- android:theme="@style/ThemeControlHighlightWorkspaceColor" />
+ <LinearLayout
+ style="@style/GoOverviewActionButtonContainer">
+ <ImageButton
+ android:id="@+id/action_screenshot"
+ style="@style/GoOverviewActionButton"
+ android:src="@drawable/ic_screenshot"
+ android:contentDescription="@string/action_screenshot"
+ android:background="@drawable/round_rect_button" />
+ <TextView
+ style="@style/GoOverviewActionButtonCaption"
+ android:text="@string/action_screenshot" />
+ </LinearLayout>
<Space
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
- <Button
- android:id="@+id/action_search"
- style="@style/GoOverviewActionButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/ic_search"
- android:drawablePadding="1dp"
- android:text="@string/action_search"
- android:theme="@style/ThemeControlHighlightWorkspaceColor"
- android:visibility="gone" />
+ <!-- Will be enabled in a future version. -->
+ <LinearLayout
+ style="@style/GoOverviewActionButtonContainer"
+ android:visibility="gone" >
+ <ImageButton
+ android:id="@+id/action_search"
+ style="@style/GoOverviewActionButton"
+ android:src="@drawable/ic_search"
+ android:contentDescription="@string/action_search"
+ android:background="@drawable/round_rect_button" />
+ <TextView
+ style="@style/GoOverviewActionButtonCaption"
+ android:text="@string/action_search" />
+ </LinearLayout>
+ <!-- Unused. Included only for compatibility with parent class. -->
<Button
android:id="@+id/action_share"
style="@style/GoOverviewActionButton"
@@ -98,13 +111,6 @@
android:text="@string/action_share"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
-
- <Space
- android:id="@+id/oav_three_button_space"
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1"
- android:visibility="gone" />
</LinearLayout>
</com.android.quickstep.views.GoOverviewActionsView>
\ No newline at end of file
diff --git a/go/quickstep/res/values-af/strings.xml b/go/quickstep/res/values-af/strings.xml
new file mode 100644
index 0000000..8570531
--- /dev/null
+++ b/go/quickstep/res/values-af/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Deel program"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Luister"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Vertaal"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-da/strings.xml b/go/quickstep/res/values-da/strings.xml
new file mode 100644
index 0000000..46648ce
--- /dev/null
+++ b/go/quickstep/res/values-da/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Del app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Lyt"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Oversæt"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-en-rAU/strings.xml b/go/quickstep/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..3a609b6
--- /dev/null
+++ b/go/quickstep/res/values-en-rAU/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-en-rCA/strings.xml b/go/quickstep/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..3a609b6
--- /dev/null
+++ b/go/quickstep/res/values-en-rCA/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-en-rGB/strings.xml b/go/quickstep/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..3a609b6
--- /dev/null
+++ b/go/quickstep/res/values-en-rGB/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-en-rIN/strings.xml b/go/quickstep/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..3a609b6
--- /dev/null
+++ b/go/quickstep/res/values-en-rIN/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-en-rXC/strings.xml b/go/quickstep/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..614f69a
--- /dev/null
+++ b/go/quickstep/res/values-en-rXC/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share App"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-es-rUS/strings.xml b/go/quickstep/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..e6946d7
--- /dev/null
+++ b/go/quickstep/res/values-es-rUS/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartir app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Escuchar"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Traducir"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-fa/strings.xml b/go/quickstep/res/values-fa/strings.xml
new file mode 100644
index 0000000..491b32f
--- /dev/null
+++ b/go/quickstep/res/values-fa/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"همرسانی برنامه"</string>
+ <string name="action_listen" msgid="2370304050784689486">"گوش دادن"</string>
+ <string name="action_translate" msgid="8028378961867277746">"ترجمه"</string>
+ <string name="action_search" msgid="6269564710943755464">"لنز"</string>
+</resources>
diff --git a/go/quickstep/res/values-kn/strings.xml b/go/quickstep/res/values-kn/strings.xml
new file mode 100644
index 0000000..1083e84
--- /dev/null
+++ b/go/quickstep/res/values-kn/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"ಆ್ಯಪ್ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="action_listen" msgid="2370304050784689486">"ಆಲಿಸಿ"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-ms/strings.xml b/go/quickstep/res/values-ms/strings.xml
new file mode 100644
index 0000000..39698e8
--- /dev/null
+++ b/go/quickstep/res/values-ms/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Kongsi Apl"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Dengar"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Terjemah"</string>
+ <string name="action_search" msgid="6269564710943755464">"Kanta"</string>
+</resources>
diff --git a/go/quickstep/res/values-nl/strings.xml b/go/quickstep/res/values-nl/strings.xml
new file mode 100644
index 0000000..ff5f16b
--- /dev/null
+++ b/go/quickstep/res/values-nl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"App delen"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Luisteren"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Vertalen"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-pl/strings.xml b/go/quickstep/res/values-pl/strings.xml
new file mode 100644
index 0000000..a9696a6
--- /dev/null
+++ b/go/quickstep/res/values-pl/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Udostępnij aplikację"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Posłuchaj"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Przetłumacz"</string>
+ <string name="action_search" msgid="6269564710943755464">"Obiektyw"</string>
+</resources>
diff --git a/go/quickstep/res/values-pt/strings.xml b/go/quickstep/res/values-pt/strings.xml
new file mode 100644
index 0000000..6be2219
--- /dev/null
+++ b/go/quickstep/res/values-pt/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartilhar app"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Ouvir"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Traduzir"</string>
+ <string name="action_search" msgid="6269564710943755464">"Google Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-sk/strings.xml b/go/quickstep/res/values-sk/strings.xml
new file mode 100644
index 0000000..f142492
--- /dev/null
+++ b/go/quickstep/res/values-sk/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Zdieľať aplikáciu"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Počúvať"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Preložiť"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-uz/strings.xml b/go/quickstep/res/values-uz/strings.xml
new file mode 100644
index 0000000..4e375c7
--- /dev/null
+++ b/go/quickstep/res/values-uz/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Ilovani ulashish"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Tinglash"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Tarjimon"</string>
+ <string name="action_search" msgid="6269564710943755464">"Lens"</string>
+</resources>
diff --git a/go/quickstep/res/values-zu/strings.xml b/go/quickstep/res/values-zu/strings.xml
new file mode 100644
index 0000000..6dd94cb
--- /dev/null
+++ b/go/quickstep/res/values-zu/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"Yabelana nge-App"</string>
+ <string name="action_listen" msgid="2370304050784689486">"Lalela"</string>
+ <string name="action_translate" msgid="8028378961867277746">"Humusha"</string>
+ <string name="action_search" msgid="6269564710943755464">"Ilensi"</string>
+</resources>
diff --git a/go/quickstep/res/values/colors.xml b/go/quickstep/res/values/colors.xml
new file mode 100644
index 0000000..9383770
--- /dev/null
+++ b/go/quickstep/res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Overview -->
+ <color name="go_overview_button_icon_color">#3C4043</color>
+ <color name="go_overview_button_color">#70FFFFFF</color>
+</resources>
diff --git a/go/quickstep/res/values/dimens.xml b/go/quickstep/res/values/dimens.xml
new file mode 100644
index 0000000..cb260b5
--- /dev/null
+++ b/go/quickstep/res/values/dimens.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <dimen name="go_button_corner_radius">20dp</dimen>
+
+ <!-- Overview -->
+ <dimen name="go_overview_button_width">60dp</dimen>
+ <dimen name="go_overview_button_height">60dp</dimen>
+ <dimen name="go_overview_button_container_width">80dp</dimen>
+ <dimen name="go_overview_button_caption_margin">8dp</dimen>
+</resources>
diff --git a/go/quickstep/res/values/styles.xml b/go/quickstep/res/values/styles.xml
index 927c49a..df49ecd 100644
--- a/go/quickstep/res/values/styles.xml
+++ b/go/quickstep/res/values/styles.xml
@@ -15,12 +15,31 @@
limitations under the License.
-->
<resources>
- <style name="GoOverviewActionButton"
- parent="@android:style/Widget.DeviceDefault.Button">
- <item name="android:textColor">@color/overview_button</item>
- <item name="android:drawableTint">@color/overview_button</item>
- <item name="android:tint">?android:attr/textColorPrimary</item>
- <item name="android:drawablePadding">8dp</item>
- <item name="android:textAllCaps">false</item>
+ <style name="GoOverviewActionButton">
+ <item name="android:tint">@color/go_overview_button_icon_color</item>
+ <item name="android:backgroundTint">@color/go_overview_button_color</item>
+ <item name="android:background">@drawable/round_rect_button</item>
+ <item name="android:layout_width">@dimen/go_overview_button_width</item>
+ <item name="android:layout_height">@dimen/go_overview_button_height</item>
+ <item name="android:layout_gravity">center_horizontal</item>
+ </style>
+
+ <style name="GoOverviewActionButtonCaption">
+ <item name="android:fontFamily">roboto-medium</item>
+ <item name="android:textSize">14dp</item>
+ <item name="android:textColor">@color/go_overview_button_icon_color</item>
+ <item name="android:lineHeight">20dp</item>
+ <item name="android:textAlignment">center</item>
+ <item name="android:importantForAccessibility">no</item>
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_marginTop">@dimen/go_overview_button_caption_margin</item>
+ <item name="android:layout_gravity">center_horizontal</item>
+ </style>
+
+ <style name="GoOverviewActionButtonContainer">
+ <item name="android:layout_width">@dimen/go_overview_button_container_width</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:orientation">vertical</item>
</style>
</resources>
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index 79e50ef..67e9d89 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -49,6 +49,7 @@
public static final String ACTION_SEARCH = "com.android.quickstep.ACTION_SEARCH";
public static final String ELAPSED_NANOS = "niu_actions_elapsed_realtime_nanos";
public static final String ACTIONS_URL = "niu_actions_app_url";
+ public static final String ACTIONS_APP_PACKAGE = "niu_actions_app_package";
public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code";
public static final int ERROR_PERMISSIONS = 1;
private static final String TAG = "TaskOverlayFactoryGo";
@@ -72,6 +73,7 @@
*/
public static final class TaskOverlayGo<T extends OverviewActionsView> extends TaskOverlay {
private String mNIUPackageName;
+ private String mTaskPackageName;
private String mWebUrl;
private boolean mAssistPermissionsEnabled;
@@ -87,7 +89,7 @@
boolean rotated) {
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
mNIUPackageName =
- mApplicationContext.getResources().getString(R.string.niu_actions_package);
+ mApplicationContext.getString(R.string.niu_actions_package);
if (thumbnail == null || TextUtils.isEmpty(mNIUPackageName)) {
return;
@@ -96,6 +98,7 @@
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
+ mTaskPackageName = task.key.getPackageName();
checkPermissions();
if (!mAssistPermissionsEnabled) {
@@ -150,6 +153,7 @@
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
.setPackage(mNIUPackageName)
+ .putExtra(ACTIONS_APP_PACKAGE, mTaskPackageName)
.putExtra(ELAPSED_NANOS, SystemClock.elapsedRealtimeNanos());
if (mWebUrl != null) {
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 7fe9b08..6808222 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 842abc3..bf9059f 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -71,7 +71,7 @@
android:stateNotNeeded="true"
android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""/>
@@ -103,16 +103,40 @@
android:clearTaskOnLaunch="true"
android:exported="false"/>
+ <!--
+ Activity for gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
- android:autoRemoveFromRecents="true"
- android:excludeFromRecents="true"
- android:screenOrientation="portrait"
- android:exported="true">
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
<intent-filter>
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
+
+ <!--
+ Activity following gesture nav onboarding.
+ It's protected by android.permission.REBOOT to ensure that only system apps can start it
+ (setup wizard already has this permission)
+ -->
+ <activity android:name="com.android.quickstep.interaction.AllSetActivity"
+ android:autoRemoveFromRecents="true"
+ android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
+ android:permission="android.permission.REBOOT"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.quickstep.action.GESTURE_ONBOARDING_ALL_SET"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
+
<activity
android:name=".hybridhotseat.HotseatEduActivity"
android:theme="@android:style/Theme.NoDisplay"
diff --git a/quickstep/res/drawable/ic_all_set.xml b/quickstep/res/drawable/ic_all_set.xml
new file mode 100644
index 0000000..a6852aa
--- /dev/null
+++ b/quickstep/res/drawable/ic_all_set.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="42dp"
+ android:height="40dp"
+ android:viewportWidth="42"
+ android:viewportHeight="40">
+ <path
+ android:pathData="M38,14H25.38L27.28,4.86L27.34,4.22C27.34,3.4 27,2.64 26.46,2.1L24.34,0C24.34,0 10.16,13.7 10,14H0V40H32C33.66,40 35.08,39 35.68,37.56L41.72,23.46C41.9,23 42,22.52 42,22V18C42,15.8 40.2,14 38,14ZM10,36H4V18H10V36ZM38,22L32,36H14V16L22.68,7.32L20,18H38V22Z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/quickstep/res/drawable/ic_ime_switcher.xml b/quickstep/res/drawable/ic_ime_switcher.xml
new file mode 100644
index 0000000..a86d390
--- /dev/null
+++ b/quickstep/res/drawable/ic_ime_switcher.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M19,7h2v2h-2V7zM15,7h2v2h-2V7zM3,7h2v2H3V7zM7,7h2v2H7V7zM11,7h2v2h-2V7zM19,11h2v2h-2V11zM15,11h2v2h-2V11zM3,11h2v2H3V11zM7,11h2v2H7V11zM11,11h2v2h-2V11zM7,15h10v2H7V15z"
+ android:fillColor="@android:color/white" />
+</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_back.xml b/quickstep/res/drawable/ic_sysbar_back.xml
new file mode 100644
index 0000000..1eea677
--- /dev/null
+++ b/quickstep/res/drawable/ic_sysbar_back.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:autoMirrored="true"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.49,14.86c-0.66-0.39-0.66-1.34,0-1.73l6.02-3.53l5.89-3.46C19.11,5.73,20,6.26,20,7.1V14v6.9 c0,0.84-0.89,1.37-1.6,0.95l-5.89-3.46L6.49,14.86z" />
+</vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_home.xml b/quickstep/res/drawable/ic_sysbar_home.xml
new file mode 100644
index 0000000..b4b397b
--- /dev/null
+++ b/quickstep/res/drawable/ic_sysbar_home.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 14 7 C 17.8659932488 7 21 10.1340067512 21 14 C 21 17.8659932488 17.8659932488 21 14 21 C 10.1340067512 21 7 17.8659932488 7 14 C 7 10.1340067512 10.1340067512 7 14 7 Z" />
+</vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_recent.xml b/quickstep/res/drawable/ic_sysbar_recent.xml
new file mode 100644
index 0000000..f8c4778
--- /dev/null
+++ b/quickstep/res/drawable/ic_sysbar_recent.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M19.9,21.5H8.1c-0.88,0-1.6-0.72-1.6-1.6V8.1c0-0.88,0.72-1.6,1.6-1.6h11.8c0.88,0,1.6,0.72,1.6,1.6v11.8 C21.5,20.78,20.78,21.5,19.9,21.5z" />
+</vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml b/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml
new file mode 100644
index 0000000..d6160de
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2021 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/taskbar_icon_selection_ripple">
+ <item android:id="@android:id/mask">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/white" />
+ <corners android:radius="8dp" />
+ </shape>
+ </item>
+</ripple>
\ No newline at end of file
diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml
new file mode 100644
index 0000000..a6a17e5
--- /dev/null
+++ b/quickstep/res/layout/activity_allset.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="@dimen/allset_page_margin_horizontal"
+ android:paddingEnd="@dimen/allset_page_margin_horizontal"
+ android:layoutDirection="locale"
+ android:textDirection="locale"
+ android:background="?android:attr/colorBackground">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="start"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_icon_margin_top"
+ android:src="@drawable/ic_all_set"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_title"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_subtitle_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_description"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/navigation_settings"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/hint"
+ android:gravity="center_horizontal"
+ android:layout_marginBottom="72dp"/>
+
+ <TextView
+ android:id="@id/hint"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/allset_hint_margin_bottom"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:text="@string/allset_hint"/>
+</RelativeLayout>
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index d7bcd9e..f303f31 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -15,12 +15,6 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <com.android.quickstep.views.SplitPlaceholderView
- android:id="@+id/split_placeholder"
- android:layout_width="match_parent"
- android:layout_height="@dimen/split_placeholder_size"
- android:background="@android:color/darker_gray"
- android:visibility="gone" />
<com.android.quickstep.views.LauncherRecentsView
android:id="@+id/overview_panel"
@@ -31,6 +25,13 @@
android:clipToPadding="false"
android:visibility="invisible" />
+ <com.android.quickstep.views.SplitPlaceholderView
+ android:id="@+id/split_placeholder"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/split_placeholder_size"
+ android:background="@android:color/darker_gray"
+ android:visibility="gone" />
+
<include
android:id="@+id/overview_actions_view"
layout="@layout/overview_actions_container" />
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 732222a..240fe55 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -26,4 +26,10 @@
android:layout_height="wrap_content"
android:gravity="center"/>
+ <com.android.launcher3.taskbar.ImeBarView
+ android:id="@+id/ime_bar_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"/>
+
</com.android.launcher3.taskbar.TaskbarContainerView>
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 815ba04..0a82e04 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probeer weer"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Mooi so!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriaal <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Gereed!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swiep op om na die tuisskerm toe te gaan"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Jy is gereed om jou foon te begin gebruik"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigasie-instellings vir toeganklikheid"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Deel"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skermkiekie"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Jou organisasie laat nie hierdie program toe nie"</string>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 5a3df9d..c74819e 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"እንደገና ሞክር"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ጥሩ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"አጋዥ ሥልጠና <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"አጋራ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ቅጽበታዊ ገጽ እይታ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ይህ ድርጊት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 8205f89..cf4407e 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"إعادة المحاولة"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"أحسنت"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"الدليل التوجيهي <xliff:g id="CURRENT">%1$d</xliff:g> من إجمالي <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"مشاركة"</string>
<string name="action_screenshot" msgid="8171125848358142917">"لقطة شاشة"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء."</string>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 9b22c62..8c11cdd 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"পুনৰ চেষ্টা কৰক"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"সুন্দৰ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"টিউট’ৰিয়েল <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"শ্বেয়াৰ কৰক"</string>
<string name="action_screenshot" msgid="8171125848358142917">"স্ক্ৰীনশ্বট"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"এপ্টোৱে অথবা আপোনাৰ প্ৰতিষ্ঠানে এই কাৰ্যটোৰ অনুমতি নিদিয়ে"</string>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index bd88392..0d8e5b9 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Yenə sınayın"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Əla!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Dərslik <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Paylaşın"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Ekran şəkli"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Bu əməliyyata tətbiq və ya təşkilatınız tərəfindən icazə verilmir"</string>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 21295fc..8f3a555 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probajte ponovo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Svaka čast!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Deli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili organizacija ne dozvoljavaju ovu radnju"</string>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index d31468c..0473b5f 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Паўтарыць спробу"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Выдатна!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Дапаможнік <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Абагуліць"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Здымак экрана"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Гэта дзеянне не дазволена праграмай ці вашай арганізацыяй"</string>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index d2554d5..f7845e3 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Опитайте отново"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудесно!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Урок <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Споделяне"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Екранна снимка"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Това действие не е разрешено от приложението или организацията ви"</string>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 48d2690..c99f9b0 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"আবার চেষ্টা করুন"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"সাবাস!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"টিউটোরিয়াল <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"শেয়ার করুন"</string>
<string name="action_screenshot" msgid="8171125848358142917">"স্ক্রিনশট নিন"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"এই অ্যাপ বা আপনার প্রতিষ্ঠান এই অ্যাকশনটি পারফর্ম করার অনুমতি দেয়নি"</string>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 18494a9..15979c1 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Pokušaj ponovo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Lijepo!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Dijeli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ovu radnju ne dozvoljava aplikacija ili vaša organizacija"</string>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 7c417ef..795f2e4 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Torna-ho a provar"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Molt bé!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Comparteix"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"L\'aplicació o la teva organització no permeten aquesta acció"</string>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 9d1b94e..b2e222f 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zkusit znovu"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Skvělé!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Výukový program <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Sdílet"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snímek obrazovky"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikace nebo organizace zakazuje tuto akci"</string>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index 42098dc..f4519b8 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Prøv igen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Sådan!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Selvstudie <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Alt er parat!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Stryg opad for at gå til startsiden"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Du er klar til at bruge din telefon"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigationsindstillinger for hjælpefunktioner"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Del"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller din organisation tillader ikke denne handling"</string>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index e7d9523..3e63458 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Wiederholen"</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>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Teilen"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Die App oder deine Organisation lässt diese Aktion nicht zu"</string>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 21c2984..0eb9098 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Δοκιμάστε ξανά"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Ωραία!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Οδηγός <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Κοινοποίηση"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Στιγμιότυπο οθόνης"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Αυτή η ενέργεια δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας."</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index 487d6cc..5aae288 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
+ <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigation settings for accessibility"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Share"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 487d6cc..5aae288 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
+ <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigation settings for accessibility"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Share"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index 487d6cc..5aae288 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
+ <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigation settings for accessibility"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Share"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index 487d6cc..5aae288 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
+ <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigation settings for accessibility"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Share"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index 36df9d1..4d10fd5 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"All set!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe up to go home"</string>
+ <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071">""<annotation id="link">"Navigation settings for accessibility"</annotation>""</string>
<string name="action_share" msgid="2648470652637092375">"Share"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organization"</string>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 478d1cd..10f4479 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reintentar"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"¡Genial!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Instructivo <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Todo listo"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Desliza el dedo hacia arriba para ir a la página principal"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Ya puedes empezar a usar tu teléfono"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Configuración de la navegación para accesibilidad"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Compartir"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"La app o tu organización no permiten realizar esta acción"</string>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 454bea7..46bd267 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reintentar"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"¡Muy bien!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Compartir"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Hacer captura"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"No puedes hacerlo porque la aplicación o tu organización no lo permiten"</string>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index b729934..b059585 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Proovige uuesti"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Tubli töö!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Õpetus <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Jaga"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Ekraanipilt"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Rakendus või teie organisatsioon on selle toimingu keelanud"</string>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index f6d3f23..10232a4 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Saiatu berriro"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Ederki!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriala: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Partekatu"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Atera pantaila-argazki bat"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikazioak edo erakundeak ez du eman ekintza hori gauzatzeko baimena"</string>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 8ca0f95..bd8f3b8 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"امتحان مجدد"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"عالی!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"آموزش گامبهگام <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"همه چیز آماده است!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"برای رفتن به صفحه اصلی، تند بهبالا بکشید"</string>
+ <string name="allset_description" msgid="6350320429953234580">"آمادهاید از تلفنتان استفاده کنید"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"تنظیمات پیمایش برای دسترسپذیری"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"همرسانی"</string>
<string name="action_screenshot" msgid="8171125848358142917">"نماگرفت"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"برنامه یا سازمان شما اجازه نمیدهد این کنش انجام شود."</string>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 9ce7e6b..d75d7a3 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Yritä uudelleen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Hienoa!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Ohje <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Jaa"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Kuvakaappaus"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Sovellus tai organisaatio ei salli tätä toimintoa"</string>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index da73849..59ef61a 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Réessayer"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bien!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Étape <xliff:g id="CURRENT">%1$d</xliff:g> sur <xliff:g id="TOTAL">%2$d</xliff:g> du tutoriel"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Partager"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"L\'application ou votre organisation n\'autorise pas cette action"</string>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index b6abea7..394b7cd 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Réessayez"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bravo !"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriel <xliff:g id="CURRENT">%1$d</xliff:g> sur <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Partager"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Cette action n\'est pas autorisée par l\'application ou par votre organisation"</string>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 9310d71..f7e3058 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Téntao de novo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Excelente!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Titorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Compartir"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Facer captura"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"A aplicación ou a túa organización non permite realizar esta acción"</string>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 496d33b..62aa28e 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ફરી પ્રયાસ કરો"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"સરસ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ટ્યૂટૉરિઅલ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"શેર કરો"</string>
<string name="action_screenshot" msgid="8171125848358142917">"સ્ક્રીનશૉટ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ઍપ કે તમારી સંસ્થા દ્વારા આ ક્રિયા કરવાની મંજૂરી નથી"</string>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index a7711fe..a39faf0 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"फिर से कोशिश करें"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"बहुत बढ़िया!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्यूटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"शेयर करें"</string>
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता"</string>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index d5e4b9d..e3e62bd 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Pokušajte ponovo"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Odlično!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Podijeli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snimka zaslona"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili vaša organizacija ne dopuštaju ovu radnju"</string>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 386ef3e..49c0c1b 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Újra"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Remek!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Útmutató (<xliff:g id="TOTAL">%2$d</xliff:g>/<xliff:g id="CURRENT">%1$d</xliff:g>.)"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Megosztás"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Képernyőkép"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Az alkalmazás vagy az Ön szervezete nem engedélyezi ezt a műveletet"</string>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 3ff9d0d..9b25392 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Նորից փորձեք"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Գերազանց է"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Ուղեցույց <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Կիսվել"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Սքրինշոթ անել"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից"</string>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 941bdb7..dc105b5 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Coba lagi"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Bagikan"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda"</string>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 6042b47..eb5fc95 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reyna aftur"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Flott!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Leiðsögn <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Deila"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skjámynd"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Forritið eða fyrirtækið leyfir ekki þessa aðgerð"</string>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 6c81d17..a17c188 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Riprova"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bene!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Condividi"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Questa azione non è consentita dall\'app o dall\'organizzazione"</string>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index b77faeb..da2e79a 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"אפשר לנסות שוב"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"איזה יופי!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"מדריך <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"שיתוף"</string>
<string name="action_screenshot" msgid="8171125848358142917">"צילום מסך"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"האפליקציה או הארגון שלך אינם מתירים את הפעולה הזאת"</string>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 1cbdf73..960b839 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"再試行"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"成功"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"チュートリアル <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"共有"</string>
<string name="action_screenshot" msgid="8171125848358142917">"スクリーンショット"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"この操作はアプリまたは組織で許可されていません"</string>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 5dd818d..8b3b95c 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ხელახლა ცდა"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"მშვენიერია!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"სახელმძღვანელო <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"გაზიარება"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ეკრანის ანაბეჭდი"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ეს მოქმედება არ არის დაშვებული აპის ან თქვენი ორგანიზაციის მიერ"</string>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 554d10d..45618e0 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Қайталау"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Жақсы!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Оқулық: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Бөлісу"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Бұл әрекетке қолданба не ұйым рұқсат етпейді."</string>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 62858ba..9e12034 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ព្យាយាមម្ដងទៀត"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ល្អ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"មេរៀនទី <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"ចែករំលែក"</string>
<string name="action_screenshot" msgid="8171125848358142917">"រូបថតអេក្រង់"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"សកម្មភាពនេះមិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី ឬស្ថាប័នរបស់អ្នកទេ"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 8fdba69..3cf37b4 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ಚೆನ್ನಾಗಿದೆ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ಟ್ಯುಟೋರಿಯಲ್ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="allset_description" msgid="6350320429953234580">"ನಿಮ್ಮ ಫೋನ್ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"ಅಕ್ಸೆಸಿಬಿಲಿಟಿಗಾಗಿ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್ಗಳು"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ಸ್ಕ್ರೀನ್ಶಾಟ್"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ಆ್ಯಪ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಕ್ರಿಯೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index fbbddd6..63f2d96 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"다시 시도"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"잘하셨습니다"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"튜토리얼 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"공유"</string>
<string name="action_screenshot" msgid="8171125848358142917">"스크린샷"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"이 작업은 앱 또는 조직에서 허용되지 않습니다."</string>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index bd50eed..5d2d7e0 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Кайра аракет кылыңыз"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Сонун!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Үйрөткүч: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Бөлүшүү"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Бул аракетти аткарууга колдонмо же ишканаңыз тыюу салган"</string>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index e05b18e..ee09438 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ລອງໃໝ່"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ດີ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ການສອນການນຳໃຊ້ທີ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"ແບ່ງປັນ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ຮູບໜ້າຈໍ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ແອັບ ຫຼື ອົງການຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ໃຊ້ຄຳສັ່ງນີ້"</string>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 2f1db50..d2f217f 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Bandykite dar kartą"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Šaunu!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Mokymo programa: <xliff:g id="CURRENT">%1$d</xliff:g> iš <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Bendrinti"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Ekrano kopija"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Jūsų organizacijoje arba naudojant šią programą neleidžiama atlikti šio veiksmo"</string>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index ce941bc..702e97a 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Mēģināt vēlreiz"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Lieliski!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"<xliff:g id="CURRENT">%1$d</xliff:g>. mācību darbība no <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Kopīgot"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Veikt ekrānuzņēmumu"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Lietotne vai jūsu organizācija neatļauj veikt šo darbību."</string>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index f9fd8b3..2da1cec 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Обиди се пак"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Одлично!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Упатство <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Сподели"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Слика од екранот"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Апликацијата или вашата организација не го дозволува дејствово"</string>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index fc6bc82..ebd804a 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"വീണ്ടും ശ്രമിക്കുക"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"കൊള്ളാം!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ട്യൂട്ടോറിയൽ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"പങ്കിടുക"</string>
<string name="action_screenshot" msgid="8171125848358142917">"സ്ക്രീൻഷോട്ട്"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ഈ നടപടി എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 48513eb..f7fb0f8 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Дахин оролдох"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Янзтай!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"<xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g> практик хичээл"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Хуваалцах"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Дэлгэцийн агшин дарах"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Энэ үйлдлийг апп эсвэл танай байгууллага зөвшөөрдөггүй"</string>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index c576cf1..bac7f78 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"पुन्हा प्रयत्न करा"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"छान!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्युटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"शेअर करा"</string>
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"अॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही"</string>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 74b9d08..d80e6b3 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Cuba lagi"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Siap!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Leret ke atas untuk mencapai laman utama"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Anda sudah sedia untuk mula menggunakan telefon anda"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Tetapan navigasi untuk kebolehaksesan"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Kongsi"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Tangkapan skrin"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak dibenarkan oleh apl atau organisasi anda"</string>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 919ad6e..d61f800 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ထပ်စမ်းကြည့်ရန်"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ကောင်းသည်။"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ရှင်းလင်းပို့ချချက် <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"မျှဝေရန်"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ဤလုပ်ဆောင်ချက်ကို အက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 6e7e4a3..e725ebe 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Prøv igjen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bra!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Veiledning <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Del"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skjermdump"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisasjonen din tillater ikke denne handlingen"</string>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index f3b1151..369649a 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"फेरि प्रयास गर्नुहोस्"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"राम्रो!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्युटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"सेयर गर्नुहोस्"</string>
<string name="action_screenshot" msgid="8171125848358142917">"स्क्रिनसट"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन"</string>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index be9329f..ebf8485 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Opnieuw"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Dat gaat lekker."</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Klaar!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swipe omhoog om naar het startscherm te gaan"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Je bent klaar om je telefoon te gebruiken"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Navigatie-instellingen voor toegankelijkheid"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Delen"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Deze actie wordt niet toegestaan door de app of je organisatie"</string>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 8c36972..9cbbd35 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ବଢ଼ିଆ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ଟ୍ୟୁଟୋରିଆଲ୍ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"ସେୟାର୍ କରନ୍ତୁ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ସ୍କ୍ରିନସଟ୍"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ଆପ୍ କିମ୍ବା ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ଏହି କାର୍ଯ୍ୟକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 227c060..56b66c7 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ਵਧੀਆ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ਟਿਊਟੋਰੀਅਲ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"ਸਾਂਝਾ ਕਰੋ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਕਾਰਵਾਈ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 61d9b93..e01dc08 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Spróbuj ponownie"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Super!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Samouczek <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Wszystko gotowe"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Aby przejść na stronę główną, przesuń w górę"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Teraz możesz zacząć używać telefonu"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Ustawienia nawigacji na potrzeby ułatwień dostępu"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Udostępnij"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Zrzut ekranu"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Nie możesz wykonać tego działania, bo nie zezwala na to aplikacja lub Twoja organizacja"</string>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 0feead7..5fd560a 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tente novamente"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Boa!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Partilhar"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Fazer captura de ecrã"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Esta ação não é permitida pela app ou a sua entidade."</string>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index f533bbc..704afb6 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tentar novamente"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Muito bem!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Tudo pronto!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Deslize para cima para acessar a tela inicial"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Você já pode começar a usar seu smartphone"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Configurações de navegação para acessibilidade"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Compartilhar"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Capturar tela"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Essa ação não é permitida pelo app ou pela organização"</string>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 37d2935..ae781fe 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reîncercați"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bravo!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorialul <xliff:g id="CURRENT">%1$d</xliff:g> / <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Distribuiți"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Captură de ecran"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Această acțiune nu este permisă de aplicație sau de organizația dvs."</string>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 8d4c40a..608ebd4 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Повторите попытку"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Поздравляем!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Руководство (шаг <xliff:g id="CURRENT">%1$d</xliff:g> из <xliff:g id="TOTAL">%2$d</xliff:g>)"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Поделиться"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Это действие заблокировано приложением или организацией."</string>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index d526e13..64cf9cc 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"නැවත උත්සාහ කරන්න"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"කදිමයි!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"නිබන්ධනය <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"බෙදා ගන්න"</string>
<string name="action_screenshot" msgid="8171125848358142917">"තිර රුව"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"මෙම ක්රියාව යෙදුම හෝ ඔබේ සංවිධානය මගින් ඉඩ නොදේ"</string>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 24a4ac9..56f0616 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Skúste to znova"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Výborne!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Návod <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Hotovo"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Potiahnutím nahor prejdete na plochu"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Telefón môžete začať používať"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Nastavenia navigácie pre dostupnosť"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Zdieľať"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Snímka obrazovky"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikácia alebo vaša organizácia túto akciu nepovoľuje"</string>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index fdc8a6a..55a0fba 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Poskusite znova"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Odlično!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Vadnica <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Deli"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Posnetek zaslona"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ali vaša organizacija ne dovoljuje tega dejanja"</string>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 36e0afc..73d983b 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Provo përsëri"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bukur!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Udhëzuesi <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Ndaj"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Pamja e ekranit"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ky veprim nuk lejohet nga aplikacioni ose organizata jote"</string>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 8a462f9..900950f 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Пробајте поново"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Свака част!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Водич <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Дели"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Снимак екрана"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Апликација или организација не дозвољавају ову радњу"</string>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index bf69850..ce256db 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Försök igen"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bra!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Självstudie <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Dela"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skärmbild"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisationen tillåter inte den här åtgärden"</string>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index b761cae..92b7839 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Jaribu tena"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Safi!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Mafunzo ya <xliff:g id="CURRENT">%1$d</xliff:g> kati ya <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Shiriki"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Picha ya skrini"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Kitendo hiki hakiruhusiwi na programu au shirika lako"</string>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 089c95d..cd8e3a3 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"மீண்டும் முயல்க"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"அருமை!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"பயிற்சி <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"பகிர்"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ஸ்கிரீன்ஷாட்"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ஆப்ஸோ உங்கள் நிறுவனமோ இந்த செயலை அனுமதிப்பதில்லை"</string>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index c73c83e..5e8230c 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"మళ్లీ ట్రై చేయండి"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"పనితీరు బాగుంది!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ట్యుటోరియల్ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"షేర్ చేయండి"</string>
<string name="action_screenshot" msgid="8171125848358142917">"స్క్రీన్షాట్"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ఈ చర్యను యాప్ గానీ, మీ సంస్థ గానీ అనుమతించవు"</string>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index d706108..ec7c652 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"ลองอีกครั้ง"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"ดีมาก"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"บทแนะนำ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"แชร์"</string>
<string name="action_screenshot" msgid="8171125848358142917">"ภาพหน้าจอ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"แอปหรือองค์กรของคุณไม่อนุญาตการดำเนินการนี้"</string>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 5056481..f973042 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Subukan ulit"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Magaling!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Ibahagi"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Hindi pinapayagan ng app o ng iyong organisasyon ang pagkilos na ito"</string>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index a22247b..dc89f44 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tekrar deneyin"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Güzel!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Eğitici <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Paylaş"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Ekran görüntüsü"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Uygulamanız veya kuruluşunuz bu işleme izin vermiyor"</string>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index c63cec4..926c1fb 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Спробуйте ще"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудово!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Навчальний посібник <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Поділитися"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Знімок екрана"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ця дія заборонена додатком або адміністратором організації"</string>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 5ce95ad..a04e090 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"پھر کوشش کریں"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"عمدہ!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"ٹیوٹوریل <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"اشتراک کریں"</string>
<string name="action_screenshot" msgid="8171125848358142917">"اسکرین شاٹ"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"ایپ یا آپ کی تنظیم کی جانب سے اس کارروائی کی اجازت نہیں ہے"</string>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 7272edd..8ca3898 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Qayta urinish"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Yaxshi!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Darslik: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Hammasi tayyor!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Boshiga qaytish uchun tepaga suring"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Telefoningiz xizmatga tayyor"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Maxsus imkoniyatlar uchun navigatsiya sozlamalari"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Ulashish"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Skrinshot"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Bu amal ilova yoki tashkilotingiz tomonidan taqiqlangan"</string>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index fc3ef3f..3034ce7 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Thử lại"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Tuyệt vời!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Hướng dẫn <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"Chia sẻ"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Chụp ảnh màn hình"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Ứng dụng hoặc tổ chức của bạn không cho phép thực hiện hành động này"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index fe5e553d..e60e2a8 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"重试"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"教程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"分享"</string>
<string name="action_screenshot" msgid="8171125848358142917">"屏幕截图"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"该应用或您所在的单位不允许执行此操作"</string>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 5522a67..b546820 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"再試一次"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"教學課程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"分享"</string>
<string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"應用程式或您的機構不允許此操作"</string>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 20af2b4..8146ec3 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -74,6 +74,14 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"重試"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"教學課程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <!-- no translation found for allset_title (5021126669778966707) -->
+ <skip />
+ <!-- no translation found for allset_hint (459504134589971527) -->
+ <skip />
+ <!-- no translation found for allset_description (6350320429953234580) -->
+ <skip />
+ <!-- no translation found for allset_navigation_settings (417773244979225071) -->
+ <skip />
<string name="action_share" msgid="2648470652637092375">"分享"</string>
<string name="action_screenshot" msgid="8171125848358142917">"擷取螢幕畫面"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"這個應用程式或貴機構不允許執行這個動作"</string>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 2ffaecf..7f61e7d 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -74,6 +74,10 @@
<string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zama futhi"</string>
<string name="gesture_tutorial_nice" msgid="2936275692616928280">"Kuhle!"</string>
<string name="gesture_tutorial_step" msgid="1279786122817620968">"Okokufundisa <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
+ <string name="allset_title" msgid="5021126669778966707">"Konke kusethiwe!"</string>
+ <string name="allset_hint" msgid="459504134589971527">"Swayiphela phezulu ukuze uye ekhaya"</string>
+ <string name="allset_description" msgid="6350320429953234580">"Usulungele ukuqala ukusebenzisa ifoni yakho"</string>
+ <string name="allset_navigation_settings" msgid="417773244979225071"><annotation id="link">"Amasethingi wokufinyelela ukuzulazula"</annotation></string>
<string name="action_share" msgid="2648470652637092375">"Yabelana"</string>
<string name="action_screenshot" msgid="8171125848358142917">"Isithombe-skrini"</string>
<string name="blocked_by_policy" msgid="2071401072261365546">"Lesi senzo asivunyelwanga uhlelo lokusebenza noma inhlangano yakho"</string>
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
new file mode 100644
index 0000000..336fb57
--- /dev/null
+++ b/quickstep/res/values/attrs.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <declare-styleable name="AllSetLinkSpan">
+ <attr name="android:textSize"/>
+ <attr name="android:fontFamily"/>
+ </declare-styleable>
+</resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 3bc8ddc..167c7c3 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -27,4 +27,5 @@
<!-- Taskbar -->
<color name="taskbar_background">#101010</color>
+ <color name="taskbar_icon_selection_ripple">#E0E0E0</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9c0a083..c459472 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -36,7 +36,7 @@
<dimen name="overview_grid_bottom_margin">90dp</dimen>
<dimen name="overview_grid_side_margin">54dp</dimen>
<dimen name="overview_grid_row_spacing">42dp</dimen>
- <dimen name="overview_grid_focus_vertical_margin">130dp</dimen>
+ <dimen name="overview_grid_focus_vertical_margin">90dp</dimen>
<dimen name="split_placeholder_size">110dp</dimen>
<dimen name="recents_page_spacing">16dp</dimen>
@@ -99,6 +99,13 @@
<dimen name="gesture_tutorial_feedback_margin_start_end">24dp</dimen>
<dimen name="gesture_tutorial_button_margin_start_end">18dp</dimen>
+ <!-- All Set page -->
+ <dimen name="allset_page_margin_horizontal">40dp</dimen>
+ <dimen name="allset_title_margin_top">28dp</dimen>
+ <dimen name="allset_title_icon_margin_top">80dp</dimen>
+ <dimen name="allset_hint_margin_bottom">52dp</dimen>
+ <dimen name="allset_subtitle_margin_top">24dp</dimen>
+
<!-- All Apps Education tutorial -->
<dimen name="swipe_edu_padding">8dp</dimen>
<dimen name="swipe_edu_circle_size">64dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index a0f1638..7ada496 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -177,6 +177,15 @@
<!-- Feedback subtext displaying the current step and the total number of steps for the tutorial. [CHAR LIMIT=30] -->
<string name="gesture_tutorial_step">Tutorial <xliff:g id="current">%1$d</xliff:g>/<xliff:g id="total">%2$d</xliff:g></string>
+ <!-- Title of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_title">All set!</string>
+ <!-- Hint string at the bottom of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_hint">Swipe up to go home</string>
+ <!-- Description of "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_description">You\u2019re ready to start using your phone</string>
+ <!-- String linking to navigation settings on "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="allset_navigation_settings"><annotation id="link">Navigation settings for accessibility</annotation></string>
+
<!-- ******* Overview ******* -->
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
<string name="action_share">Share</string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 7c7d20a..0a8ecb8 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -59,7 +59,7 @@
parent="TextAppearance.GestureTutorial">
<item name="android:gravity">start</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:fontFamily">google-sans</item>
+ <item name="android:fontFamily">google-sans-text</item>
<item name="android:letterSpacing">0.03</item>
<item name="android:textSize">18sp</item>
<item name="android:lineHeight">24sp</item>
@@ -99,6 +99,11 @@
<item name="android:textColor">@color/gesture_tutorial_primary_color</item>
</style>
+ <style name="TextAppearance.GestureTutorial.LinkText"
+ parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
+ <item name="android:textSize">14sp</item>
+ </style>
+
<!--
Can be applied to views to color things like ripples and list highlights the workspace text
color.
diff --git a/quickstep/res/xml/indexable_launcher_prefs.xml b/quickstep/res/xml/indexable_launcher_prefs.xml
index c7e864f..b4740e5 100644
--- a/quickstep/res/xml/indexable_launcher_prefs.xml
+++ b/quickstep/res/xml/indexable_launcher_prefs.xml
@@ -26,7 +26,7 @@
android:key="pref_allowRotation"
android:title="@string/allow_rotation_title"
android:summary="@string/allow_rotation_desc"
- android:defaultValue="@bool/allow_rotation"
+ android:defaultValue="false"
android:persistent="true" />
</PreferenceScreen>
diff --git a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
index 70a143e..7c97b93 100644
--- a/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
+++ b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
@@ -36,6 +36,7 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -44,6 +45,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shadows.ShadowDeviceFlag;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -60,6 +62,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowAppWidgetManager;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.util.ReflectionHelpers;
@@ -174,6 +177,41 @@
assertWidgetInfo(recommendedWidgets.get(2).info, mApp1Provider1);
}
+ @Test
+ public void widgetsRecommendationRan_localFilterDisabled_shouldReturnWidgetsInPredicationOrder()
+ throws Exception {
+ ShadowDeviceFlag shadowDeviceFlag = Shadow.extract(
+ FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER);
+ shadowDeviceFlag.setValue(false);
+
+ // WHEN newPredicationTask is executed with 5 predicated widgets.
+ AppTarget widget1 = new AppTarget(new AppTargetId("app1"), "app1", "provider1",
+ mUserHandle);
+ AppTarget widget2 = new AppTarget(new AppTargetId("app1"), "app1", "provider2",
+ mUserHandle);
+ // Not installed app
+ AppTarget widget3 = new AppTarget(new AppTargetId("app2"), "app3", "provider1",
+ mUserHandle);
+ // Not installed widget
+ AppTarget widget4 = new AppTarget(new AppTargetId("app4"), "app4", "provider3",
+ mUserHandle);
+ AppTarget widget5 = new AppTarget(new AppTargetId("app5"), "app5", "provider1",
+ mUserHandle);
+ mModelHelper.executeTaskForTest(
+ newWidgetsPredicationTask(List.of(widget5, widget3, widget2, widget4, widget1)))
+ .forEach(Runnable::run);
+
+ // THEN only 3 widgets are returned because the launcher only filters out non-exist widgets.
+ List<PendingAddWidgetInfo> recommendedWidgets = mCallback.mRecommendedWidgets.items
+ .stream()
+ .map(itemInfo -> (PendingAddWidgetInfo) itemInfo)
+ .collect(Collectors.toList());
+ assertThat(recommendedWidgets).hasSize(3);
+ assertWidgetInfo(recommendedWidgets.get(0).info, mApp5Provider1);
+ assertWidgetInfo(recommendedWidgets.get(1).info, mApp1Provider2);
+ assertWidgetInfo(recommendedWidgets.get(2).info, mApp1Provider1);
+ }
+
private void assertWidgetInfo(
LauncherAppWidgetProviderInfo actual, AppWidgetProviderInfo expected) {
assertThat(actual.provider).isEqualTo(expected.provider);
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 910e473..6966fb6 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -19,9 +19,11 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
+import static com.android.launcher3.LauncherState.NO_OFFSET;
+import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.animation.AnimatorSet;
@@ -30,8 +32,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.IBinder;
import android.view.View;
import androidx.annotation.Nullable;
@@ -61,6 +66,7 @@
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.util.SplitSelectStateController;
@@ -82,6 +88,8 @@
private DepthController mDepthController = new DepthController(this);
private QuickstepTransitionManager mAppTransitionManager;
+ private ServiceConnection mTisBinderConnection;
+ protected TouchInteractionService.TISBinder mTisBinder;
/**
* Reusable command for applying the back button alpha on the background thread.
@@ -103,6 +111,24 @@
super.onCreate(savedInstanceState);
SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
addMultiWindowModeChangedListener(mDepthController);
+ setupTouchInteractionServiceBinder();
+ }
+
+ private void setupTouchInteractionServiceBinder() {
+ Intent intent = new Intent(this, TouchInteractionService.class);
+ mTisBinderConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder binder) {
+ mTisBinder = ((TouchInteractionService.TISBinder) binder);
+ mTisBinder.setTaskbarOverviewProxyDelegate(mTaskbarController);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ mTisBinder = null;
+ }
+ };
+ bindService(intent, mTisBinderConnection, 0);
}
@Override
@@ -113,6 +139,10 @@
if (mTaskbarController != null) {
mTaskbarController.cleanup();
mTaskbarController = null;
+ if (mTisBinder != null) {
+ mTisBinder.setTaskbarOverviewProxyDelegate(null);
+ unbindService(mTisBinderConnection);
+ }
}
super.onDestroy();
@@ -161,6 +191,15 @@
}
@Override
+ protected void onScreenOff() {
+ super.onScreenOff();
+ if (LIVE_TILE.get()) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.finishRecentsAnimation(true /* toRecents */, null);
+ }
+ }
+
+ @Override
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
if (requestCode != -1) {
@@ -240,7 +279,7 @@
public void onDisplayInfoChanged(Context context, DisplayController.Info info,
int flags) {
super.onDisplayInfoChanged(context, info, flags);
- if ((flags & CHANGE_SIZE) != 0) {
+ if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
addTaskbarIfNecessary();
}
}
@@ -248,6 +287,9 @@
private void addTaskbarIfNecessary() {
if (mTaskbarController != null) {
mTaskbarController.cleanup();
+ if (mTisBinder != null) {
+ mTisBinder.setTaskbarOverviewProxyDelegate(null);
+ }
mTaskbarController = null;
}
if (mDeviceProfile.isTaskbarPresent) {
@@ -256,6 +298,9 @@
mTaskbarController = new TaskbarController(this,
taskbarActivityContext.getTaskbarContainerView(), taskbarViewOnHome);
mTaskbarController.init();
+ if (mTisBinder != null) {
+ mTisBinder.setTaskbarOverviewProxyDelegate(mTaskbarController);
+ }
}
}
@@ -343,7 +388,7 @@
@Override
public float[] getNormalOverviewScaleAndOffset() {
return SysUINavigationMode.getMode(this).hasGestures
- ? new float[] {1, 1} : new float[] {1.1f, 0};
+ ? new float[] {1, NO_OFFSET, 1} : new float[] {1.1f, NO_OFFSET, NO_OFFSET};
}
@Override
@@ -460,7 +505,8 @@
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- // Fall through and continue if it's an app or shortcut
+ case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+ // Fall through and continue if it's an app, shortcut, or widget
break;
default:
return;
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index fb67645..1b54211 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -60,6 +60,7 @@
import android.os.Looper;
import android.os.SystemProperties;
import android.util.Pair;
+import android.util.Size;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -490,7 +491,7 @@
List<View> viewsToAnimate = new ArrayList<>();
Workspace workspace = mLauncher.getWorkspace();
- workspace.getVisiblePages().forEach(
+ workspace.forEachVisiblePage(
view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets()));
viewsToAnimate.add(mLauncher.getHotseat());
@@ -780,7 +781,9 @@
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
? 0 : getWindowCornerRadius(mLauncher.getResources());
final FloatingWidgetView floatingView = FloatingWidgetView.getFloatingWidgetView(mLauncher,
- v, widgetBackgroundBounds, windowTargetBounds, finalWindowRadius);
+ v, widgetBackgroundBounds,
+ new Size(windowTargetBounds.width(), windowTargetBounds.height()),
+ finalWindowRadius);
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
? floatingView.getInitialCornerRadius() : 0;
@@ -1257,21 +1260,20 @@
if (launchingFromWidget) {
composeWidgetLaunchAnimator(anim, (LauncherAppWidgetHostView) mV, appTargets,
wallpaperTargets, nonAppTargets);
+ // TODO(b/169042867): jank monitoring instrumentation
} else if (launchingFromRecents) {
composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
launcherClosing);
+ addCujInstrumentation(
+ anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS);
} else if (launchingFromTaskbar) {
// TODO
} else {
composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets,
launcherClosing);
+ addCujInstrumentation(anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON);
}
- addCujInstrumentation(anim,
- launchingFromRecents
- ? InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS
- : InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON);
-
if (launcherClosing) {
anim.addListener(mForceInvisibleListener);
}
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index cc3ccea..6d5975f 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -33,7 +33,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
@@ -80,9 +79,9 @@
setOrientation(LinearLayout.HORIZONTAL);
mFocusHelper = new SimpleFocusIndicatorHelper(this);
- mNumPredictedAppsPerRow = LauncherAppState.getIDP(context).numAllAppsColumns;
mLauncher = Launcher.getLauncher(context);
mLauncher.addOnDeviceProfileChangeListener(this);
+ mNumPredictedAppsPerRow = mLauncher.getDeviceProfile().numShownAllAppsColumns;
updateVisibility();
}
@@ -174,7 +173,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
- mNumPredictedAppsPerRow = dp.inv.numAllAppsColumns;
+ mNumPredictedAppsPerRow = dp.numShownAllAppsColumns;
removeAllViews();
applyPredictionApps();
}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 67ed5fb..5dcf84c 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.hybridhotseat.HotseatEduController.getSettingsIntent;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
@@ -150,7 +151,7 @@
* Shows appropriate hotseat education based on prediction enabled and migration states.
*/
public void showEdu() {
- mLauncher.getStateManager().goToState(NORMAL, true, () -> {
+ mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
if (mPredictedItems.isEmpty()) {
// launcher has empty predictions set
Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
@@ -165,7 +166,7 @@
.collect(Collectors.toList()));
eduController.showEdu();
}
- });
+ }));
}
/**
@@ -255,8 +256,8 @@
}
}
if (animate) {
- animationSet.addListener(AnimationSuccessListener
- .forRunnable(this::removeOutlineDrawings));
+ animationSet.addListener(
+ forSuccessCallback(this::removeOutlineDrawings));
animationSet.start();
} else {
removeOutlineDrawings();
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 8c68872..a9c2a5e 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -18,7 +18,6 @@
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.formatElapsedTime;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
@@ -104,8 +103,8 @@
// TODO: Implement caching and preloading
super.loadItems(ums, pinnedShortcuts);
- WorkspaceItemFactory allAppsFactory =
- new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numAllAppsColumns);
+ WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(
+ mApp, ums, pinnedShortcuts, mIDP.numDatabaseAllAppsColumns);
mAllAppsState.items.setItems(
mAllAppsState.storage.read(mApp.getContext(), allAppsFactory, ums.allUsers::get));
mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
@@ -204,7 +203,7 @@
registerPredictor(mAllAppsState, apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("home")
- .setPredictedTargetCount(mIDP.numAllAppsColumns)
+ .setPredictedTargetCount(mIDP.numDatabaseAllAppsColumns)
.build()));
// TODO: get bundle
@@ -252,11 +251,9 @@
}
@Override
- public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
- if ((changeFlags & CHANGE_FLAG_GRID) != 0) {
- // Reinitialize everything
- Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
- }
+ public void onIdpChanged(InvariantDeviceProfile profile) {
+ // Reinitialize everything
+ Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
}
private void onAppTargetEvent(AppTargetEvent event, int client) {
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index a29ac1a..22a8c9b 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -16,16 +16,17 @@
package com.android.launcher3.model;
import android.app.prediction.AppTarget;
+import android.content.ComponentName;
+import android.text.TextUtils;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.PendingAddWidgetInfo;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,25 +57,43 @@
Map<PackageUserKey, List<WidgetItem>> allWidgets =
dataModel.widgetsModel.getAllWidgetsWithoutShortcuts();
- ArrayList<ItemInfo> recommendedWidgetsInDescendingOrder = new ArrayList<>();
- for (AppTarget app : mTargets) {
- PackageUserKey packageUserKey = new PackageUserKey(app.getPackageName(), app.getUser());
- if (allWidgets.containsKey(packageUserKey)) {
- List<WidgetItem> notAddedWidgets = allWidgets.get(packageUserKey).stream()
- .filter(item ->
- !widgetsInWorkspace.contains(
- new ComponentKey(item.componentName, item.user)))
- .collect(Collectors.toList());
- if (notAddedWidgets.size() > 0) {
- // Even an apps have more than one widgets, we only include one widget.
- recommendedWidgetsInDescendingOrder.add(
- new PendingAddWidgetInfo(notAddedWidgets.get(0).widgetInfo));
+ FixedContainerItems fixedContainerItems = mPredictorState.items;
+ fixedContainerItems.items.clear();
+
+ if (FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER.get()) {
+ for (AppTarget app : mTargets) {
+ PackageUserKey packageUserKey = new PackageUserKey(app.getPackageName(),
+ app.getUser());
+ if (allWidgets.containsKey(packageUserKey)) {
+ List<WidgetItem> notAddedWidgets = allWidgets.get(packageUserKey).stream()
+ .filter(item ->
+ !widgetsInWorkspace.contains(
+ new ComponentKey(item.componentName, item.user)))
+ .collect(Collectors.toList());
+ if (notAddedWidgets.size() > 0) {
+ // Even an apps have more than one widgets, we only include one widget.
+ fixedContainerItems.items.add(
+ new PendingAddWidgetInfo(notAddedWidgets.get(0).widgetInfo));
+ }
+ }
+ }
+ } else {
+ Map<ComponentKey, WidgetItem> widgetItems =
+ allWidgets.values().stream().flatMap(List::stream)
+ .collect(Collectors.toMap(widget -> (ComponentKey) widget,
+ widget -> widget));
+ for (AppTarget app : mTargets) {
+ if (TextUtils.isEmpty(app.getClassName())) {
+ continue;
+ }
+ ComponentKey targetWidget = new ComponentKey(
+ new ComponentName(app.getPackageName(), app.getClassName()), app.getUser());
+ if (widgetItems.containsKey(targetWidget)) {
+ fixedContainerItems.items.add(
+ new PendingAddWidgetInfo(widgetItems.get(targetWidget).widgetInfo));
}
}
}
- FixedContainerItems fixedContainerItems = mPredictorState.items;
- fixedContainerItems.items.clear();
- fixedContainerItems.items.addAll(recommendedWidgetsInDescendingOrder);
bindExtraContainerItems(fixedContainerItems);
// Don't store widgets prediction to disk because it is not used frequently.
diff --git a/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java
new file mode 100644
index 0000000..0d4130d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar;
+
+import android.annotation.DrawableRes;
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.launcher3.R;
+
+/**
+ * Creates Buttons for Taskbar for 3 button nav.
+ * Can add animations and state management for buttons in this class as things progress.
+ */
+public class ButtonProvider {
+
+ private int mMarginLeftRight;
+ private final Context mContext;
+
+ public ButtonProvider(Context context) {
+ mContext = context;
+ }
+
+ public void setMarginLeftRight(int margin) {
+ mMarginLeftRight = margin;
+ }
+
+ public View getBack() {
+ // Back button
+ return getButtonForDrawable(R.drawable.ic_sysbar_back);
+ }
+
+ public View getDown() {
+ // Ime down button
+ return getButtonForDrawable(R.drawable.ic_sysbar_back);
+ }
+
+ public View getHome() {
+ // Home button
+ return getButtonForDrawable(R.drawable.ic_sysbar_home);
+ }
+
+ public View getRecents() {
+ // Recents button
+ return getButtonForDrawable(R.drawable.ic_sysbar_recent);
+ }
+
+ public View getImeSwitcher() {
+ // IME Switcher Button
+ return getButtonForDrawable(R.drawable.ic_ime_switcher);
+ }
+
+ private View getButtonForDrawable(@DrawableRes int drawableId) {
+ ImageView buttonView = new ImageView(mContext);
+ buttonView.setImageResource(drawableId);
+ buttonView.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect);
+ buttonView.setPadding(mMarginLeftRight, 0, mMarginLeftRight, 0);
+ return buttonView;
+ }
+
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java
new file mode 100644
index 0000000..bb3669b
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar;
+
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RelativeLayout;
+
+import com.android.launcher3.views.ActivityContext;
+
+public class ImeBarView extends RelativeLayout {
+
+ private ButtonProvider mButtonProvider;
+ private TaskbarController.TaskbarViewCallbacks mControllerCallbacks;
+ private View mImeView;
+
+ public ImeBarView(Context context) {
+ this(context, null);
+ }
+
+ public ImeBarView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ImeBarView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void construct(ButtonProvider buttonProvider) {
+ mButtonProvider = buttonProvider;
+ }
+
+ public void init(TaskbarController.TaskbarViewCallbacks taskbarCallbacks) {
+ mControllerCallbacks = taskbarCallbacks;
+ ActivityContext context = getActivityContext();
+ RelativeLayout.LayoutParams imeParams = new RelativeLayout.LayoutParams(
+ context.getDeviceProfile().iconSizePx,
+ context.getDeviceProfile().iconSizePx
+ );
+ RelativeLayout.LayoutParams downParams = new RelativeLayout.LayoutParams(imeParams);
+
+ imeParams.addRule(ALIGN_PARENT_END);
+ imeParams.setMarginEnd(context.getDeviceProfile().iconSizePx);
+ downParams.setMarginStart(context.getDeviceProfile().iconSizePx);
+ downParams.addRule(ALIGN_PARENT_START);
+
+ // Down Arrow
+ View downView = mButtonProvider.getDown();
+ downView.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick(
+ BUTTON_BACK));
+ downView.setLayoutParams(downParams);
+ downView.setRotation(-90);
+ addView(downView);
+
+ // IME switcher button
+ mImeView = mButtonProvider.getImeSwitcher();
+ mImeView.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick(
+ BUTTON_IME_SWITCH));
+ mImeView.setLayoutParams(imeParams);
+ addView(mImeView);
+ }
+
+ public void cleanup() {
+ removeAllViews();
+ }
+
+ public void setImeSwitcherVisibility(boolean show) {
+ mImeView.setVisibility(show ? VISIBLE : GONE);
+ }
+
+ private <T extends Context & ActivityContext> T getActivityContext() {
+ return ActivityContext.lookupContext(getContext());
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 5513c16..3af51d5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -16,12 +16,24 @@
package com.android.launcher3.taskbar;
import android.content.ContextWrapper;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
import com.android.launcher3.R;
+import com.android.launcher3.dragndrop.DragController;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.dragndrop.DraggableView;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
@@ -35,6 +47,7 @@
private final DeviceProfile mDeviceProfile;
private final LayoutInflater mLayoutInflater;
private final TaskbarContainerView mTaskbarContainerView;
+ private final MyDragController mDragController;
public TaskbarActivityContext(BaseQuickstepLauncher launcher) {
super(launcher);
@@ -47,6 +60,7 @@
mTaskbarContainerView = (TaskbarContainerView) mLayoutInflater
.inflate(R.layout.taskbar, null, false);
+ mDragController = new MyDragController(this);
}
public TaskbarContainerView getTaskbarContainerView() {
@@ -72,4 +86,31 @@
public Rect getFolderBoundingBox() {
return mTaskbarContainerView.getFolderBoundingBox();
}
+
+ @Override
+ public DragController getDragController() {
+ return mDragController;
+ }
+
+ private static class MyDragController extends DragController<TaskbarActivityContext> {
+ MyDragController(TaskbarActivityContext activity) {
+ super(activity);
+ }
+
+ @Override
+ protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
+ DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
+ ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
+ float dragViewScaleOnDrop, DragOptions options) {
+ return null;
+ }
+
+ @Override
+ protected void exitDrag() { }
+
+ @Override
+ protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
+ return null;
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
index 46e4506..29f6935 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
@@ -44,7 +44,7 @@
private final AnimatedFloat mTaskbarVisibilityAlphaForLauncherState = new AnimatedFloat(
this::updateVisibilityAlpha);
private final AnimatedFloat mTaskbarVisibilityAlphaForIme = new AnimatedFloat(
- this::updateVisibilityAlpha);
+ this::updateVisibilityAlphaForIme);
// Scale.
private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat(
@@ -110,16 +110,22 @@
// We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
// assumption being that Taskbar should always be visible regardless of the current
// LauncherState if Launcher is paused.
+ float alphaDueToIme = mTaskbarVisibilityAlphaForIme.value;
float alphaDueToLauncher = Math.max(mTaskbarBackgroundAlpha.value,
mTaskbarVisibilityAlphaForLauncherState.value);
- float alphaDueToOther = mTaskbarVisibilityAlphaForIme.value;
- float taskbarAlpha = alphaDueToLauncher * alphaDueToOther;
+ float taskbarAlpha = alphaDueToLauncher * alphaDueToIme;
mTaskbarCallbacks.updateTaskbarVisibilityAlpha(taskbarAlpha);
// Make the nav bar invisible if taskbar is visible.
setNavBarButtonAlpha(1f - taskbarAlpha);
}
+ private void updateVisibilityAlphaForIme() {
+ updateVisibilityAlpha();
+ float taskbarAlphaDueToIme = mTaskbarVisibilityAlphaForIme.value;
+ mTaskbarCallbacks.updateImeBarVisibilityAlpha(1f - taskbarAlphaDueToIme);
+ }
+
private void updateScale() {
// We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
// assumption being that Taskbar should always be at scale 1f regardless of the current
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
index c93de00..6084e10 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.taskbar;
+import static android.view.View.GONE;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -28,6 +31,7 @@
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
+import android.inputmethodservice.InputMethodService;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -48,9 +52,12 @@
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.AnimatedFloat;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.TouchInteractionService.TaskbarOverviewProxyDelegate;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -58,13 +65,15 @@
/**
* Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView.
*/
-public class TaskbarController {
+public class TaskbarController implements TaskbarOverviewProxyDelegate {
private static final String WINDOW_TITLE = "Taskbar";
private final TaskbarContainerView mTaskbarContainerView;
private final TaskbarView mTaskbarViewInApp;
private final TaskbarView mTaskbarViewOnHome;
+ private final ImeBarView mImeBarView;
+
private final BaseQuickstepLauncher mLauncher;
private final WindowManager mWindowManager;
// Layout width and height of the Taskbar in the default state.
@@ -73,9 +82,13 @@
private final TaskbarAnimationController mTaskbarAnimationController;
private final TaskbarHotseatController mHotseatController;
private final TaskbarDragController mDragController;
+ private final TaskbarNavButtonController mNavButtonController;
// Initialized in init().
private WindowManager.LayoutParams mWindowLayoutParams;
+ private SysUINavigationMode.Mode mNavMode = SysUINavigationMode.Mode.NO_BUTTON;
+ private final SysUINavigationMode.NavigationModeChangeListener mNavigationModeChangeListener =
+ this::onNavModeChanged;
private @Nullable Animator mAnimator;
private boolean mIsAnimatingToLauncher;
@@ -85,10 +98,14 @@
mLauncher = launcher;
mTaskbarContainerView = taskbarContainerView;
mTaskbarContainerView.construct(createTaskbarContainerViewCallbacks());
+ ButtonProvider buttonProvider = new ButtonProvider(launcher);
mTaskbarViewInApp = mTaskbarContainerView.findViewById(R.id.taskbar_view);
- mTaskbarViewInApp.construct(createTaskbarViewCallbacks());
+ mTaskbarViewInApp.construct(createTaskbarViewCallbacks(), buttonProvider);
mTaskbarViewOnHome = taskbarViewOnHome;
- mTaskbarViewOnHome.construct(createTaskbarViewCallbacks());
+ mTaskbarViewOnHome.construct(createTaskbarViewCallbacks(), buttonProvider);
+ mImeBarView = mTaskbarContainerView.findViewById(R.id.ime_bar_view);
+ mImeBarView.construct(buttonProvider);
+ mNavButtonController = new TaskbarNavButtonController(launcher);
mWindowManager = mLauncher.getWindowManager();
mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getDeviceProfile().taskbarSize);
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
@@ -108,11 +125,21 @@
@Override
public void updateTaskbarVisibilityAlpha(float alpha) {
- mTaskbarContainerView.setAlpha(alpha);
+ mTaskbarViewInApp.setAlpha(alpha);
mTaskbarViewOnHome.setAlpha(alpha);
}
@Override
+ public void updateImeBarVisibilityAlpha(float alpha) {
+ if (mNavMode != SysUINavigationMode.Mode.THREE_BUTTONS) {
+ // TODO Remove sysui IME bar for gesture nav as well
+ return;
+ }
+ mImeBarView.setAlpha(alpha);
+ mImeBarView.setVisibility(alpha == 0 ? GONE : VISIBLE);
+ }
+
+ @Override
public void updateTaskbarScale(float scale) {
mTaskbarViewInApp.setScaleX(scale);
mTaskbarViewInApp.setScaleY(scale);
@@ -136,16 +163,21 @@
return new TaskbarContainerViewCallbacks() {
@Override
public void onViewRemoved() {
- if (mTaskbarContainerView.getChildCount() == 1) {
- // Only TaskbarView remains.
- setTaskbarWindowFullscreen(false);
+ // Ensure no other children present (like Folders, etc)
+ for (int i = 0; i < mTaskbarContainerView.getChildCount(); i++) {
+ View v = mTaskbarContainerView.getChildAt(i);
+ if (!((v instanceof TaskbarView) || (v instanceof ImeBarView))){
+ return;
+ }
}
+ setTaskbarWindowFullscreen(false);
}
@Override
public boolean isTaskbarTouchable() {
return mTaskbarContainerView.getAlpha() > AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD
- && mTaskbarViewInApp.getVisibility() == View.VISIBLE
+ && (mTaskbarViewInApp.getVisibility() == VISIBLE
+ || mImeBarView.getVisibility() == VISIBLE)
&& !mIsAnimatingToLauncher;
}
};
@@ -198,7 +230,7 @@
// space so that the others line up with the home screen hotseat.
boolean isOnHomeScreen = taskbarView == mTaskbarViewOnHome
|| mLauncher.hasBeenResumed() || mIsAnimatingToLauncher;
- return isOnHomeScreen ? View.INVISIBLE : View.GONE;
+ return isOnHomeScreen ? INVISIBLE : GONE;
}
@Override
@@ -212,6 +244,11 @@
alignRealHotseatWithTaskbar();
}
}
+
+ @Override
+ public void onNavigationButtonClick(@TaskbarButton int buttonType) {
+ mNavButtonController.onButtonClick(buttonType);
+ }
};
}
@@ -228,9 +265,12 @@
* Initializes the Taskbar, including adding it to the screen.
*/
public void init() {
- mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons());
- mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons());
+ mNavMode = SysUINavigationMode.INSTANCE.get(mLauncher)
+ .addModeChangeListener(mNavigationModeChangeListener);
+ mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons(), mNavMode);
+ mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons(), mNavMode);
mTaskbarContainerView.init(mTaskbarViewInApp);
+ mImeBarView.init(createTaskbarViewCallbacks());
addToWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
mTaskbarAnimationController.init();
@@ -272,12 +312,15 @@
mTaskbarViewInApp.cleanup();
mTaskbarViewOnHome.cleanup();
mTaskbarContainerView.cleanup();
+ mImeBarView.cleanup();
removeFromWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(null);
mTaskbarAnimationController.cleanup();
mHotseatController.cleanup();
setWhichTaskbarViewIsVisible(null);
+ SysUINavigationMode.INSTANCE.get(mLauncher)
+ .removeModeChangeListener(mNavigationModeChangeListener);
}
private void removeFromWindowManager() {
@@ -315,6 +358,12 @@
mWindowManager.addView(mTaskbarContainerView, mWindowLayoutParams);
}
+ private void onNavModeChanged(SysUINavigationMode.Mode newMode) {
+ mNavMode = newMode;
+ cleanup();
+ init();
+ }
+
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
@@ -387,6 +436,28 @@
*/
public void setIsImeVisible(boolean isImeVisible) {
mTaskbarAnimationController.animateToVisibilityForIme(isImeVisible ? 0 : 1);
+ blockTaskbarTouchesForIme(isImeVisible);
+ }
+
+ /**
+ * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
+ * instantiating at all, which is what's responsible for sending sysui state flags over.
+ *
+ * @param vis IME visibility flag
+ * @param backDisposition Used to determine back button behavior for software keyboard
+ * See BACK_DISPOSITION_* constants in {@link InputMethodService}
+ */
+ public void updateImeStatus(int displayId, int vis, int backDisposition,
+ boolean showImeSwitcher) {
+ if (displayId != mTaskbarContainerView.getContext().getDisplayId() ||
+ mNavMode != SysUINavigationMode.Mode.THREE_BUTTONS) {
+ return;
+ }
+
+ boolean imeVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
+ mTaskbarAnimationController.animateToVisibilityForIme(imeVisible ? 0 : 1);
+ mImeBarView.setImeSwitcherVisibility(showImeSwitcher);
+ blockTaskbarTouchesForIme(imeVisible);
}
/**
@@ -436,12 +507,17 @@
private void setWhichTaskbarViewIsVisible(@Nullable TaskbarView visibleTaskbar) {
mTaskbarViewInApp.setVisibility(visibleTaskbar == mTaskbarViewInApp
- ? View.VISIBLE : View.INVISIBLE);
+ ? VISIBLE : INVISIBLE);
mTaskbarViewOnHome.setVisibility(visibleTaskbar == mTaskbarViewOnHome
- ? View.VISIBLE : View.INVISIBLE);
+ ? VISIBLE : INVISIBLE);
mLauncher.getHotseat().setIconsAlpha(visibleTaskbar != mTaskbarViewInApp ? 1f : 0f);
}
+ private void blockTaskbarTouchesForIme(boolean block) {
+ mTaskbarViewOnHome.setTouchesEnabled(!block);
+ mTaskbarViewInApp.setTouchesEnabled(!block);
+ }
+
/**
* Returns the ratio of the taskbar icon size on home vs in an app.
*/
@@ -485,6 +561,7 @@
protected interface TaskbarAnimationControllerCallbacks {
void updateTaskbarBackgroundAlpha(float alpha);
void updateTaskbarVisibilityAlpha(float alpha);
+ void updateImeBarVisibilityAlpha(float alpha);
void updateTaskbarScale(float scale);
void updateTaskbarTranslationY(float translationY);
}
@@ -507,6 +584,7 @@
/** Returns how much to scale non-icon elements such as spacing and dividers. */
float getNonIconScale(TaskbarView taskbarView);
void onItemPositionsChanged(TaskbarView taskbarView);
+ void onNavigationButtonClick(@TaskbarButton int buttonType);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
new file mode 100644
index 0000000..54e1610
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.taskbar;
+
+import android.content.Context;
+import android.content.Intent;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.annotation.IntDef;
+
+import com.android.quickstep.OverviewCommandHelper;
+import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TouchInteractionService;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Controller for 3 button mode in the taskbar.
+ * Handles all the functionality of the various buttons, making/routing the right calls into
+ * launcher or sysui/system.
+ *
+ * TODO: Create callbacks to hook into UI layer since state will change for more context buttons/
+ * assistant invocation.
+ */
+public class TaskbarNavButtonController {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {
+ BUTTON_BACK,
+ BUTTON_HOME,
+ BUTTON_RECENTS,
+ BUTTON_IME_SWITCH
+ })
+
+ public @interface TaskbarButton {}
+
+ static final int BUTTON_BACK = 1;
+ static final int BUTTON_HOME = BUTTON_BACK << 1;
+ static final int BUTTON_RECENTS = BUTTON_HOME << 1;
+ static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1;
+
+
+ private final Context mContext;
+
+ public TaskbarNavButtonController(Context context) {
+ mContext = context;
+ }
+
+ public void onButtonClick(@TaskbarButton int buttonType) {
+ switch (buttonType) {
+ case BUTTON_BACK:
+ executeBack();
+ break;
+ case BUTTON_HOME:
+ navigateHome();
+ break;
+ case BUTTON_RECENTS:
+ navigateToOverview();;
+ break;
+ case BUTTON_IME_SWITCH:
+ showIMESwitcher();
+ break;
+ }
+ }
+
+ private void navigateHome() {
+ mContext.startActivity(new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ }
+
+ private void navigateToOverview() {
+ TouchInteractionService.getInstance().getOverviewCommandHelper()
+ .addCommand(OverviewCommandHelper.TYPE_SHOW);
+ }
+
+ private void executeBack() {
+ SystemUiProxy.INSTANCE.getNoCreate().onBackPressed();
+ }
+
+ private void showIMESwitcher() {
+ mContext.getSystemService(InputMethodManager.class).showInputMethodPickerFromSystem(
+ true /* showAuxiliarySubtypes */, mContext.getDisplayId());
+ }
+
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 60a7add..9e8013e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -15,6 +15,10 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
+
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
@@ -24,8 +28,10 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.view.DragEvent;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -45,12 +51,17 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.views.ActivityContext;
+import com.android.quickstep.SysUINavigationMode;
/**
* Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps.
*/
public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconParent, Insettable {
+
+ private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
+ SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
+
private final int mIconTouchSize;
private final boolean mIsRtl;
private final int mTouchSlop;
@@ -68,15 +79,22 @@
private LayoutTransition mLayoutTransition;
private int mHotseatStartIndex;
private int mHotseatEndIndex;
+ private LinearLayout mButtonRegion;
// Delegate touches to the closest view if within mIconTouchSize.
private boolean mDelegateTargeted;
private View mDelegateView;
+ // Prevents dispatching touches to children if true
+ private boolean mTouchEnabled = true;
private boolean mIsDraggingItem;
// Only non-null when the corresponding Folder is open.
private @Nullable FolderIcon mLeaveBehindFolderIcon;
+ private int mNavButtonStartIndex;
+ /** Provider of buttons added to taskbar in 3 button nav */
+ private ButtonProvider mButtonProvider;
+
public TaskbarView(@NonNull Context context) {
this(context, null);
}
@@ -100,15 +118,28 @@
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
- protected void construct(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) {
+ protected void construct(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks,
+ ButtonProvider buttonProvider) {
mControllerCallbacks = taskbarViewCallbacks;
mNonIconScale = mControllerCallbacks.getNonIconScale(this);
mItemMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
mItemMarginLeftRight = Math.round(mItemMarginLeftRight * mNonIconScale);
+ mButtonProvider = buttonProvider;
+ mButtonProvider.setMarginLeftRight(mItemMarginLeftRight);
}
- protected void init(int numHotseatIcons) {
- mHotseatStartIndex = 0;
+ protected void init(int numHotseatIcons, SysUINavigationMode.Mode newMode) {
+ // TODO: check if buttons on left
+ if (newMode == SysUINavigationMode.Mode.THREE_BUTTONS && ENABLE_THREE_BUTTON_TASKBAR) {
+ // 3 button
+ mNavButtonStartIndex = 0;
+ createNavButtons();
+ } else {
+ mNavButtonStartIndex = -1;
+ removeNavButtons();
+ }
+
+ mHotseatStartIndex = mNavButtonStartIndex + 1;
mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1;
updateHotseatItems(new ItemInfo[numHotseatIcons]);
@@ -185,11 +216,11 @@
if (hotseatView == null || hotseatView.getSourceLayoutResId() != expectedLayoutResId
|| needsReinflate) {
removeView(hotseatView);
- ActivityContext activityContext = ActivityContext.lookupContext(getContext());
+ ActivityContext activityContext = getActivityContext();
if (isFolder) {
FolderInfo folderInfo = (FolderInfo) hotseatItemInfo;
FolderIcon folderIcon = FolderIcon.inflateFolderAndIcon(expectedLayoutResId,
- ActivityContext.lookupContext(getContext()), this, folderInfo);
+ getActivityContext(), this, folderInfo);
folderIcon.setTextVisible(false);
hotseatView = folderIcon;
} else {
@@ -244,11 +275,23 @@
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (!mTouchEnabled) {
+ return true;
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = delegateTouchIfNecessary(event);
return super.onTouchEvent(event) || handled;
}
+ public void setTouchesEnabled(boolean touchEnabled) {
+ this.mTouchEnabled = touchEnabled;
+ }
+
/**
* User touched the Taskbar background. Determine whether the touch is close enough to a view
* that we should forward the touches to it.
@@ -335,12 +378,57 @@
return findDelegateView(xInOurCoordinates, yInOurCoorindates) != null;
}
+ private void removeNavButtons() {
+ if (mButtonRegion != null) {
+ mButtonRegion.removeAllViews();
+ removeView(mButtonRegion);
+ } // else We've never been in 3 button. Woah Scoob!
+ }
+
+ /**
+ * Add back/home/recents buttons into a single ViewGroup that will be inserted at
+ * {@param navButtonStartIndex}
+ */
+ private void createNavButtons() {
+ ActivityContext context = getActivityContext();
+ if (mButtonRegion == null) {
+ mButtonRegion = new LinearLayout(getContext());
+ } else {
+ mButtonRegion.removeAllViews();
+ }
+ mButtonRegion.setVisibility(VISIBLE);
+
+ LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
+ context.getDeviceProfile().iconSizePx,
+ context.getDeviceProfile().iconSizePx
+ );
+ buttonParams.gravity = Gravity.CENTER;
+
+ View backButton = mButtonProvider.getBack();
+ backButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick(
+ BUTTON_BACK));
+ mButtonRegion.addView(backButton, buttonParams);
+
+ // Home button
+ View homeButton = mButtonProvider.getHome();
+ homeButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick(
+ BUTTON_HOME));
+ mButtonRegion.addView(homeButton, buttonParams);
+
+ View recentsButton = mButtonProvider.getRecents();
+ recentsButton.setOnClickListener(view -> mControllerCallbacks.onNavigationButtonClick(
+ BUTTON_RECENTS));
+ mButtonRegion.addView(recentsButton, buttonParams);
+
+ addView(mButtonRegion, mNavButtonStartIndex);
+ }
+
@Override
public boolean onDragEvent(DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
mIsDraggingItem = true;
- AbstractFloatingView.closeAllOpenViews(ActivityContext.lookupContext(getContext()));
+ AbstractFloatingView.closeAllOpenViews(getActivityContext());
return true;
case DragEvent.ACTION_DRAG_ENDED:
mIsDraggingItem = false;
@@ -407,12 +495,15 @@
}
private View inflate(@LayoutRes int layoutResId) {
- return ActivityContext.lookupContext(getContext()).getLayoutInflater()
- .inflate(layoutResId, this, false);
+ return getActivityContext().getLayoutInflater().inflate(layoutResId, this, false);
}
@Override
public void setInsets(Rect insets) {
// Ignore, we just implement Insettable to draw behind system insets.
}
+
+ private <T extends Context & ActivityContext> T getActivityContext() {
+ return ActivityContext.lookupContext(getContext());
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index 1e03b05..76a5782 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -18,13 +18,23 @@
import android.app.Person;
import android.content.pm.ShortcutInfo;
+import android.view.Display;
import com.android.launcher3.Utilities;
public class ApiWrapper {
+ public static final boolean TASKBAR_DRAWN_IN_PROCESS = true;
+
public static Person[] getPersons(ShortcutInfo si) {
Person[] persons = si.getPersons();
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
}
+
+ /**
+ * Returns true if the display is an internal displays
+ */
+ public static boolean isInternalDisplay(Display display) {
+ return display.getType() == Display.TYPE_INTERNAL;
+ }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 01616d4..e508690 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -24,10 +24,12 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.util.FloatProperty;
@@ -62,7 +64,8 @@
public void setState(@NonNull LauncherState state) {
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mLauncher);
RECENTS_SCALE_PROPERTY.set(mRecentsView, scaleAndOffset[0]);
- ADJACENT_PAGE_OFFSET.set(mRecentsView, scaleAndOffset[1]);
+ ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
+ ADJACENT_PAGE_VERTICAL_OFFSET.set(mRecentsView, scaleAndOffset[2]);
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
@@ -92,15 +95,17 @@
float[] scaleAndOffset = toState.getOverviewScaleAndOffset(mLauncher);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
- setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
+ setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
+ setter.setFloat(mRecentsView, ADJACENT_PAGE_VERTICAL_OFFSET, scaleAndOffset[2],
+ config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
PagedOrientationHandler orientationHandler =
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
FloatProperty taskViewsFloat = orientationHandler.getSplitSelectTaskOffset(
- TASK_PRIMARY_TRANSLATION, TASK_SECONDARY_TRANSLATION, mLauncher.getDeviceProfile());
+ TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
+ mLauncher.getDeviceProfile());
setter.setFloat(mRecentsView, taskViewsFloat,
- toState.getOverviewSecondaryTranslation(mLauncher),
- config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
+ toState.getOverviewSecondaryTranslation(mLauncher), LINEAR);
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
index bb1f6fc..c115bbb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
@@ -68,6 +68,12 @@
mListeners.remove(r);
}
+ @Override
+ public boolean get() {
+ // Override this method in order to let Robolectric ShadowDeviceFlag to stub it.
+ return super.get();
+ }
+
private void registerDeviceConfigChangedListener(Context context) {
DeviceConfig.addOnPropertiesChangedListener(
NAMESPACE_LAUNCHER,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 66e4f4c..a54f963 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -23,6 +23,7 @@
import android.view.View;
import android.widget.RemoteViews;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -49,6 +50,11 @@
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(hostView);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(mLauncher, hostView);
+ activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Object itemInfo = hostView.getTag();
+ if (itemInfo instanceof ItemInfo) {
+ mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
+ }
options = Pair.create(options.first, activityOptions.options);
return RemoteViews.startPendingIntent(hostView, pendingIntent, options);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index f09d9e0..d07cc35 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_WIDGET_APP_START;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_TWO_BUTTON_ORDINAL;
@@ -36,7 +37,6 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
-import android.os.SystemProperties;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -90,9 +90,6 @@
public class QuickstepLauncher extends BaseQuickstepLauncher {
- private static final boolean ENABLE_APP_WIDGET_LAUNCH_ANIMATION =
- SystemProperties.getBoolean("persist.debug.quickstep_app_widget_launch", false);
-
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
/**
* Reusable command for applying the shelf height on the background thread.
@@ -327,7 +324,7 @@
protected LauncherAppWidgetHost createAppWidgetHost() {
LauncherAppWidgetHost appWidgetHost = super.createAppWidgetHost();
- if (ENABLE_APP_WIDGET_LAUNCH_ANIMATION) {
+ if (ENABLE_QUICKSTEP_WIDGET_APP_START.get()) {
appWidgetHost.setInteractionHandler(new QuickstepInteractionHandler(this));
}
return appWidgetHost;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 0652d48..996d36a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -35,7 +35,7 @@
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.states.StateAnimationConfig;
@@ -78,7 +78,7 @@
mRecentsView.updateEmptyMessage();
} else {
builder.addListener(
- AnimationSuccessListener.forRunnable(mRecentsView::resetTaskVisuals));
+ AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals));
}
// Create or dismiss split screen select animations
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index a81bdd5..d822c8c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -84,11 +84,6 @@
}
@Override
- public float[] getOverviewScaleAndOffset(Launcher launcher) {
- return new float[] {0.9f, 1};
- }
-
- @Override
public LauncherState getHistoryForState(LauncherState previousState) {
return previousState == OVERVIEW ? OVERVIEW : NORMAL;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 77c2611..06ffae4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -96,6 +96,6 @@
BaseDraggingActivity activity) {
return new float[] {
((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(),
- NO_OFFSET};
+ NO_OFFSET, NO_OFFSET};
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index 6f084a1..1fc288f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -78,6 +78,6 @@
float scale = Math.min((float) modalTaskSize.height() / taskSize.y,
(float) modalTaskSize.width() / taskSize.x);
- return new float[] {scale, NO_OFFSET};
+ return new float[] {scale, NO_OFFSET, NO_OFFSET};
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 135c478..c9cfad3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Context;
import android.graphics.Rect;
@@ -60,9 +59,8 @@
@Override
public int getTransitionDuration(Context context) {
- // In no-button mode, overview comes in all the way from the left, so give it more time.
- boolean isNoButtonMode = SysUINavigationMode.INSTANCE.get(context).getMode() == NO_BUTTON;
- return isNoButtonMode ? 380 : 250;
+ // In gesture modes, overview comes in all the way from the bottom, so give it more time.
+ return SysUINavigationMode.INSTANCE.get(context).getMode().hasGestures ? 380 : 250;
}
@Override
@@ -80,7 +78,7 @@
@Override
public float[] getOverviewScaleAndOffset(Launcher launcher) {
- return new float[] {NO_SCALE, NO_OFFSET};
+ return new float[] {NO_SCALE, NO_OFFSET, NO_OFFSET};
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index ba61923..adc6b18 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -23,34 +23,34 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import android.animation.ValueAnimator;
-import android.view.View;
import com.android.launcher3.CellLayout;
import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
-import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.quickstep.SysUINavigationMode;
@@ -65,6 +65,12 @@
// Scale recents takes before animating in
private static final float RECENTS_PREPARE_SCALE = 1.33f;
+ // Scale workspace takes before animating in
+ private static final float WORKSPACE_PREPARE_SCALE_GESTURES = 0.97f;
+ private static final float WORKSPACE_PREPARE_SCALE_BUTTONS = 0.92f;
+ // When the overview to home transition reaches this percentage, immediately hide overview and
+ // start animating away the scrim and animating in workspace.
+ private static final float OVERVIEW_TO_HOME_HARD_HAND_OFF = 0.4f;
// Due to use of physics, duration may differ between devices so we need to calculate and
// cache the value.
@@ -77,17 +83,33 @@
@Override
public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
StateAnimationConfig config) {
+ RecentsView overview = mActivity.getOverviewPanel();
if (toState == NORMAL && fromState == OVERVIEW) {
- config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
- config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
- config.setInterpolator(ANIM_ALL_APPS_FADE, ACCEL);
- config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL);
-
- if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
- config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
+ final float workspacePrepareScale;
+ if (SysUINavigationMode.getMode(mActivity).hasGestures
+ && overview.getTaskViewCount() > 0) {
+ workspacePrepareScale = WORKSPACE_PREPARE_SCALE_GESTURES;
+ // Overview is going offscreen, so keep it at its current scale and opacity.
+ config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
+ config.setInterpolator(ANIM_OVERVIEW_FADE, clampToProgress(
+ FINAL_FRAME, 0f, OVERVIEW_TO_HOME_HARD_HAND_OFF));
+ config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(
+ DEACCEL, 0f, OVERVIEW_TO_HOME_HARD_HAND_OFF));
+ config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, AGGRESSIVE_EASE_IN_OUT);
+ config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(
+ DEACCEL, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f));
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, clampToProgress(
+ DEACCEL, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f));
+ config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress(
+ INSTANT, OVERVIEW_TO_HOME_HARD_HAND_OFF, 1f));
} else {
+ workspacePrepareScale = WORKSPACE_PREPARE_SCALE_BUTTONS;
+ config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
+ config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR);
+ config.setInterpolator(ANIM_SCRIM_FADE, LINEAR);
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
+ config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
}
Workspace workspace = mActivity.getWorkspace();
@@ -100,35 +122,33 @@
&& currentChild.getShortcutsAndWidgets().getAlpha() > 0;
}
if (!isWorkspaceVisible) {
- workspace.setScaleX(0.92f);
- workspace.setScaleY(0.92f);
+ workspace.setScaleX(workspacePrepareScale);
+ workspace.setScaleY(workspacePrepareScale);
}
Hotseat hotseat = mActivity.getHotseat();
boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
if (!isHotseatVisible) {
- hotseat.setScaleX(0.92f);
- hotseat.setScaleY(0.92f);
- AllAppsContainerView qsbContainer = mActivity.getAppsView();
- View qsb = qsbContainer.getSearchView();
- boolean qsbVisible = qsb.getVisibility() == VISIBLE && qsb.getAlpha() > 0;
- if (!qsbVisible) {
- qsbContainer.setScaleX(0.92f);
- qsbContainer.setScaleY(0.92f);
- }
+ hotseat.setScaleX(workspacePrepareScale);
+ hotseat.setScaleY(workspacePrepareScale);
}
} else if ((fromState == NORMAL || fromState == HINT_STATE
|| fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
- if (SysUINavigationMode.getMode(mActivity) == NO_BUTTON) {
+ if (SysUINavigationMode.getMode(mActivity).hasGestures) {
config.setInterpolator(ANIM_WORKSPACE_SCALE,
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
- config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
+
+ // Scrolling in tasks, so show straight away
+ if (overview.getTaskViewCount() > 0) {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, INSTANT);
+ } else {
+ config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
+ }
} else {
config.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
// Scale up the recents, if it is not coming from the side
- RecentsView overview = mActivity.getOverviewPanel();
if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
RECENTS_SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
}
@@ -137,6 +157,10 @@
config.setInterpolator(ANIM_ALL_APPS_FADE, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
config.setInterpolator(ANIM_DEPTH, OVERSHOOT_1_2);
+ config.setInterpolator(ANIM_SCRIM_FADE, t -> {
+ // Animate at the same rate until reaching progress 1, and skip the overshoot.
+ return Math.min(1, OVERSHOOT_1_2.getInterpolation(t));
+ });
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_1_2);
} else if (fromState == HINT_STATE && toState == NORMAL) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index b8caf81..19d1b32 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
@@ -38,7 +39,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
@@ -199,7 +200,7 @@
.animateWithVelocity(velocity);
} else {
mLauncher.getStateManager().goToState(mEndState, true,
- () -> onSwipeInteractionCompleted(mEndState));
+ forEndCallback(() -> onSwipeInteractionCompleted(mEndState)));
}
if (mStartState != mEndState) {
logHomeGesture();
@@ -214,7 +215,7 @@
// Quickly return to the state we came from (we didn't move far).
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(progress, 0);
- anim.addListener(AnimationSuccessListener.forRunnable(
+ anim.addListener(AnimatorListeners.forSuccessCallback(
() -> onSwipeInteractionCompleted(mStartState)));
anim.setDuration(80).start();
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 2d95ce2..eb62110 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -18,20 +18,12 @@
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
-import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
-import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_HEADER_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@@ -45,7 +37,6 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
@@ -182,13 +173,13 @@
}
mNormalToHintOverviewScrimAnimator = null;
mCurrentAnimation.getTarget().addListener(newCancelListener(() ->
- mLauncher.getStateManager().goToState(OVERVIEW, true, () -> {
+ mLauncher.getStateManager().goToState(OVERVIEW, true, forSuccessCallback(() -> {
mOverviewResistYAnim = AnimatorControllerWithResistance
.createRecentsResistanceFromOverviewAnim(mLauncher, null)
.createPlaybackController();
mReachedOverview = true;
maybeSwipeInteractionToOverviewComplete();
- })));
+ }))));
mCurrentAnimation.getTarget().removeListener(mClearStateOnCancelListener);
mCurrentAnimation.dispatchOnCancel();
@@ -269,39 +260,4 @@
private float dpiFromPx(float pixels) {
return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics().densityDpi);
}
-
- @Override
- protected StateAnimationConfig getConfigForStates(
- LauncherState fromState, LauncherState toState) {
- if (fromState == NORMAL && toState == ALL_APPS) {
- StateAnimationConfig builder = new StateAnimationConfig();
- builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
- ACCEL,
- 0,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
- ACCEL,
- ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
- ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
-
- // Get workspace out of the way quickly, to prepare for potential pause.
- builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL_3);
- builder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, DEACCEL_3);
- builder.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_3);
- return builder;
- } else if (fromState == ALL_APPS && toState == NORMAL) {
- StateAnimationConfig builder = new StateAnimationConfig();
-
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(
- DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
- builder.setInterpolator(ANIM_ALL_APPS_HEADER_FADE, Interpolators.clampToProgress(
- DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1));
- return builder;
- }
- return super.getConfigForStates(fromState, toState);
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 12de4a6..62687c5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -36,11 +37,14 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
@@ -207,7 +211,7 @@
/** Create state animation to control non-overview components. */
private void updateNonOverviewAnim(LauncherState toState, StateAnimationConfig config) {
config.duration = (long) (Math.max(mXRange, mYRange) * 2);
- config.animFlags |= SKIP_OVERVIEW;
+ config.animFlags |= SKIP_OVERVIEW | SKIP_SCRIM;
mNonOverviewAnim = mLauncher.getStateManager()
.createAnimationToNewWorkspace(toState, config);
mNonOverviewAnim.getTarget().addListener(mClearStateOnCancelListener);
@@ -219,7 +223,8 @@
// Set RecentView's initial properties.
RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
- ADJACENT_PAGE_OFFSET.set(mRecentsView, 1f);
+ ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
+ ADJACENT_PAGE_VERTICAL_OFFSET.set(mRecentsView, 0f);
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
mLauncher.getActionsView().getVisibilityAlpha().setValue(
@@ -229,10 +234,14 @@
// As we drag right, animate the following properties:
// - RecentsView translationX
// - OverviewScrim
+ // - RecentsView fade (if it's empty)
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
- xAnim.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1], LINEAR);
+ xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR);
xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
toState.getWorkspaceScrimColor(mLauncher), LINEAR);
+ if (mRecentsView.getTaskViewCount() == 0) {
+ xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
+ }
mXOverviewAnim = xAnim.createPlaybackController();
mXOverviewAnim.dispatchOnStart();
@@ -410,7 +419,7 @@
targetState.ordinal > mStartState.ordinal
? LAUNCHER_UNKNOWN_SWIPEUP
: LAUNCHER_UNKNOWN_SWIPEDOWN));
- mLauncher.getStateManager().goToState(targetState, false, this::clearState);
+ mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState));
}
private void cancelAnimations() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index b8f9452..3c83d25 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -24,6 +24,7 @@
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import android.view.MotionEvent;
@@ -56,13 +57,17 @@
/**
* Minimum clamping progress for fading in all apps content
*/
- protected static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.4f;
-
+ protected static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
/**
- * The progress at which recents will begin fading out when swiping up from overview.
+ * Minimum clamping progress for fading in all apps scrim
*/
- private static final float RECENTS_FADE_THRESHOLD = 0.88f;
+ protected static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = .1f;
+
+ /**
+ * Maximum clamping progress for opaque all apps scrim
+ */
+ protected static final float ALL_APPS_SCRIM_OPAQUE_THRESHOLD = .5f;
private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
@@ -122,14 +127,22 @@
private StateAnimationConfig getNormalToAllAppsAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
- 0, ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
+ ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
+ ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
+ ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
return builder;
}
private StateAnimationConfig getAllAppsToNormalAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD, 1));
+ 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
+ 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
+ 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
+ 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
return builder;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 3953e42..5891d5f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -30,6 +30,9 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
@@ -105,6 +108,14 @@
StateAnimationConfig config = new StateAnimationConfig();
setupInterpolators(config);
config.duration = (long) (getShiftRange() * 2);
+
+ // Set RecentView's initial properties for coming in from the side.
+ RECENTS_SCALE_PROPERTY.set(mOverviewPanel,
+ QUICK_SWITCH.getOverviewScaleAndOffset(mLauncher)[0] * 0.85f);
+ ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mOverviewPanel, 1f);
+ ADJACENT_PAGE_VERTICAL_OFFSET.set(mOverviewPanel, 0f);
+ mOverviewPanel.setContentAlpha(1);
+
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(mToState, config);
mCurrentAnimation.getTarget().addListener(mClearStateOnCancelListener);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index c2e5cda..70b3870 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -167,6 +167,7 @@
mAllowGoingDown = true;
directionsToDetectScroll = DIRECTION_BOTH;
} else {
+ mAllowGoingDown = false;
directionsToDetectScroll = upDirection;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
index b0d0b15..e2747df 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
@@ -78,18 +78,9 @@
return true;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TWO_BUTTON_NORMAL_NOT_OVERVIEW,
- "Didn't intercept touch due to top view: "
- + AbstractFloatingView.getTopOpenView(mLauncher));
- }
return false;
}
if ((ev.getEdgeFlags() & EDGE_NAV_BAR) == 0) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TWO_BUTTON_NORMAL_NOT_OVERVIEW,
- "Didn't intercept touch because event wasn't from nav bar");
- }
return false;
}
if (!mIsTransposed && mLauncher.isInState(OVERVIEW)) {
@@ -101,10 +92,6 @@
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
boolean intercept = super.onControllerInterceptTouchEvent(ev);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TWO_BUTTON_NORMAL_NOT_OVERVIEW,
- "2 button touch controller intercept touch? " + intercept);
- }
return intercept;
}
@@ -123,10 +110,6 @@
@Override
protected void onReinitToState(LauncherState newToState) {
super.onReinitToState(newToState);
-
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TWO_BUTTON_NORMAL_NOT_OVERVIEW, "onReinitToState: " + newToState);
- }
}
@Override
@@ -175,9 +158,6 @@
@Override
protected void onSwipeInteractionCompleted(LauncherState targetState) {
super.onSwipeInteractionCompleted(targetState);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TWO_BUTTON_NORMAL_NOT_OVERVIEW, "Reached state: " + targetState);
- }
if (!mIsTransposed) {
mContinuousTouchCount++;
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index ecaac94..d04bfe9 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -47,7 +47,6 @@
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_END;
import static com.android.quickstep.util.SwipePipToHomeAnimator.FRACTION_START;
-import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -55,7 +54,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -65,7 +63,6 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
-import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.view.MotionEvent;
@@ -138,7 +135,6 @@
protected final BaseActivityInterface<S, T> mActivityInterface;
protected final InputConsumerProxy mInputConsumerProxy;
protected final ActivityInitListener mActivityInitListener;
- private final Handler mHandler = new Handler();
// Callbacks to be made once the recents animation starts
private final ArrayList<Runnable> mRecentsAnimationStartCallbacks = new ArrayList<>();
private final OnScrollChangedListener mOnRecentsScrollListener = this::onRecentsViewScroll;
@@ -150,9 +146,6 @@
protected Runnable mGestureEndCallback;
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
- // One time flag set when onConsumerAboutToBeSwitched() is called, indicating that certain
- // shared animations should not be canceled when this handler is invalidated
- private boolean mConsumerIsSwitching;
private boolean mRecentsViewScrollLinked = false;
private static int getFlagForIndex(int index, String name) {
@@ -340,6 +333,10 @@
}
protected boolean onActivityInit(Boolean alreadyOnHome) {
+ if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
+ return false;
+ }
+
T createdActivity = mActivityInterface.getCreatedActivity();
if (createdActivity != null) {
initTransitionEndpoints(createdActivity.getDeviceProfile());
@@ -464,8 +461,6 @@
mDeviceState.getRotationTouchHelper()
.onEndTargetCalculated(mGestureState.getEndTarget(),
mActivityInterface);
-
- mRecentsView.onGestureEndTargetCalculated(mGestureState.getEndTarget());
});
notifyGestureStartedAsync();
@@ -571,6 +566,8 @@
}
});
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
+ mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
+ reapplyWindowTransformAnim::cancel);
} else {
applyWindowTransform();
}
@@ -1005,14 +1002,7 @@
animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity);
}
- private int getLogGestureTaskIndex(@Nullable TaskView targetTask) {
- return mRecentsView == null || targetTask == null
- ? LOG_NO_OP_PAGE_INDEX
- : mRecentsView.indexOfChild(targetTask);
- }
-
- private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask,
- int pageIndex) {
+ private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
StatsLogManager.EventEnum event;
switch (endTarget) {
case HOME:
@@ -1041,6 +1031,9 @@
// We probably never received an animation controller, skip logging.
return;
}
+ int pageIndex = endTarget == LAST_TASK
+ ? LOG_NO_OP_PAGE_INDEX
+ : mRecentsView.getNextPage();
// TODO: set correct container using the pageIndex
logger.log(event);
}
@@ -1133,6 +1126,10 @@
}
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
mLauncherTransitionController = null;
+
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget());
+ }
} else {
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator windowAnim = mCurrentShift.animateToValue(start, end);
@@ -1171,9 +1168,9 @@
}
});
animatorSet.play(windowAnim);
- S state = mActivityInterface.stateFromGestureEndTarget(mGestureState.getEndTarget());
- if (mRecentsView != null && state.displayOverviewTasksAsGrid(mDp)) {
- animatorSet.play(ObjectAnimator.ofFloat(mRecentsView, RECENTS_GRID_PROGRESS, 1));
+ if (mRecentsView != null) {
+ mRecentsView.onPrepareGestureEndAnimation(
+ animatorSet, mGestureState.getEndTarget());
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
@@ -1205,6 +1202,7 @@
TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
startBounds,
destinationBounds,
+ mRecentsView.getPipCornerRadius(),
mRecentsView);
// We would assume home and app window always in the same rotation While homeRotation
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
@@ -1287,18 +1285,18 @@
}
public void onConsumerAboutToBeSwitched() {
- mConsumerIsSwitching = true;
if (mActivity != null) {
// In the off chance that the gesture ends before Launcher is started, we should clear
// the callback here so that it doesn't update with the wrong state
mActivity.clearRunOnceOnStartCallback();
+ resetLauncherListeners();
}
if (mGestureState.getEndTarget() != null && !mGestureState.isRunningAnimationToLauncher()) {
cancelCurrentAnimation();
} else {
mStateCallback.setStateOnUiThread(STATE_FINISH_WITH_NO_END);
+ reset();
}
- reset();
}
public boolean isCanceled() {
@@ -1309,14 +1307,13 @@
private void resumeLastTask() {
mRecentsAnimationController.finish(false /* toRecents */, null);
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
- doLogGesture(LAST_TASK, null, getLogGestureTaskIndex(null));
+ doLogGesture(LAST_TASK, null);
reset();
}
@UiThread
private void startNewTask() {
TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
- int taskPageIndex = getLogGestureTaskIndex(taskToLaunch);
startNewTask(success -> {
if (!success) {
reset();
@@ -1325,7 +1322,7 @@
endLauncherTransitionController();
updateSysUiFlags(1 /* windowProgress == overview */);
}
- doLogGesture(NEW_TASK, taskToLaunch, taskPageIndex);
+ doLogGesture(NEW_TASK, taskToLaunch);
});
}
@@ -1359,38 +1356,28 @@
}
private void invalidateHandler() {
- if (!mConsumerIsSwitching) {
- if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
- || mGestureState.getEndTarget() != RECENTS) {
- mInputConsumerProxy.destroy();
- mTaskAnimationManager.setLiveTileCleanUpHandler(null);
- }
- endRunningWindowAnim(false /* cancel */);
+ if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode()
+ || mGestureState.getEndTarget() != RECENTS) {
+ mInputConsumerProxy.destroy();
+ mTaskAnimationManager.setLiveTileCleanUpHandler(null);
+ }
+ mInputConsumerProxy.unregisterCallback();
+ endRunningWindowAnim(false /* cancel */);
- if (mGestureEndCallback != null) {
- mGestureEndCallback.run();
- }
+ if (mGestureEndCallback != null) {
+ mGestureEndCallback.run();
}
- mInputConsumerProxy.unregisterCallback();
mActivityInitListener.unregister();
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
mTaskSnapshot = null;
- mHandler.post(() -> {
- // Defer clearing the activity since invalidation can happen over multiple callbacks
- // ie. invalidateHandlerWithLauncher()
- mActivity = null;
- mRecentsView = null;
- });
}
private void invalidateHandlerWithLauncher() {
- if (!mConsumerIsSwitching) {
- endLauncherTransitionController();
- mRecentsView.onGestureAnimationEnd();
- }
+ endLauncherTransitionController();
mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
+ mRecentsView.onGestureAnimationEnd();
resetLauncherListeners();
}
@@ -1509,8 +1496,7 @@
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
- TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView();
- doLogGesture(HOME, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
+ doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
}
/**
@@ -1541,8 +1527,7 @@
}
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
- TaskView taskToLaunch = mRecentsView.getCurrentPageTaskView();
- doLogGesture(RECENTS, taskToLaunch, getLogGestureTaskIndex(taskToLaunch));
+ doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView());
reset();
}
@@ -1701,7 +1686,7 @@
// No need to apply any transform if there is ongoing swipe-pip-to-home animator since
// that animator handles the leash solely.
if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
- if (mRecentsViewScrollLinked) {
+ if (mRecentsViewScrollLinked && mRecentsView != null) {
mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
}
mTaskViewSimulator.apply(mTransformParams);
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 7aa81d4..b60b1be 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -23,8 +23,8 @@
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.SysUINavigationMode.getMode;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
-import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_Y_ANIM;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
@@ -469,17 +469,17 @@
float fromTranslation = attached ? 1 : 0;
float toTranslation = attached ? 0 : 1;
mActivity.getStateManager()
- .cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_X_ANIM);
+ .cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_Y_ANIM);
if (!recentsView.isShown() && animate) {
- ADJACENT_PAGE_OFFSET.set(recentsView, fromTranslation);
+ ADJACENT_PAGE_VERTICAL_OFFSET.set(recentsView, fromTranslation);
} else {
- fromTranslation = ADJACENT_PAGE_OFFSET.get(recentsView);
+ fromTranslation = ADJACENT_PAGE_VERTICAL_OFFSET.get(recentsView);
}
if (!animate) {
- ADJACENT_PAGE_OFFSET.set(recentsView, toTranslation);
+ ADJACENT_PAGE_VERTICAL_OFFSET.set(recentsView, toTranslation);
} else {
mActivity.getStateManager().createStateElementAnimation(
- INDEX_RECENTS_TRANSLATE_X_ANIM,
+ INDEX_RECENTS_TRANSLATE_Y_ANIM,
fromTranslation, toTranslation).start();
}
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 9fa65d9..3c81d1b 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -163,7 +163,9 @@
@Override
public boolean isInLiveTileMode() {
- return false;
+ RecentsActivity activity = getCreatedActivity();
+ return activity != null && activity.getStateManager().getState() == DEFAULT &&
+ activity.isStarted();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index dffee7f..c43d3c9 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -192,7 +193,8 @@
closeOverlay();
launcher.getStateManager().goToState(OVERVIEW,
- launcher.getStateManager().shouldAnimateStateChange(), onCompleteCallback);
+ launcher.getStateManager().shouldAnimateStateChange(),
+ onCompleteCallback == null ? null : forEndCallback(onCompleteCallback));
return true;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 2ea34d7..46cd8a2 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -30,9 +30,11 @@
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.os.IBinder;
import android.os.UserHandle;
+import android.util.Size;
import android.view.View;
import androidx.annotation.NonNull;
@@ -50,9 +52,11 @@
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.FloatingIconView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
+import com.android.quickstep.views.FloatingWidgetView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.plugins.ResourceProvider;
@@ -77,155 +81,207 @@
@Override
protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
long duration) {
- HomeAnimationFactory homeAnimFactory;
- if (mActivity != null) {
- final View workspaceView = findWorkspaceView(launchCookies,
- mRecentsView.getRunningTaskView());
- boolean canUseWorkspaceView =
- workspaceView != null && workspaceView.isAttachedToWindow();
-
- mActivity.getRootView().setForceHideBackArrow(true);
- mActivity.setHintUserWillBeActive();
-
- if (canUseWorkspaceView) {
- final ResourceProvider rp = DynamicResource.provider(mActivity);
- final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
- float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s));
- final float launcherAlphaMax =
- rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress);
-
- RectF iconLocation = new RectF();
- FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
- true /* hideOriginal */, iconLocation, false /* isOpening */);
-
- // We want the window alpha to be 0 once this threshold is met, so that the
- // FolderIconView can be seen morphing into the icon shape.
- float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
- homeAnimFactory = new LauncherHomeAnimationFactory() {
-
- // There is a delay in loading the icon, so we need to keep the window
- // opaque until it is ready.
- private boolean mIsFloatingIconReady = false;
-
- private @Nullable ValueAnimator mBounceBackAnimator;
-
- @Override
- public RectF getWindowTargetRect() {
- if (PROTOTYPE_APP_CLOSE.get()) {
- // We want the target rect to be at this offset position, so that all
- // launcher content can spring back upwards.
- floatingIconView.setPositionOffsetY(transY);
- }
- return iconLocation;
- }
-
- @Override
- public void setAnimation(RectFSpringAnim anim) {
- anim.addAnimatorListener(floatingIconView);
- floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
- floatingIconView.setFastFinishRunnable(anim::end);
- if (PROTOTYPE_APP_CLOSE.get()) {
- mBounceBackAnimator = bounceBackToRestingPosition();
- // Use a spring to put drag layer translation back to 0.
- anim.addAnimatorListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- floatingIconView.setPositionOffsetY(0);
- mBounceBackAnimator.start();
- }
- });
-
- Workspace workspace = mActivity.getWorkspace();
- workspace.setPivotToScaleWithSelf(mActivity.getHotseat());
- }
- }
-
- private ValueAnimator bounceBackToRestingPosition() {
- DragLayer dl = mActivity.getDragLayer();
- Workspace workspace = mActivity.getWorkspace();
- Hotseat hotseat = mActivity.getHotseat();
-
- final float startValue = transY;
- final float endValue = 0;
- // Ensures the velocity is always aligned with the direction.
- float pixelPerSecond = Math.abs(dpPerSecond)
- * Math.signum(endValue - transY);
-
- ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
- .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
- .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
- .setMinimumVisibleChange(1f)
- .setStartValue(startValue)
- .setEndValue(endValue)
- .setStartVelocity(pixelPerSecond)
- .build(dl, VIEW_TRANSLATE_Y);
- springTransY.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- dl.setTranslationY(0f);
- dl.setAlpha(1f);
- SCALE_PROPERTY.set(workspace, 1f);
- SCALE_PROPERTY.set(hotseat, 1f);
- }
- });
- return springTransY;
- }
-
- @Override
- public boolean keepWindowOpaque() {
- if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
- mIsFloatingIconReady = true;
- return false;
- }
- return true;
- }
-
- @Override
- public void update(@Nullable AppCloseConfig config, RectF currentRect,
- float progress, float radius) {
- int fgAlpha = 255;
- if (config != null && PROTOTYPE_APP_CLOSE.get()) {
- DragLayer dl = mActivity.getDragLayer();
- float translationY = config.getWorkspaceTransY();
- dl.setTranslationY(translationY);
-
- float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR);
- dl.setAlpha(Math.min(alpha, 1f));
-
- float scale = Math.min(1f, config.getWorkspaceScale());
- SCALE_PROPERTY.set(mActivity.getWorkspace(), scale);
- SCALE_PROPERTY.set(mActivity.getHotseat(), scale);
- SCALE_PROPERTY.set(mActivity.getAppsView(), scale);
-
- progress = config.getInterpolatedProgress();
- fgAlpha = config.getFgAlpha();
- }
- floatingIconView.update(1f, fgAlpha, currentRect, progress,
- windowAlphaThreshold, radius, false);
- }
-
- @Override
- public void onCancel() {
- floatingIconView.fastFinish();
- if (mBounceBackAnimator != null) {
- mBounceBackAnimator.cancel();
- }
- }
- };
- } else {
- homeAnimFactory = new LauncherHomeAnimationFactory();
- }
- } else {
- homeAnimFactory = new HomeAnimationFactory() {
+ if (mActivity == null) {
+ mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
+ isPresent -> mRecentsView.startHome());
+ return new HomeAnimationFactory() {
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
return AnimatorPlaybackController.wrap(new AnimatorSet(), duration);
}
};
- mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
- isPresent -> mRecentsView.startHome());
}
- return homeAnimFactory;
+
+ final View workspaceView = findWorkspaceView(launchCookies,
+ mRecentsView.getRunningTaskView());
+ boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
+
+ mActivity.getRootView().setForceHideBackArrow(true);
+ mActivity.setHintUserWillBeActive();
+
+ if (!canUseWorkspaceView) {
+ return new LauncherHomeAnimationFactory();
+ }
+ if (workspaceView instanceof LauncherAppWidgetHostView) {
+ return createWidgetHomeAnimationFactory((LauncherAppWidgetHostView) workspaceView);
+ }
+ return createIconHomeAnimationFactory(workspaceView);
+ }
+
+ private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
+ final ResourceProvider rp = DynamicResource.provider(mActivity);
+ final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+ float dpPerSecond = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp_per_s));
+ final float launcherAlphaMax =
+ rp.getFloat(R.dimen.swipe_up_launcher_alpha_max_progress);
+
+ RectF iconLocation = new RectF();
+ FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
+ true /* hideOriginal */, iconLocation, false /* isOpening */);
+
+ // We want the window alpha to be 0 once this threshold is met, so that the
+ // FolderIconView can be seen morphing into the icon shape.
+ float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
+ return new LauncherHomeAnimationFactory() {
+
+ // There is a delay in loading the icon, so we need to keep the window
+ // opaque until it is ready.
+ private boolean mIsFloatingIconReady = false;
+
+ private @Nullable ValueAnimator mBounceBackAnimator;
+
+ @Override
+ public RectF getWindowTargetRect() {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ // We want the target rect to be at this offset position, so that all
+ // launcher content can spring back upwards.
+ floatingIconView.setPositionOffsetY(transY);
+ }
+ return iconLocation;
+ }
+
+ @Override
+ public void setAnimation(RectFSpringAnim anim) {
+ anim.addAnimatorListener(floatingIconView);
+ floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ floatingIconView.setFastFinishRunnable(anim::end);
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ mBounceBackAnimator = bounceBackToRestingPosition();
+ // Use a spring to put drag layer translation back to 0.
+ anim.addAnimatorListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ floatingIconView.setPositionOffsetY(0);
+ mBounceBackAnimator.start();
+ }
+ });
+
+ Workspace workspace = mActivity.getWorkspace();
+ workspace.setPivotToScaleWithSelf(mActivity.getHotseat());
+ }
+ }
+
+ private ValueAnimator bounceBackToRestingPosition() {
+ DragLayer dl = mActivity.getDragLayer();
+ Workspace workspace = mActivity.getWorkspace();
+ Hotseat hotseat = mActivity.getHotseat();
+
+ final float startValue = transY;
+ final float endValue = 0;
+ // Ensures the velocity is always aligned with the direction.
+ float pixelPerSecond = Math.abs(dpPerSecond) * Math.signum(endValue - transY);
+
+ ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
+ .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
+ .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
+ .setMinimumVisibleChange(1f)
+ .setStartValue(startValue)
+ .setEndValue(endValue)
+ .setStartVelocity(pixelPerSecond)
+ .build(dl, VIEW_TRANSLATE_Y);
+ springTransY.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ dl.setTranslationY(0f);
+ dl.setAlpha(1f);
+ SCALE_PROPERTY.set(workspace, 1f);
+ SCALE_PROPERTY.set(hotseat, 1f);
+ }
+ });
+ return springTransY;
+ }
+
+ @Override
+ public boolean keepWindowOpaque() {
+ if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
+ mIsFloatingIconReady = true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ int fgAlpha = 255;
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ DragLayer dl = mActivity.getDragLayer();
+ float translationY = config.getWorkspaceTransY();
+ dl.setTranslationY(translationY);
+
+ float alpha = mapToRange(progress, 0, launcherAlphaMax, 0, 1f, LINEAR);
+ dl.setAlpha(Math.min(alpha, 1f));
+
+ float scale = Math.min(1f, config.getWorkspaceScale());
+ SCALE_PROPERTY.set(mActivity.getWorkspace(), scale);
+ SCALE_PROPERTY.set(mActivity.getHotseat(), scale);
+ SCALE_PROPERTY.set(mActivity.getAppsView(), scale);
+
+ progress = config.getInterpolatedProgress();
+ fgAlpha = config.getFgAlpha();
+ }
+ floatingIconView.update(1f, fgAlpha, currentRect, progress,
+ windowAlphaThreshold, radius, false);
+ }
+
+ @Override
+ public void onCancel() {
+ floatingIconView.fastFinish();
+ if (mBounceBackAnimator != null) {
+ mBounceBackAnimator.cancel();
+ }
+ }
+ };
+ }
+
+ private HomeAnimationFactory createWidgetHomeAnimationFactory(
+ LauncherAppWidgetHostView hostView) {
+
+ RectF backgroundLocation = new RectF();
+ Rect crop = new Rect();
+ mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
+ Size windowSize = new Size(crop.width(), crop.height());
+ FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
+ hostView, backgroundLocation, windowSize,
+ mTaskViewSimulator.getCurrentCornerRadius());
+
+ return new LauncherHomeAnimationFactory() {
+
+ @Override
+ public RectF getWindowTargetRect() {
+ return backgroundLocation;
+ }
+
+ @Override
+ public float getEndRadius(RectF cropRectF) {
+ return floatingWidgetView.getInitialCornerRadius();
+ }
+
+ @Override
+ public void setAnimation(RectFSpringAnim anim) {
+ anim.addAnimatorListener(floatingWidgetView);
+ floatingWidgetView.setOnTargetChangeListener(anim::onTargetPositionChanged);
+ floatingWidgetView.setFastFinishRunnable(anim::end);
+ }
+
+ @Override
+ public boolean keepWindowOpaque() {
+ return false;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ floatingWidgetView.update(currentRect, 1 /* floatingWidgetAlpha */,
+ config != null ? config.getFgAlpha() : 1f /* foregroundAlpha */,
+ 0 /* fallbackBackgroundAlpha */, 1 - progress);
+ }
+
+ @Override
+ public void onCancel() {
+ floatingWidgetView.fastFinish();
+ }
+ };
}
/**
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index c47300c..35a851a 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -35,7 +35,6 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController.Info;
import java.io.PrintWriter;
@@ -92,7 +91,7 @@
};
private static final String TAG = "OrientationTouchTransformer";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private static final int QUICKSTEP_ROTATION_UNINITIALIZED = -1;
@@ -161,11 +160,9 @@
resetSwipeRegions(info);
}
- void setNavigationMode(SysUINavigationMode.Mode newMode, Info info,
- Resources newRes) {
+ void setNavigationMode(SysUINavigationMode.Mode newMode, Info info, Resources newRes) {
if (DEBUG) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "setNavigationMode new: " + newMode
- + " oldMode: " + mMode + " " + this);
+ Log.d(TAG, "setNavigationMode new: " + newMode + " oldMode: " + mMode + " " + this);
}
if (mMode == newMode) {
return;
@@ -191,7 +188,7 @@
* @see #enableMultipleRegions(boolean, Info)
*/
void createOrAddTouchRegion(Info info) {
- mCurrentDisplay = new CurrentDisplay(info.realSize, info.rotation);
+ mCurrentDisplay = new CurrentDisplay(info.currentSize, info.rotation);
if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED
&& mCurrentDisplay.rotation == mQuickStepStartingRotation) {
@@ -256,20 +253,12 @@
Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplay.rotation);
}
- mCurrentDisplay = new CurrentDisplay(region.realSize, region.rotation);
+ mCurrentDisplay = new CurrentDisplay(region.currentSize, region.rotation);
OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay);
- if (DEBUG) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "cached region: " + regionToKeep
- + " mCurrentDisplay: " + mCurrentDisplay + " " + this);
- }
if (regionToKeep == null) {
regionToKeep = createRegionForDisplay(region);
}
mSwipeTouchRegions.clear();
- if (DEBUG) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "adding region: " + regionToKeep
- + " mCurrentDisplay: " + mCurrentDisplay + " " + this);
- }
mSwipeTouchRegions.put(mCurrentDisplay, regionToKeep);
updateAssistantRegions(regionToKeep);
}
@@ -289,7 +278,7 @@
+ " with mode: " + mMode + " displayRotation: " + display.rotation);
}
- Point size = display.realSize;
+ Point size = display.currentSize;
int rotation = display.rotation;
int touchHeight = mNavBarGesturalHeight;
OrientationRectF orientationRectF =
@@ -301,10 +290,6 @@
mAssistantLeftRegion.setEmpty();
mAssistantRightRegion.setEmpty();
int navbarSize = getNavbarSize(ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
- if (DEBUG) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "else case mode: " + mMode
- + " getNavbarSize: " + navbarSize + " rotation: " + rotation + " " + this);
- }
switch (rotation) {
case Surface.ROTATION_90:
orientationRectF.left = orientationRectF.right
@@ -355,8 +340,8 @@
}
boolean touchInValidSwipeRegions(float x, float y) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "touchInValidSwipeRegions " + x + "," + y + " in "
+ if (DEBUG) {
+ Log.d(TAG, "touchInValidSwipeRegions " + x + "," + y + " in "
+ mLastRectTouched + " this: " + this);
}
if (mLastRectTouched != null) {
@@ -399,16 +384,10 @@
}
for (OrientationRectF rect : mSwipeTouchRegions.values()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "transform:DOWN, rect=" + rect);
- }
if (rect == null) {
continue;
}
if (rect.applyTransform(event, false)) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "setting mLastRectTouched");
- }
mLastRectTouched = rect;
mActiveTouchRotation = rect.mRotation;
if (mEnableMultipleRegions
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 2f1538b..3302da0 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -93,10 +93,6 @@
* @return The change id of the current task list
*/
public synchronized int getTasks(boolean loadKeysOnly, Consumer<ArrayList<Task>> callback) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTasks: keysOnly=" + loadKeysOnly
- + " callback=" + callback);
- }
final int requestLoadId = mChangeId;
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
// The list is up to date, send the callback on the next frame,
@@ -105,9 +101,6 @@
// Copy synchronously as the changeId might change by next frame
ArrayList<Task> result = copyOf(mResultsUi);
mMainThreadExecutor.post(() -> {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTasks: no new tasks");
- }
callback.accept(result);
});
}
@@ -118,24 +111,15 @@
// Kick off task loading in the background
mLoadingTasksInBackground = true;
UI_HELPER_EXECUTOR.execute(() -> {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTasks: loading in bg start");
- }
if (!mResultsBg.isValidForRequest(requestLoadId, loadKeysOnly)) {
mResultsBg = loadTasksInBackground(Integer.MAX_VALUE, requestLoadId, loadKeysOnly);
}
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTasks: loading in bg end");
- }
TaskLoadResult loadResult = mResultsBg;
mMainThreadExecutor.execute(() -> {
mLoadingTasksInBackground = false;
mResultsUi = loadResult;
if (callback != null) {
ArrayList<Task> result = copyOf(mResultsUi);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTasks: callback w/ bg results");
- }
callback.accept(result);
}
});
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 3b92779..0e9e3ad 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -22,10 +22,13 @@
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
import static com.android.launcher3.Utilities.createHomeIntent;
+import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -35,6 +38,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.view.SurfaceControl.Transaction;
import android.view.View;
import androidx.annotation.Nullable;
@@ -47,6 +51,7 @@
import com.android.launcher3.R;
import com.android.launcher3.WrappedAnimationRunnerImpl;
import com.android.launcher3.WrappedLauncherAnimationRunner;
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -69,6 +74,7 @@
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.views.OverviewActionsView;
+import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.SplitPlaceholderView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityOptionsCompat;
@@ -90,6 +96,8 @@
private Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private static final long HOME_APPEAR_DURATION = 250;
+
private RecentsDragLayer mDragLayer;
private ScrimView mScrimView;
private FallbackRecentsView mFallbackRecentsView;
@@ -112,6 +120,7 @@
mScrimView = findViewById(R.id.scrim_view);
mFallbackRecentsView = findViewById(R.id.overview_panel);
mActionsView = findViewById(R.id.overview_actions_view);
+ SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
splitPlaceholderView.init(
@@ -291,6 +300,16 @@
super.onConfigurationChanged(newConfig);
}
+ @Override
+ public void onStateSetEnd(RecentsState state) {
+ super.onStateSetEnd(state);
+
+ if (state == RecentsState.DEFAULT) {
+ AccessibilityManagerCompat.sendStateEventToTest(getBaseContext(),
+ OVERVIEW_STATE_ORDINAL);
+ }
+ }
+
/**
* Initialize/update the device profile.
*/
@@ -329,7 +348,42 @@
}
public void startHome() {
- startActivity(createHomeIntent());
+ if (LIVE_TILE.get()) {
+ RecentsView recentsView = getOverviewPanel();
+ recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true,
+ this::startHomeInternal));
+ } else {
+ startHomeInternal();
+ }
+ }
+
+ private void startHomeInternal() {
+ WrappedLauncherAnimationRunner runner = new WrappedLauncherAnimationRunner(
+ getMainThreadHandler(), this::onCreateAnimationToHome, true);
+ RemoteAnimationAdapterCompat adapterCompat =
+ new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0);
+ startActivity(createHomeIntent(),
+ ActivityOptionsCompat.makeRemoteAnimation(adapterCompat).toBundle());
+ }
+
+ private void onCreateAnimationToHome(
+ int transit, RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) {
+ AnimatorPlaybackController controller = getStateManager()
+ .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION);
+ controller.dispatchOnStart();
+
+ RemoteAnimationTargets targets = new RemoteAnimationTargets(
+ appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
+ for (RemoteAnimationTargetCompat app : targets.apps) {
+ new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply();
+ }
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(controller.getAnimationPlayer());
+ anim.setDuration(HOME_APPEAR_DURATION);
+ result.setAnimation(anim, this,
+ () -> getStateManager().goToState(RecentsState.HOME, false));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index ef09957..110b356 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -18,7 +18,7 @@
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
@@ -229,7 +229,6 @@
* Cleans up all the registered listeners and receivers.
*/
public void destroy() {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "destroying RADS", new Throwable());
for (Runnable r : mOnDestroyActions) {
r.run();
}
@@ -271,15 +270,9 @@
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
- // ignore displays that aren't running launcher and frame refresh rate changes
- return;
+ if ((flags & CHANGE_ROTATION) != 0) {
+ mNavBarPosition = new NavBarPosition(mMode, info);
}
-
- if (!mMode.hasGestures) {
- return;
- }
- mNavBarPosition = new NavBarPosition(mMode, info);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index c786167..2eb9dd8 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -31,6 +31,7 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.icons.IconProvider;
+import com.android.launcher3.icons.IconProvider.IconChangeListener;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.shared.recents.model.Task;
@@ -49,7 +50,7 @@
* Singleton class to load and manage recents model.
*/
@TargetApi(Build.VERSION_CODES.O)
-public class RecentsModel extends TaskStackChangeListener {
+public class RecentsModel extends TaskStackChangeListener implements IconChangeListener {
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
@@ -69,12 +70,13 @@
mContext = context;
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
- mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR);
+
+ IconProvider iconProvider = new IconProvider(context);
+ mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
mThumbnailCache = new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR);
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
- IconProvider.registerIconChangeListener(context,
- this::onPackageIconChanged, MAIN_EXECUTOR.getHandler());
+ iconProvider.registerIconChangeListener(this, MAIN_EXECUTOR.getHandler());
}
public TaskIconCache getIconCache() {
@@ -183,17 +185,23 @@
if (level == ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL) {
// Clear everything once we reach a low-mem situation
mThumbnailCache.clear();
- mIconCache.clear();
+ mIconCache.clearCache();
}
}
- private void onPackageIconChanged(String pkg, UserHandle user) {
- mIconCache.invalidateCacheEntries(pkg, user);
+ @Override
+ public void onAppIconChanged(String packageName, UserHandle user) {
+ mIconCache.invalidateCacheEntries(packageName, user);
for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) {
- mThumbnailChangeListeners.get(i).onTaskIconChanged(pkg, user);
+ mThumbnailChangeListeners.get(i).onTaskIconChanged(packageName, user);
}
}
+ @Override
+ public void onSystemIconStateChanged(String iconState) {
+ mIconCache.clearCache();
+ }
+
/**
* Adds a listener for visuals changes
*/
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index fd0de42..070d725 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -17,8 +17,9 @@
import static android.view.Surface.ROTATION_0;
+import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_FRAME_DELAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
@@ -132,8 +133,6 @@
private RotationTouchHelper(Context context) {
mContext = context;
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "RotationTouchHelper ctor init? " + mNeedsInit
- + " " + this);
if (mNeedsInit) {
init();
}
@@ -141,11 +140,8 @@
public void init() {
if (!mNeedsInit) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "Did not need init? " + " " + this);
return;
}
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "RotationTouchHelper init() " + this,
- new Throwable());
mDisplayController = DisplayController.INSTANCE.get(mContext);
Resources resources = mContext.getResources();
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(mContext);
@@ -156,8 +152,6 @@
// Register for navigation mode changes
SysUINavigationMode.Mode newMode = mSysUiNavMode.addModeChangeListener(this);
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "AddedModeChangeListener: " + this +
- " currentMode: " + newMode);
onNavigationModeChanged(newMode);
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
@@ -203,7 +197,6 @@
* Cleans up all the registered listeners and receivers.
*/
public void destroy() {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "destroying " + this);
for (Runnable r : mOnDestroyActions) {
r.run();
}
@@ -252,7 +245,6 @@
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "nav mode changed: " + newMode);
mDisplayController.removeChangeListener(this);
mDisplayController.addChangeListener(this);
onDisplayInfoChanged(mContext, mDisplayController.getInfo(), CHANGE_ALL);
@@ -274,8 +266,7 @@
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if (info.id != mDisplayId|| flags == CHANGE_FRAME_DELAY) {
- // ignore displays that aren't running launcher and frame refresh rate changes
+ if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
return;
}
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 0f34a72..29a00d1 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -145,6 +145,11 @@
targetX + halfIconSize, targetY + halfIconSize);
}
+ /** Returns the corner radius of the window at the end of the animation. */
+ public float getEndRadius(RectF cropRectF) {
+ return cropRectF.width() / 2f;
+ }
+
public abstract @NonNull AnimatorPlaybackController createActivityAnimationToHome();
public void playAtomicAnimation(float velocity) {
@@ -197,8 +202,7 @@
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
Matrix homeToWindowPositionMap = new Matrix();
- final RectF startRect = updateProgressForStartRect(
- homeToWindowPositionMap, startProgress);
+ final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
// Move the startRect to Launcher space as floatingIconView runs in Launcher
@@ -210,7 +214,7 @@
if (PROTOTYPE_APP_CLOSE.get()) {
anim = new RectFSpringAnim2(startRect, targetRect, mContext,
mTaskViewSimulator.getCurrentCornerRadius(),
- cropRectF.width() / 2f);
+ homeAnimationFactory.getEndRadius(cropRectF));
} else {
anim = new RectFSpringAnim(startRect, targetRect, mContext);
}
@@ -269,7 +273,7 @@
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
// rounding at the end of the animation.
mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
- mEndRadius = cropRectF.width() / 2f;
+ mEndRadius = factory.getEndRadius(cropRectF);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/SysUINavigationMode.java b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
index efec037..74f4bea 100644
--- a/quickstep/src/com/android/quickstep/SysUINavigationMode.java
+++ b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
@@ -34,6 +34,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* Observer for the resource config that specifies the navigation bar mode.
@@ -75,7 +76,8 @@
private int mNavBarGesturalHeight;
private int mNavBarLargerGesturalHeight;
- private final List<NavigationModeChangeListener> mChangeListeners = new ArrayList<>();
+ private final List<NavigationModeChangeListener> mChangeListeners =
+ new CopyOnWriteArrayList<>();
private final List<OneHandedModeChangeListener> mOneHandedOverlayChangeListeners =
new ArrayList<>();
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index f6018d1..39d8888 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -68,6 +68,12 @@
MAIN_EXECUTOR.execute(() -> clearProxy());
};
+ // Save the listeners passed into the proxy since when set/register these listeners,
+ // setProxy may not have been called, eg. OverviewProxyService is not connected yet.
+ private IPipAnimationListener mPendingPipAnimationListener;
+ private ISplitScreenListener mPendingSplitScreenListener;
+ private IStartingWindowListener mPendingStartingWindowListener;
+
// Used to dedupe calls to SystemUI
private int mLastShelfHeight;
private boolean mLastShelfVisible;
@@ -116,6 +122,19 @@
mShellTransitions = shellTransitions;
mStartingWindow = startingWindow;
linkToDeath();
+ // re-attach the listeners once missing due to setProxy has not been initialized yet.
+ if (mPendingPipAnimationListener != null && mPip != null) {
+ setPinnedStackAnimationListener(mPendingPipAnimationListener);
+ mPendingPipAnimationListener = null;
+ }
+ if (mPendingSplitScreenListener != null && mSplitScreen != null) {
+ registerSplitScreenListener(mPendingSplitScreenListener);
+ mPendingSplitScreenListener = null;
+ }
+ if (mPendingStartingWindowListener != null && mStartingWindow != null) {
+ setStartingWindowListener(mPendingStartingWindowListener);
+ mPendingStartingWindowListener = null;
+ }
}
public void clearProxy() {
@@ -390,6 +409,8 @@
} catch (RemoteException e) {
Log.w(TAG, "Failed call setPinnedStackAnimationListener", e);
}
+ } else {
+ mPendingPipAnimationListener = listener;
}
}
@@ -427,6 +448,8 @@
} catch (RemoteException e) {
Log.w(TAG, "Failed call registerSplitScreenListener");
}
+ } else {
+ mPendingSplitScreenListener = listener;
}
}
@@ -438,6 +461,7 @@
Log.w(TAG, "Failed call unregisterSplitScreenListener");
}
}
+ mPendingSplitScreenListener = null;
}
public void setSideStageVisibility(boolean visible) {
@@ -590,6 +614,8 @@
} catch (RemoteException e) {
Log.w(TAG, "Failed call setStartingWindowListener", e);
}
+ } else {
+ mPendingStartingWindowListener = listener;
}
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index c87cd17..44a3e95 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -61,9 +61,11 @@
if (LIVE_TILE.get() && activityInterface.isInLiveTileMode()
&& activityInterface.getCreatedActivity() != null) {
RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
- recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
- ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
- mLiveTileRestartListener);
+ if (recentsView != null) {
+ recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
+ mLiveTileRestartListener);
+ }
}
}
};
@@ -135,10 +137,12 @@
&& activityInterface.getCreatedActivity() != null) {
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
- RemoteAnimationTargetCompat[] apps = new RemoteAnimationTargetCompat[1];
- apps[0] = appearedTaskTarget;
- recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
- return;
+ if (recentsView != null) {
+ RemoteAnimationTargetCompat[] apps = new RemoteAnimationTargetCompat[1];
+ apps[0] = appearedTaskTarget;
+ recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
+ return;
+ }
}
if (mController != null) {
if (mLastAppearedTaskTarget == null
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index ba1c413..fa61fff 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -16,6 +16,7 @@
package com.android.quickstep;
import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED;
+import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
import android.app.ActivityManager.TaskDescription;
import android.content.Context;
@@ -35,9 +36,12 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconProvider;
-import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
+import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.Preconditions;
import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.TaskKeyLruCache;
@@ -52,7 +56,7 @@
/**
* Manages the caching of task icons and related data.
*/
-public class TaskIconCache {
+public class TaskIconCache implements DisplayInfoChangeListener {
private final Executor mBgExecutor;
private final AccessibilityManager mAccessibilityManager;
@@ -62,15 +66,27 @@
private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>();
private final IconProvider mIconProvider;
- public TaskIconCache(Context context, Executor bgExecutor) {
+ private BaseIconFactory mIconFactory;
+
+ public TaskIconCache(Context context, Executor bgExecutor, IconProvider iconProvider) {
mContext = context;
mBgExecutor = bgExecutor;
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+ mIconProvider = iconProvider;
Resources res = context.getResources();
int cacheSize = res.getInteger(R.integer.recentsIconCacheSize);
+
mIconCache = new TaskKeyLruCache<>(cacheSize);
- mIconProvider = new IconProvider(context);
+
+ DisplayController.INSTANCE.get(mContext).addChangeListener(this);
+ }
+
+ @Override
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ if ((flags & CHANGE_DENSITY) != 0) {
+ clearCache();
+ }
}
/**
@@ -104,8 +120,11 @@
return request;
}
- public void clear() {
- mIconCache.evictAll();
+ /**
+ * Clears the icon cache
+ */
+ public void clearCache() {
+ mBgExecutor.execute(this::resetFactory);
}
void onTaskRemoved(TaskKey taskKey) {
@@ -193,8 +212,8 @@
synchronized (mDefaultIcons) {
BitmapInfo info = mDefaultIcons.get(userId);
if (info == null) {
- try (LauncherIcons la = LauncherIcons.obtain(mContext)) {
- info = la.makeDefaultIcon(UserHandle.of(userId));
+ try (BaseIconFactory bif = getIconFactory()) {
+ info = bif.makeDefaultIcon(UserHandle.of(userId));
}
mDefaultIcons.put(userId, info);
}
@@ -205,16 +224,32 @@
@WorkerThread
private BitmapInfo getBitmapInfo(Drawable drawable, int userId,
int primaryColor, boolean isInstantApp) {
- try (LauncherIcons la = LauncherIcons.obtain(mContext)) {
- la.disableColorExtraction();
- la.setWrapperBackgroundColor(primaryColor);
+ try (BaseIconFactory bif = getIconFactory()) {
+ bif.disableColorExtraction();
+ bif.setWrapperBackgroundColor(primaryColor);
// User version code O, so that the icon is always wrapped in an adaptive icon container
- return la.createBadgedIconBitmap(drawable, UserHandle.of(userId),
+ return bif.createBadgedIconBitmap(drawable, UserHandle.of(userId),
Build.VERSION_CODES.O, isInstantApp);
}
}
+ @WorkerThread
+ private BaseIconFactory getIconFactory() {
+ if (mIconFactory == null) {
+ mIconFactory = new BaseIconFactory(mContext,
+ DisplayController.INSTANCE.get(mContext).getInfo().densityDpi,
+ mContext.getResources().getDimensionPixelSize(R.dimen.taskbar_icon_size));
+ }
+ return mIconFactory;
+ }
+
+ @WorkerThread
+ private void resetFactory() {
+ mIconFactory = null;
+ mIconCache.evictAll();
+ }
+
private static class TaskCacheEntry {
public Drawable icon;
public String contentDescription = "";
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 4fc9770..027dd1c 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -52,6 +52,7 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
@@ -145,12 +146,25 @@
@Nullable
private OverscrollPlugin mOverscrollPlugin;
- private final IBinder mMyBinder = new IOverviewProxy.Stub() {
+ /**
+ * Extension of OverviewProxy aidl interface without needing to modify the actual interface.
+ * This is for methods that need only need local access and not intended to make IPC calls.
+ */
+ public abstract static class TISBinder extends IOverviewProxy.Stub {
+ public abstract void setTaskbarOverviewProxyDelegate(
+ @Nullable TaskbarOverviewProxyDelegate i);
+ }
+
+
+ private final TISBinder mMyBinder = new TISBinder() {
+
+ public void setTaskbarOverviewProxyDelegate(
+ @Nullable TaskbarOverviewProxyDelegate delegate) {
+ mTaskbarOverviewProxyDelegate = delegate;
+ }
@BinderThread
public void onInitialize(Bundle bundle) {
- Log.d(TAG + " b/182478748", "TouchInteractionService.onInitialize: user="
- + getUserId());
ISystemUiProxy proxy = ISystemUiProxy.Stub.asInterface(
bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
IPip pip = IPip.Stub.asInterface(bundle.getBinder(KEY_EXTRA_SHELL_PIP));
@@ -252,20 +266,49 @@
MAIN_EXECUTOR.execute(() -> mDeviceState.setDeferredGestureRegion(region));
}
+ @Override
public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) {
WindowBounds wb = new WindowBounds(bounds, insets);
MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
}
+
+ @Override
+ public void onImeWindowStatusChanged(int displayId, IBinder token, int vis,
+ int backDisposition, boolean showImeSwitcher) throws RemoteException {
+ if (mTaskbarOverviewProxyDelegate == null) {
+ return;
+ }
+ MAIN_EXECUTOR.execute(() -> {
+ if (mTaskbarOverviewProxyDelegate == null) {
+ return;
+ }
+ mTaskbarOverviewProxyDelegate
+ .updateImeStatus(displayId, vis, backDisposition, showImeSwitcher);
+ });
+ }
};
+ public interface TaskbarOverviewProxyDelegate {
+ void updateImeStatus(int displayId, int vis, int backDisposition,
+ boolean showImeSwitcher);
+ }
+
private static boolean sConnected = false;
+ private static TouchInteractionService sInstance;
private static boolean sIsInitialized = false;
private RotationTouchHelper mRotationTouchHelper;
+ @Nullable
+ private TaskbarOverviewProxyDelegate mTaskbarOverviewProxyDelegate;
public static boolean isConnected() {
return sConnected;
}
+ @Nullable
+ public static TouchInteractionService getInstance() {
+ return sInstance;
+ }
+
public static boolean isInitialized() {
return sIsInitialized;
}
@@ -293,6 +336,10 @@
private DisplayManager mDisplayManager;
+ public TouchInteractionService() {
+ sInstance = this;
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -301,8 +348,6 @@
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
mDeviceState = new RecentsAnimationDeviceState(this, true);
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "RADS OTT instance: " +
- mDeviceState.getRotationTouchHelper().getOrientationTouchTransformer());
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
mDeviceState.addOneHandedModeChangedCallback(this::onOneHandedModeOverlayChanged);
@@ -314,8 +359,6 @@
}
private void disposeEventHandlers() {
- Log.d(TAG + " b/182478748", "TouchInteractionService.disposeEventHandlers: user="
- + getUserId());
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
@@ -327,21 +370,12 @@
}
private void initInputMonitor() {
- Log.d(TAG + " b/182478748", "TouchInteractionService.initInputMonitor: user="
- + getUserId());
disposeEventHandlers();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TIS_NO_EVENTS, "initInputMonitor: isButtonMode? "
- + mDeviceState.isButtonNavMode());
- }
-
if (mDeviceState.isButtonNavMode()) {
- Log.d(TAG + " b/182478748", "isButtonNav: user=" + getUserId());
return;
}
- Log.d(TAG + " b/182478748", "create swipe-up input monitor: user=" + getUserId());
mInputMonitorCompat = new InputMonitorCompat("swipe-up", mDeviceState.getDisplayId());
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
mMainChoreographer, this::onInputEvent);
@@ -389,6 +423,10 @@
onOverviewTargetChange(mOverviewComponentObserver.isHomeAndOverviewSame());
}
+ public OverviewCommandHelper getOverviewCommandHelper() {
+ return mOverviewCommandHelper;
+ }
+
private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() {
if (!mDeviceState.isUserUnlocked() || mDeviceState.isButtonNavMode()) {
// Skip if not yet unlocked (can't read user shared prefs) or if the current navigation
@@ -496,6 +534,13 @@
Point sz = new Point();
display.getRealSize(sz);
if (rotation != Surface.ROTATION_0) {
+ if ((rotation % 2) != 0) {
+ // via display-manager, the display size is unrotated, so "rotate" its size
+ // to match the rotation we are transforming the event into.
+ final int tmpX = sz.x;
+ sz.x = sz.y;
+ sz.y = tmpX;
+ }
event.transform(InputChannelCompat.createRotationMatrix(rotation, sz.x, sz.y));
}
}
@@ -512,17 +557,10 @@
final int action = event.getAction();
if (action == ACTION_DOWN) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "TouchInteractionService.onInputEvent:DOWN");
- }
mRotationTouchHelper.setOrientationTransformIfNeeded(event);
if (!mDeviceState.isOneHandedModeActive()
&& mRotationTouchHelper.isInSwipeUpTouchRegion(event)) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME,
- "TouchInteractionService.onInputEvent:isInSwipeUpTouchRegion");
- }
// Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger
// onConsumerInactive and wipe the previous gesture state
GestureState prevGestureState = new GestureState(mGestureState);
@@ -618,9 +656,6 @@
private InputConsumer newConsumer(GestureState previousGestureState,
GestureState newGestureState, MotionEvent event) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "newConsumer");
- }
boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
if (!mDeviceState.isUserUnlocked()) {
@@ -632,9 +667,6 @@
return mResetGestureInputConsumer;
}
}
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_SWIPE_TO_HOME, "newConsumer:user is unlocked");
- }
// When there is an existing recents animation running, bypass systemState check as this is
// a followup gesture and the first gesture started in a valid system state.
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 7067dbc..4d776ba 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -20,9 +20,10 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -86,8 +87,10 @@
float[] scaleAndOffset = state.getOverviewScaleAndOffset(mActivity);
setter.setFloat(mRecentsView, RECENTS_SCALE_PROPERTY, scaleAndOffset[0],
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
- setter.setFloat(mRecentsView, ADJACENT_PAGE_OFFSET, scaleAndOffset[1],
+ setter.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1],
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
+ setter.setFloat(mRecentsView, ADJACENT_PAGE_VERTICAL_OFFSET, scaleAndOffset[2],
+ config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
@@ -98,6 +101,6 @@
state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()) ? 1f : 0f, LINEAR);
setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
- config.getInterpolator(ANIM_WORKSPACE_SCRIM_FADE, LINEAR));
+ config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 4d4b6e1..ac3fb27 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -20,6 +20,7 @@
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
+import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
@@ -27,6 +28,9 @@
import android.util.AttributeSet;
import android.util.Log;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.testing.TestProtocol;
@@ -67,7 +71,6 @@
@Override
public void startHome() {
mActivity.startHome();
- mActivity.getStateManager().goToState(RecentsState.HOME);
}
/**
@@ -86,14 +89,17 @@
* to the center.
*/
@Override
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
- super.onGestureEndTargetCalculated(endTarget);
- if (mHomeTaskInfo != null && endTarget == RECENTS) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ super.onPrepareGestureEndAnimation(animatorSet, endTarget);
+ if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
TaskView tv = getTaskView(mHomeTaskInfo.taskId);
if (tv != null) {
PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150);
pa.addEndListener(e -> setCurrentTask(-1));
- runDismissAnimation(pa);
+ AnimatorPlaybackController controller = pa.createPlaybackController();
+ controller.dispatchOnStart();
+ animatorSet.play(controller.getAnimationPlayer());
}
}
}
@@ -134,10 +140,6 @@
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as if we are switching on any other app.
if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == mRunningTaskId && !tasks.isEmpty()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED,
- "FallbackRecentsView.applyLoadPlan: running task is home");
- }
// Check if the task list has running task
boolean found = false;
for (Task t : tasks) {
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index b3d6cfa..532f219 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -39,15 +39,18 @@
private static final int FLAG_OVERVIEW_ACTIONS = BaseState.getFlag(3);
private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4);
private static final int FLAG_SCRIM = BaseState.getFlag(5);
+ private static final int FLAG_LIVE_TILE = BaseState.getFlag(6);
public static final RecentsState DEFAULT = new RecentsState(0,
- FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM
+ | FLAG_LIVE_TILE);
public static final RecentsState MODAL_TASK = new ModalState(1,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL
- | FLAG_SHOW_AS_GRID | FLAG_SCRIM);
+ | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE);
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN);
public static final RecentsState HOME = new RecentsState(3, 0);
+ public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
public final int ordinal;
private final int mFlags;
@@ -108,6 +111,13 @@
}
/**
+ * For this state, whether live tile should be shown.
+ */
+ public boolean hasLiveTile() {
+ return hasFlag(FLAG_LIVE_TILE);
+ }
+
+ /**
* For this state, what color scrim should be drawn behind overview.
*/
public int getScrimColor(RecentsActivity activity) {
@@ -116,7 +126,7 @@
}
public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
- return new float[] { NO_SCALE, NO_OFFSET };
+ return new float[] { NO_SCALE, NO_OFFSET, NO_OFFSET };
}
/**
@@ -152,4 +162,15 @@
return getOverviewScaleAndOffsetForBackgroundState(activity);
}
}
+
+ private static class LauncherState extends RecentsState {
+ LauncherState(int id, int flags) {
+ super(id, flags);
+ }
+
+ @Override
+ public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
+ return new float[] { NO_SCALE, NO_OFFSET, 1 };
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
index d7458d2..273d1f6 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep.fallback;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
+
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.quickstep.RecentsActivity;
@@ -26,7 +28,8 @@
@Override
protected boolean isRecentsInteractive() {
- return mActivity.hasWindowFocus();
+ return mActivity.hasWindowFocus() || (LIVE_TILE.get()
+ && mActivity.getStateManager().getState().hasLiveTile());
}
@Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 9c64794..fcc0217 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -116,7 +116,7 @@
R.dimen.device_locked_y_offset);
// Do not use DeviceProfile as the user data might be locked
- mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
// Init states
mStateCallback = new MultiStateCallback(STATE_NAMES);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
index d82d43d..8d9c524 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OneHandedModeInputConsumer.java
@@ -70,7 +70,7 @@
mDragDistThreshold = context.getResources().getDimensionPixelSize(
R.dimen.gestures_onehanded_drag_threshold);
mSquaredSlop = Utilities.squaredTouchSlop(context);
- mDisplaySize = DisplayController.INSTANCE.get(mContext).getInfo().realSize;
+ mDisplaySize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
mNavBarSize = ResourceUtils.getNavbarSize(NAVBAR_BOTTOM_GESTURE_SIZE,
mContext.getResources());
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index fa9e0ec..4af6338 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -18,6 +18,8 @@
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import android.media.AudioManager;
+import android.media.session.MediaSessionManager;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -101,6 +103,17 @@
@Override
public void onKeyEvent(KeyEvent ev) {
if (LIVE_TILE.get()) {
+ switch (ev.getKeyCode()) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ MediaSessionManager mgr = mActivity.getSystemService(MediaSessionManager.class);
+ mgr.dispatchVolumeKeyEventAsSystemService(ev,
+ AudioManager.USE_DEFAULT_STREAM_TYPE);
+ break;
+ default:
+ break;
+ }
mActivity.dispatchKeyEvent(ev);
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
new file mode 100644
index 0000000..76f43c9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+import java.net.URISyntaxException;
+
+/**
+ * A page shows after SUW flow to hint users to swipe up from the bottom of the screen to go home
+ * for the gestural system navigation.
+ */
+public class AllSetActivity extends Activity {
+
+ private static final String LOG_TAG = "AllSetActivity";
+ private static final String URI_SYSTEM_NAVIGATION_SETTING =
+ "#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end";
+ private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "accent_color_dark_mode";
+ private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "accent_color_light_mode";
+
+ private int mAccentColor;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_allset);
+ setTitle(R.string.allset_title);
+
+ final int mode =
+ getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ mAccentColor = getIntent().getIntExtra(
+ mode == Configuration.UI_MODE_NIGHT_YES
+ ? EXTRA_ACCENT_COLOR_DARK_MODE : EXTRA_ACCENT_COLOR_LIGHT_MODE,
+ /* defValue= */ Color.BLACK);
+
+ ((ImageView) findViewById(R.id.icon)).getDrawable().mutate().setTint(mAccentColor);
+
+ TextView navigationSettings = findViewById(R.id.navigation_settings);
+ navigationSettings.setMovementMethod(LinkMovementMethod.getInstance());
+ AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo(
+ AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION,
+ new AllSetLinkSpan(
+ /* context= */ this,
+ view -> {
+ try {
+ startActivityForResult(
+ Intent.parseUri(URI_SYSTEM_NAVIGATION_SETTING, 0), 0);
+ } catch (URISyntaxException e) {
+ Log.e(LOG_TAG, "Failed to parse system nav settings intent", e);
+ }
+ finish();
+ }));
+ navigationSettings.setText(
+ AnnotationSpan.linkify(getText(R.string.allset_navigation_settings), linkInfo));
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ if (hasFocus) {
+ hideSystemUI();
+ }
+ }
+
+ private void hideSystemUI() {
+ getWindow().getDecorView().setSystemUiVisibility(
+ View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_FULLSCREEN);
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
+ }
+
+ private final class AllSetLinkSpan extends AnnotationSpan {
+
+ private final String mFontFamily;
+ private final int mTextSize;
+
+ AllSetLinkSpan(Context context, View.OnClickListener listener) {
+ super(listener);
+ TypedArray typedArray =
+ context.obtainStyledAttributes(R.style.TextAppearance_GestureTutorial_LinkText,
+ R.styleable.AllSetLinkSpan);
+ mFontFamily = typedArray.getString(R.styleable.AllSetLinkSpan_android_fontFamily);
+ mTextSize =
+ typedArray.getDimensionPixelSize(
+ R.styleable.AllSetLinkSpan_android_textSize, /* defValue= */ -1);
+ typedArray.recycle();
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setColor(mAccentColor);
+ ds.setTypeface(Typeface.create(mFontFamily, Typeface.NORMAL));
+ ds.setUnderlineText(false);
+ if (mTextSize != -1) {
+ ds.setTextSize(mTextSize);
+ }
+ }
+ }
+
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
new file mode 100644
index 0000000..fea5078
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/AnnotationSpan.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep.interaction;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.text.Annotation;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.style.URLSpan;
+import android.util.Log;
+import android.view.View;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * This class is used to add {@link View.OnClickListener} for the text been wrapped by
+ * annotation.
+ *
+ * Copied from packages/apps/Settings/src/com/android/settings/utils/AnnotationSpan.java.
+ */
+public class AnnotationSpan extends URLSpan {
+
+ private final View.OnClickListener mClickListener;
+
+ AnnotationSpan(View.OnClickListener lsn) {
+ super((String) null);
+ mClickListener = lsn;
+ }
+
+ @Override
+ public void onClick(View widget) {
+ if (mClickListener != null) {
+ mClickListener.onClick(widget);
+ }
+ }
+
+ public static CharSequence linkify(CharSequence rawText, LinkInfo... linkInfos) {
+ SpannableString msg = new SpannableString(rawText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ SpannableStringBuilder builder = new SpannableStringBuilder(msg);
+ for (Annotation annotation : spans) {
+ final String key = annotation.getValue();
+ int start = msg.getSpanStart(annotation);
+ int end = msg.getSpanEnd(annotation);
+ AnnotationSpan link = null;
+ for (LinkInfo linkInfo : linkInfos) {
+ if (linkInfo.mAnnotation.equals(key)) {
+ link = linkInfo.mCustomizedSpan != null ? linkInfo.mCustomizedSpan
+ : new AnnotationSpan(linkInfo.mClickListener);
+ break;
+ }
+ }
+ if (link != null) {
+ builder.setSpan(link, start, end, msg.getSpanFlags(link));
+ }
+ }
+ return builder;
+ }
+
+ /**
+ * get the text part without having text for link part
+ */
+ public static CharSequence textWithoutLink(CharSequence encodedText) {
+ SpannableString msg = new SpannableString(encodedText);
+ Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
+ if (spans == null) {
+ return encodedText;
+ }
+ Arrays.sort(spans, Comparator.comparingInt(span -> -msg.getSpanStart(span)));
+ StringBuilder msgWithoutLink = new StringBuilder(msg.toString());
+ for (Annotation span : spans) {
+ msgWithoutLink.delete(msg.getSpanStart(span), msg.getSpanEnd(span));
+ }
+ return msgWithoutLink.toString();
+ }
+
+ /** Data class to store the annotation and the click action. */
+ public static class LinkInfo {
+ public static final String DEFAULT_ANNOTATION = "link";
+ private static final String TAG = "AnnotationSpan.LinkInfo";
+ private final String mAnnotation;
+ private final Boolean mActionable;
+ private final View.OnClickListener mClickListener;
+ private final AnnotationSpan mCustomizedSpan;
+
+ public LinkInfo(String annotation, View.OnClickListener listener) {
+ mAnnotation = annotation;
+ mClickListener = listener;
+ mActionable = true; // assume actionable
+ mCustomizedSpan = null;
+ }
+
+ public LinkInfo(String annotation, AnnotationSpan customizedSpan) {
+ mAnnotation = annotation;
+ mClickListener = null;
+ mActionable = customizedSpan != null;
+ mCustomizedSpan = customizedSpan;
+ }
+
+ public LinkInfo(Context context, String annotation, Intent intent) {
+ mAnnotation = annotation;
+ mCustomizedSpan = null;
+ if (intent != null) {
+ mActionable = context.getPackageManager().resolveActivity(intent, 0) != null;
+ } else {
+ mActionable = false;
+ }
+ if (mActionable) {
+ mClickListener =
+ view -> {
+ try {
+ context.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "Activity was not found for intent, " + intent);
+ }
+ };
+ } else {
+ mClickListener = null;
+ }
+ }
+
+ public boolean isActionable() {
+ return mActionable;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index c396eec..14c3a92 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -20,9 +20,7 @@
import static com.android.quickstep.interaction.TutorialController.TutorialType.RIGHT_EDGE_BACK_NAVIGATION;
import android.graphics.PointF;
-import android.view.View;
-import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import com.android.launcher3.R;
@@ -36,11 +34,6 @@
super(fragment, tutorialType);
}
- @Nullable
- public View getMockLauncherView() {
- return null;
- }
-
@Override
public Integer getIntroductionTitle() {
return mTutorialType == LEFT_EDGE_BACK_NAVIGATION
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 3c59ed3..06610e6 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -16,15 +16,11 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.quickstep.interaction.TutorialController.TutorialType.OVERVIEW_NAVIGATION_COMPLETE;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.graphics.PointF;
import android.os.Build;
-import android.view.View;
-
-import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
@@ -52,12 +48,6 @@
return R.string.overview_gesture_intro_subtitle;
}
- @Nullable
- @Override
- public View getMockLauncherView() {
- return null;
- }
-
@Override
public void onBackGestureAttempted(BackGestureResult result) {
switch (mTutorialType) {
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java b/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
deleted file mode 100644
index 80ffe66..0000000
--- a/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.interaction;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.graphics.LauncherPreviewRenderer;
-
-/** Renders a fake Launcher for use in the Sandbox. */
-class SandboxLauncherRenderer extends LauncherPreviewRenderer {
- SandboxLauncherRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
- super(context, idp, migrated);
- }
-
- @Override
- public boolean shouldShowRealLauncherPreview() {
- return false;
- }
-
- @Override
- public boolean shouldShowQsb() {
- return false;
- }
-
- @Override
- public View.OnLongClickListener getWorkspaceChildOnLongClickListener() {
- return null;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index 1aa64fa..66e0400 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -43,7 +43,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.quickstep.AnimatedFloat;
@@ -156,7 +156,7 @@
fadeAnim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
}
if (onEndRunnable != null) {
- fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
+ fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
}
AnimatorSet animset = fadeAnim.buildAnim();
animset.setStartDelay(100);
@@ -174,7 +174,7 @@
anim.setViewAlpha(mFakePreviousTaskView, 0, ACCEL);
}
if (onEndRunnable != null) {
- anim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
+ anim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
}
}
AnimatorSet animset = anim.buildAnim();
@@ -205,10 +205,10 @@
PendingAnimation fadeAnim = new PendingAnimation(300);
fadeAnim.setViewAlpha(mFakeIconView, 0, ACCEL);
if (onEndRunnable != null) {
- fadeAnim.addListener(AnimationSuccessListener.forRunnable(onEndRunnable));
+ fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
}
AnimatorSet animset = fadeAnim.buildAnim();
- rectAnim.addAnimatorListener(AnimationSuccessListener.forRunnable(animset::start));
+ rectAnim.addAnimatorListener(AnimatorListeners.forSuccessCallback(animset::start));
mRunningWindowAnim = RunningWindowAnim.wrap(rectAnim);
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 6f82f85..1128a7c 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -37,9 +37,8 @@
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.views.ClipIconView;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
@@ -129,13 +128,6 @@
return R.drawable.default_sandbox_app_previous_task_thumbnail;
}
- @Nullable
- public View getMockLauncherView() {
- InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext);
-
- return new SandboxLauncherRenderer(mContext, dp, true).getRenderedView();
- }
-
@DrawableRes
public int getMockAppIconResId() {
return R.drawable.default_sandbox_app_icon;
@@ -147,7 +139,7 @@
}
void fadeTaskViewAndRun(Runnable r) {
- mFakeTaskView.animate().alpha(0).setListener(AnimationSuccessListener.forRunnable(r));
+ mFakeTaskView.animate().alpha(0).setListener(AnimatorListeners.forSuccessCallback(r));
}
@StringRes
@@ -356,8 +348,8 @@
mContext, getMockLauncherResId()));
mFakeTaskView.setBackground(AppCompatResources.getDrawable(
mContext, getMockAppTaskThumbnailResId()));
- mFakeTaskView.animate().alpha(1).setListener(AnimationSuccessListener.forRunnable(
- () -> mFakeTaskView.animate().cancel()));
+ mFakeTaskView.animate().alpha(1).setListener(
+ AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel()));
mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable(
mContext, getMockPreviousAppTaskThumbnailResId()));
mFakeIconView.setBackground(AppCompatResources.getDrawable(
diff --git a/quickstep/src/com/android/quickstep/util/AssistContentRequester.java b/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
index 3730284..71c6382 100644
--- a/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
+++ b/quickstep/src/com/android/quickstep/util/AssistContentRequester.java
@@ -28,6 +28,10 @@
import com.android.launcher3.util.Executors;
+import java.lang.ref.WeakReference;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
import java.util.concurrent.Executor;
/**
@@ -51,6 +55,10 @@
private final String mPackageName;
private final Executor mCallbackExecutor;
+ // If system loses the callback, our internal cache of original callback will also get cleared.
+ private final Map<Object, Callback> mPendingCallbacks =
+ Collections.synchronizedMap(new WeakHashMap<>());
+
public AssistContentRequester(Context context) {
mActivityTaskManager = ActivityTaskManager.getService();
mPackageName = context.getApplicationContext().getPackageName();
@@ -66,20 +74,28 @@
public void requestAssistContent(int taskId, Callback callback) {
try {
mActivityTaskManager.requestAssistDataForTask(
- new AssistDataReceiver(callback, mCallbackExecutor), taskId, mPackageName);
+ new AssistDataReceiver(callback, this), taskId, mPackageName);
} catch (RemoteException e) {
Log.e(TAG, "Requesting assist content failed for task: " + taskId, e);
}
}
+ private void executeOnMainExecutor(Runnable callback) {
+ mCallbackExecutor.execute(callback);
+ }
+
private static final class AssistDataReceiver extends IAssistDataReceiver.Stub {
- private final Executor mExecutor;
- private final Callback mCallback;
+ // The AssistDataReceiver binder callback object is passed to a system server, that may
+ // keep hold of it for longer than the lifetime of the AssistContentRequester object,
+ // potentially causing a memory leak. In the callback passed to the system server, only
+ // keep a weak reference to the parent object and lookup its callback if it still exists.
+ private final WeakReference<AssistContentRequester> mParentRef;
+ private final Object mCallbackKey = new Object();
- AssistDataReceiver(Callback callback, Executor callbackExecutor) {
- mCallback = callback;
- mExecutor = callbackExecutor;
+ AssistDataReceiver(Callback callback, AssistContentRequester parent) {
+ parent.mPendingCallbacks.put(mCallbackKey, callback);
+ mParentRef = new WeakReference<>(parent);
}
@Override
@@ -94,7 +110,18 @@
return;
}
- mExecutor.execute(() -> mCallback.onAssistContentAvailable(content));
+ AssistContentRequester requester = mParentRef.get();
+ if (requester != null) {
+ Callback callback = requester.mPendingCallbacks.get(mCallbackKey);
+ if (callback != null) {
+ requester.executeOnMainExecutor(
+ () -> callback.onAssistContentAvailable(content));
+ } else {
+ Log.d(TAG, "Callback received after calling UI was disposed of");
+ }
+ } else {
+ Log.d(TAG, "Callback received after Requester was collected");
+ }
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
index c527be3..60c7add 100644
--- a/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
+++ b/quickstep/src/com/android/quickstep/util/NavigationModeFeatureFlag.java
@@ -20,8 +20,6 @@
import android.content.Context;
-import com.android.quickstep.OverviewComponentObserver;
-import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.SysUINavigationMode;
import java.util.function.Predicate;
@@ -37,7 +35,6 @@
private final Supplier<Boolean> mBasePredicate;
private final Predicate<SysUINavigationMode.Mode> mModePredicate;
private boolean mSupported;
- private OverviewComponentObserver mObserver;
private NavigationModeFeatureFlag(Supplier<Boolean> basePredicate,
Predicate<SysUINavigationMode.Mode> modePredicate) {
@@ -46,17 +43,12 @@
}
public boolean get() {
- return mBasePredicate.get() && mSupported && mObserver != null
- && mObserver.isHomeAndOverviewSame();
+ return mBasePredicate.get() && mSupported;
}
public void initialize(Context context) {
onNavigationModeChanged(SysUINavigationMode.INSTANCE.get(context).getMode());
SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
-
- // Temporary solution to disable live tile for the fallback launcher
- RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(context);
- mObserver = new OverviewComponentObserver(context, rads);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
index 42be9bb..10b7662 100644
--- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
+++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
@@ -17,44 +17,26 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.clampToProgress;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.util.Log;
-import android.view.animation.Interpolator;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.quickstep.views.RecentsView;
/**
* Runs an animation from overview to home. Currently, this animation is just a wrapper around the
- * normal state transition, in order to keep RecentsView at the same scale and translationY that
- * it started out at as it translates offscreen. It also scrolls RecentsView to page 0 and may play
- * a {@link StaggeredWorkspaceAnim} if we're starting from an upward fling.
+ * normal state transition and may play a {@link StaggeredWorkspaceAnim} if we're starting from an
+ * upward fling.
*/
public class OverviewToHomeAnim {
private static final String TAG = "OverviewToHomeAnim";
- // Constants to specify how to scroll RecentsView to the default page if it's not already there.
- private static final int DEFAULT_PAGE = 0;
- private static final int PER_PAGE_SCROLL_DURATION = 150;
- private static final int MAX_PAGE_SCROLL_DURATION = 750;
-
private final Launcher mLauncher;
private final Runnable mOnReachedHome;
@@ -95,24 +77,8 @@
mIsHomeStaggeredAnimFinished = true;
}
- RecentsView recentsView = mLauncher.getOverviewPanel();
- int numPagesToScroll = recentsView.getNextPage() - DEFAULT_PAGE;
- int scrollDuration = Math.min(MAX_PAGE_SCROLL_DURATION,
- numPagesToScroll * PER_PAGE_SCROLL_DURATION);
- int duration = Math.max(scrollDuration, startState.getTransitionDuration(mLauncher));
-
- StateAnimationConfig config = new UseFirstInterpolatorStateAnimConfig();
- config.duration = duration;
- boolean isLayoutNaturalToLauncher = recentsView.getPagedOrientationHandler()
- .isLayoutNaturalToLauncher();
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, isLayoutNaturalToLauncher
- ? clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f) : FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
- config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, LINEAR);
- if (!isLayoutNaturalToLauncher) {
- config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL);
- }
+ StateAnimationConfig config = new StateAnimationConfig();
+ config.duration = startState.getTransitionDuration(mLauncher);
AnimatorSet stateAnim = stateManager.createAtomicAnimation(
startState, NORMAL, config);
stateAnim.addListener(new AnimationSuccessListener() {
@@ -125,7 +91,6 @@
anim.play(stateAnim);
stateManager.setCurrentAnimation(anim, NORMAL);
anim.start();
- recentsView.snapToPage(DEFAULT_PAGE, duration);
}
private void maybeOverviewToHomeAnimComplete() {
@@ -133,17 +98,4 @@
mOnReachedHome.run();
}
}
-
- /**
- * Wrapper around StateAnimationConfig that doesn't allow interpolators to be set if they are
- * already set. This ensures they aren't overridden before being used.
- */
- private static class UseFirstInterpolatorStateAnimConfig extends StateAnimationConfig {
- @Override
- public void setInterpolator(int animId, Interpolator interpolator) {
- if (mInterpolators[animId] == null || interpolator == null) {
- super.setInterpolator(animId, interpolator);
- }
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
index ba70bf7..c1ca060 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
@@ -15,11 +15,13 @@
*/
package com.android.quickstep.util;
-import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
+import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_VERTICAL_OFFSET;
import android.animation.Animator;
import android.animation.ObjectAnimator;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+
import com.android.launcher3.anim.SpringAnimationBuilder;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StatefulActivity;
@@ -29,7 +31,7 @@
extends AtomicAnimationFactory<STATE_TYPE> {
public static final int INDEX_RECENTS_FADE_ANIM = AtomicAnimationFactory.NEXT_INDEX + 0;
- public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1;
+ public static final int INDEX_RECENTS_TRANSLATE_Y_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1;
private static final int MY_ANIM_COUNT = 2;
@@ -46,14 +48,14 @@
case INDEX_RECENTS_FADE_ANIM:
return ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
RecentsView.CONTENT_ALPHA, values);
- case INDEX_RECENTS_TRANSLATE_X_ANIM: {
+ case INDEX_RECENTS_TRANSLATE_Y_ANIM: {
RecentsView rv = mActivity.getOverviewPanel();
return new SpringAnimationBuilder(mActivity)
- .setMinimumVisibleChange(1f / rv.getPageOffsetScale())
+ .setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE)
.setDampingRatio(0.8f)
.setStiffness(250)
.setValues(values)
- .build(rv, ADJACENT_PAGE_OFFSET);
+ .build(rv, ADJACENT_PAGE_VERTICAL_OFFSET);
}
default:
return super.createStateElementAnimation(index, values);
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 188efad..e983f46 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -16,7 +16,6 @@
package com.android.quickstep.util;
-import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
@@ -31,8 +30,8 @@
import android.content.Context;
import android.content.SharedPreferences;
-import android.content.res.Resources;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.Log;
@@ -45,10 +44,10 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface;
@@ -65,7 +64,8 @@
* This class has initial default state assuming the device and foreground app have
* no ({@link Surface#ROTATION_0} rotation.
*/
-public final class RecentsOrientedState implements SharedPreferences.OnSharedPreferenceChangeListener {
+public final class RecentsOrientedState implements
+ SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "RecentsOrientedState";
private static final boolean DEBUG = false;
@@ -123,6 +123,7 @@
private int mFlags;
private int mPreviousRotation = ROTATION_0;
+ private boolean mListenersInitialized = false;
// Combined int which encodes the full state.
private int mStateId = 0;
@@ -150,19 +151,32 @@
mFlags = sizeStrategy.rotationSupportedByActivity
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
- Resources res = context.getResources();
- int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
- * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
- if (originalSmallestWidth < 600 && !mContext.getResources().getBoolean(
- R.bool.allow_rotation)) {
- mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
- }
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
mSettingsCache = SettingsCache.INSTANCE.get(mContext);
initFlags();
}
/**
+ * Sets the device profile for the current state.
+ */
+ public void setDeviceProfile(DeviceProfile deviceProfile) {
+ boolean oldMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
+ setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.allowRotation);
+ if (mListenersInitialized) {
+ boolean newMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
+ // If isMultipleOrientationSupportedByDevice is changed, init or destroy listeners
+ // accordingly.
+ if (newMultipleOrientationsSupported != oldMultipleOrientationsSupported) {
+ if (newMultipleOrientationsSupported) {
+ initMultipleOrientationListeners();
+ } else {
+ destroyMultipleOrientationListeners();
+ }
+ }
+ }
+ }
+
+ /**
* Sets the rotation for the recents activity, which could affect the appearance of task view.
* @see #update(int, int)
*/
@@ -285,14 +299,24 @@
updateHomeRotationSetting();
}
+ private void initMultipleOrientationListeners() {
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
+ }
+
+ private void destroyMultipleOrientationListeners() {
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener);
+ }
+
/**
* Initializes any system values and registers corresponding change listeners. It must be
* paired with {@link #destroyListeners()} call
*/
public void initListeners() {
+ mListenersInitialized = true;
if (isMultipleOrientationSupportedByDevice()) {
- mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
- mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
+ initMultipleOrientationListeners();
}
initFlags();
}
@@ -301,9 +325,9 @@
* Unregisters any previously registered listeners.
*/
public void destroyListeners() {
+ mListenersInitialized = false;
if (isMultipleOrientationSupportedByDevice()) {
- mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
- mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener);
+ destroyMultipleOrientationListeners();
}
setRotationWatcherEnabled(false);
}
@@ -561,11 +585,27 @@
*/
public DeviceProfile getLauncherDeviceProfile() {
InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(mContext);
- // TODO also check the natural orientation is landscape or portrait
- return (mRecentsActivityRotation == ROTATION_90
- || mRecentsActivityRotation == ROTATION_270)
- ? idp.landscapeProfile
- : idp.portraitProfile;
+ Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
+
+ int width, height;
+ if ((mRecentsActivityRotation == ROTATION_90 || mRecentsActivityRotation == ROTATION_270)) {
+ width = Math.max(currentSize.x, currentSize.y);
+ height = Math.min(currentSize.x, currentSize.y);
+ } else {
+ width = Math.min(currentSize.x, currentSize.y);
+ height = Math.max(currentSize.x, currentSize.y);
+ }
+
+ DeviceProfile bestMatch = idp.supportedProfiles.get(0);
+ float minDiff = Float.MAX_VALUE;
+ for (DeviceProfile profile : idp.supportedProfiles) {
+ float diff = Math.abs(profile.widthPx - width) + Math.abs(profile.heightPx - height);
+ if (diff < minDiff) {
+ minDiff = diff;
+ bestMatch = profile;
+ }
+ }
+ return bestMatch;
}
private static String nameAndAddress(Object obj) {
diff --git a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
index 88cc650..483a1c6 100644
--- a/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
+++ b/quickstep/src/com/android/quickstep/util/SplitScreenBounds.java
@@ -20,10 +20,7 @@
import android.annotation.TargetApi;
import android.content.Context;
-import android.graphics.Insets;
-import android.graphics.Rect;
import android.os.Build;
-import android.view.WindowInsets.Type;
import android.view.WindowManager;
import android.view.WindowMetrics;
@@ -73,10 +70,8 @@
*/
private static WindowBounds createDefaultWindowBounds(Context context) {
WindowMetrics wm = context.getSystemService(WindowManager.class).getMaximumWindowMetrics();
- Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
+ WindowBounds bounds = WindowBounds.fromWindowMetrics(wm);
- WindowBounds bounds = new WindowBounds(wm.getBounds(),
- new Rect(insets.left, insets.top, insets.right, insets.bottom));
int rotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
int halfDividerSize = context.getResources()
.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 01d51f8..3d33e57 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -25,6 +25,7 @@
import android.animation.AnimatorSet;
import android.app.ActivityOptions;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -64,6 +65,7 @@
private final SystemUiProxy mSystemUiProxy;
private TaskView mInitialTaskView;
private SplitPositionOption mInitialPosition;
+ private Rect mInitialBounds;
private final Handler mHandler;
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
@@ -74,9 +76,11 @@
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption) {
+ public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
+ Rect initialBounds) {
mInitialTaskView = taskView;
mInitialPosition = positionOption;
+ mInitialBounds = initialBounds;
}
/**
@@ -220,9 +224,14 @@
public void resetState() {
mInitialTaskView = null;
mInitialPosition = null;
+ mInitialBounds = null;
}
public boolean isSplitSelectActive() {
return mInitialTaskView != null;
}
+
+ public Rect getInitialBounds() {
+ return mInitialBounds;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index ab95138..0ea1fca 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -89,8 +89,7 @@
int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);
// Add animation for all the visible workspace pages
- workspace.getVisiblePages()
- .forEach(page -> addAnimationForPage((CellLayout) page, totalRows));
+ workspace.forEachVisiblePage(page -> addAnimationForPage((CellLayout) page, totalRows));
boolean workspaceClipChildren = workspace.getClipChildren();
boolean workspaceClipToPadding = workspace.getClipToPadding();
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index a1240e0..b5570a7 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -89,6 +89,7 @@
* different from the appBounds if user has swiped a certain distance and
* Launcher has performed transform on the leash.
* @param destinationBounds Bounds of the destination this animator ends to
+ * @param cornerRadius Corner radius in pixel value for PiP window
*/
public SwipePipToHomeAnimator(int taskId,
@NonNull ComponentName componentName,
@@ -97,6 +98,7 @@
@NonNull Rect appBounds,
@NonNull Rect startBounds,
@NonNull Rect destinationBounds,
+ int cornerRadius,
@NonNull View view) {
mTaskId = taskId;
mComponentName = componentName;
@@ -106,7 +108,7 @@
mDestinationBounds.set(destinationBounds);
mDestinationBoundsTransformed.set(mDestinationBounds);
mDestinationBoundsAnimation.set(mDestinationBounds);
- mSurfaceTransactionHelper = new PipSurfaceTransactionHelper();
+ mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius);
if (sourceRectHint == null) {
mSourceHintRectInsets = null;
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index e63f8bb..b15bbf3 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -36,6 +36,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
@@ -95,7 +96,9 @@
mContext = context;
mSizeStrategy = sizeStrategy;
- mOrientationState = new RecentsOrientedState(context, sizeStrategy, i -> { });
+ // TODO(b/187074722): Don't create this per-TaskViewSimulator
+ mOrientationState = TraceHelper.allowIpcs("",
+ () -> new RecentsOrientedState(context, sizeStrategy, i -> { }));
mOrientationState.setGestureActive(true);
mCurrentFullscreenParams = new FullscreenDrawParams(context);
mOrientationStateId = mOrientationState.getStateId();
@@ -109,6 +112,7 @@
public void setDp(DeviceProfile dp) {
mDp = dp;
mLayoutValid = false;
+ mOrientationState.setDeviceProfile(dp);
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index f74aa55..9ea2369 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -100,8 +100,8 @@
/** Restores the drawables to the source view. */
void finish() {
if (isUninitialized()) return;
- mSourceView.setForeground(mOriginalForeground);
- mSourceView.setBackground(mOriginalBackground);
+ if (mOriginalForeground != null) mSourceView.setForeground(mOriginalForeground);
+ if (mOriginalBackground != null) mSourceView.setBackground(mOriginalBackground);
}
void recycle() {
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index d23884c..ed54f10 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -20,13 +20,14 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Matrix;
-import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
+import android.util.Size;
import android.view.GhostView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
import com.android.launcher3.Launcher;
@@ -39,7 +40,8 @@
/** A view that mimics an App Widget through a launch animation. */
@TargetApi(Build.VERSION_CODES.S)
-public class FloatingWidgetView extends FrameLayout implements AnimatorListener {
+public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
+ OnGlobalLayoutListener {
private static final Matrix sTmpMatrix = new Matrix();
private final Launcher mLauncher;
@@ -54,6 +56,7 @@
private Runnable mEndRunnable;
private Runnable mFastFinishRunnable;
+ private Runnable mOnTargetChangeRunnable;
public FloatingWidgetView(Context context) {
this(context, null);
@@ -93,6 +96,32 @@
public void onAnimationRepeat(Animator animator) {
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnGlobalLayoutListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ super.onDetachedFromWindow();
+ }
+
+ @Override
+ public void onGlobalLayout() {
+ if (isUninitialized()) return;
+ positionViews();
+ if (mOnTargetChangeRunnable != null) {
+ mOnTargetChangeRunnable.run();
+ }
+ }
+
+ /** Sets a runnable that is called on global layout change. */
+ public void setOnTargetChangeListener(Runnable onTargetChangeListener) {
+ mOnTargetChangeRunnable = onTargetChangeListener;
+ }
+
/** Sets a runnable that is called after a call to {@link #fastFinish()}. */
public void setFastFinishRunnable(Runnable runnable) {
mFastFinishRunnable = runnable;
@@ -113,7 +142,7 @@
}
private void init(DragLayer dragLayer, LauncherAppWidgetHostView originalView,
- RectF widgetBackgroundPosition, Rect windowTargetBounds, float windowCornerRadius) {
+ RectF widgetBackgroundPosition, Size windowSize, float windowCornerRadius) {
mAppWidgetView = originalView;
mAppWidgetView.beginDeferringUpdates();
mBackgroundPosition = widgetBackgroundPosition;
@@ -128,7 +157,7 @@
getRelativePosition(mAppWidgetBackgroundView, mAppWidgetView, mBackgroundOffset);
mBackgroundView.init(mAppWidgetView, mAppWidgetBackgroundView, windowCornerRadius);
// Layout call before GhostView creation so that the overlaid view isn't clipped
- layout(0, 0, windowTargetBounds.width(), windowTargetBounds.height());
+ layout(0, 0, windowSize.getWidth(), windowSize.getHeight());
mForegroundOverlayView = GhostView.addGhost(mAppWidgetView, this);
positionViews();
@@ -205,6 +234,7 @@
private void recycle() {
mEndRunnable = null;
mFastFinishRunnable = null;
+ mOnTargetChangeRunnable = null;
mBackgroundPosition = null;
mListenerView.setListener(null);
mAppWidgetView = null;
@@ -219,19 +249,19 @@
*
* @param widgetBackgroundPosition a {@link RectF} that will be updated with the widget's
* background bounds
- * @param windowTargetBounds the bounds of the window when launched
+ * @param windowSize the size of the window when launched
* @param windowCornerRadius the corner radius of the window
*/
public static FloatingWidgetView getFloatingWidgetView(Launcher launcher,
LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition,
- Rect windowTargetBounds, float windowCornerRadius) {
+ Size windowSize, float windowCornerRadius) {
final DragLayer dragLayer = launcher.getDragLayer();
ViewGroup parent = (ViewGroup) dragLayer.getParent();
FloatingWidgetView floatingView =
launcher.getViewCache().getView(R.layout.floating_widget_view, launcher, parent);
floatingView.recycle();
- floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowTargetBounds,
+ floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowSize,
windowCornerRadius);
parent.addView(floatingView);
return floatingView;
@@ -240,7 +270,7 @@
private static void getRelativePosition(View descendant, View ancestor, RectF position) {
float[] points = new float[]{0, 0, descendant.getWidth(), descendant.getHeight()};
Utilities.getDescendantCoordRelativeToAncestor(descendant, ancestor, points,
- false /* includeRootScroll */);
+ false /* includeRootScroll */, true /* ignoreTransform */);
position.set(
Math.min(points[0], points[2]),
Math.min(points[1], points[3]),
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index f5a8ff8..65956d5 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
-import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
import android.annotation.TargetApi;
import android.content.Context;
@@ -39,7 +38,6 @@
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.LauncherActivityInterface;
-import com.android.quickstep.util.OverviewToHomeAnim;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.RecentsExtraCard;
@@ -90,15 +88,7 @@
@Override
public void startHome() {
- Runnable onReachedHome = () -> mActivity.getStateManager().goToState(NORMAL, false);
- OverviewToHomeAnim overviewToHomeAnim = new OverviewToHomeAnim(mActivity, onReachedHome);
- if (LIVE_TILE.get()) {
- switchToScreenshot(null,
- () -> finishRecentsAnimation(true /* toRecents */,
- () -> overviewToHomeAnim.animateWithVelocity(0)));
- } else {
- overviewToHomeAnim.animateWithVelocity(0);
- }
+ mActivity.getStateManager().goToState(NORMAL);
}
@Override
@@ -245,8 +235,8 @@
if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
// We want to keep the tasks translations in this temporary state
// after resetting the rest above
- setTaskViewsResistanceTranslation(mTaskViewsSecondaryTranslation);
- setTaskViewsPrimaryTranslation(mTaskViewsPrimaryTranslation);
+ setTaskViewsPrimarySplitTranslation(mTaskViewsPrimarySplitTranslation);
+ setTaskViewsSecondarySplitTranslation(mTaskViewsSecondarySplitTranslation);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index c9e7a73..a36c9af 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
@@ -64,7 +63,9 @@
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
@@ -99,6 +100,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.core.graphics.ColorUtils;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
@@ -109,6 +111,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringProperty;
@@ -118,7 +121,6 @@
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource;
@@ -171,8 +173,7 @@
public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>,
STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable,
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
- InvariantDeviceProfile.OnIDPChangeListener, TaskVisualsChangeListener,
- SplitScreenBounds.OnChangeListener {
+ TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener {
public static final FloatProperty<RecentsView> CONTENT_ALPHA =
new FloatProperty<RecentsView>("contentAlpha") {
@@ -213,19 +214,53 @@
}
};
- public static final FloatProperty<RecentsView> ADJACENT_PAGE_OFFSET =
- new FloatProperty<RecentsView>("adjacentPageOffset") {
+ public static final FloatProperty<RecentsView> ADJACENT_PAGE_HORIZONTAL_OFFSET =
+ new FloatProperty<RecentsView>("adjacentPageHorizontalOffset") {
@Override
public void setValue(RecentsView recentsView, float v) {
- if (recentsView.mAdjacentPageOffset != v) {
- recentsView.mAdjacentPageOffset = v;
+ if (recentsView.mAdjacentPageHorizontalOffset != v) {
+ recentsView.mAdjacentPageHorizontalOffset = v;
recentsView.updatePageOffsets();
}
}
@Override
public Float get(RecentsView recentsView) {
- return recentsView.mAdjacentPageOffset;
+ return recentsView.mAdjacentPageHorizontalOffset;
+ }
+ };
+
+ public static final FloatProperty<RecentsView> ADJACENT_PAGE_VERTICAL_OFFSET =
+ new FloatProperty<RecentsView>("adjacentPageVerticalOffset") {
+ @Override
+ public void setValue(RecentsView recentsView, float v) {
+ if (recentsView.mAdjacentPageVerticalOffset != v) {
+ recentsView.mAdjacentPageVerticalOffset = v;
+ recentsView.updateVerticalPageOffsets();
+ }
+ }
+
+ @Override
+ public Float get(RecentsView recentsView) {
+ return recentsView.mAdjacentPageVerticalOffset;
+ }
+ };
+
+ /**
+ * Can be used to tint the color of the RecentsView to simulate a scrim that can views
+ * excluded from. Really should be a proper scrim.
+ * TODO(b/187528071): Remove this and replace with a real scrim.
+ */
+ private static final FloatProperty<RecentsView> COLOR_TINT =
+ new FloatProperty<RecentsView>("colorTint") {
+ @Override
+ public void setValue(RecentsView recentsView, float v) {
+ recentsView.setColorTint(v);
+ }
+
+ @Override
+ public Float get(RecentsView recentsView) {
+ return recentsView.getColorTint();
}
};
@@ -240,6 +275,8 @@
@Override
public void setValue(RecentsView recentsView, float v) {
recentsView.setTaskViewsResistanceTranslation(v);
+ recentsView.mLastComputedTaskBottomPushOutDistance = null;
+ recentsView.updateVerticalPageOffsets();
}
@Override
@@ -254,16 +291,29 @@
* more specific, we'd want to create a similar FloatProperty just for a TaskView's
* offsetX/Y property
*/
- public static final FloatProperty<RecentsView> TASK_PRIMARY_TRANSLATION =
- new FloatProperty<RecentsView>("taskPrimaryTranslation") {
+ public static final FloatProperty<RecentsView> TASK_PRIMARY_SPLIT_TRANSLATION =
+ new FloatProperty<RecentsView>("taskPrimarySplitTranslation") {
@Override
public void setValue(RecentsView recentsView, float v) {
- recentsView.setTaskViewsPrimaryTranslation(v);
+ recentsView.setTaskViewsPrimarySplitTranslation(v);
}
@Override
public Float get(RecentsView recentsView) {
- return recentsView.mTaskViewsPrimaryTranslation;
+ return recentsView.mTaskViewsPrimarySplitTranslation;
+ }
+ };
+
+ public static final FloatProperty<RecentsView> TASK_SECONDARY_SPLIT_TRANSLATION =
+ new FloatProperty<RecentsView>("taskSecondarySplitTranslation") {
+ @Override
+ public void setValue(RecentsView recentsView, float v) {
+ recentsView.setTaskViewsSecondarySplitTranslation(v);
+ }
+
+ @Override
+ public Float get(RecentsView recentsView) {
+ return recentsView.mTaskViewsSecondarySplitTranslation;
}
};
@@ -276,10 +326,11 @@
view.setScaleY(scale);
view.mLastComputedTaskStartPushOutDistance = null;
view.mLastComputedTaskEndPushOutDistance = null;
+ view.mLastComputedTaskBottomPushOutDistance = null;
view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
- view.updatePageOffsets();
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
- view.setTaskViewsPrimaryTranslation(view.mTaskViewsPrimaryTranslation);
+ view.updatePageOffsets();
+ view.updateVerticalPageOffsets();
}
@Override
@@ -318,6 +369,7 @@
// How much a task that is directly offscreen will be pushed out due to RecentsView scale/pivot.
protected Float mLastComputedTaskStartPushOutDistance = null;
protected Float mLastComputedTaskEndPushOutDistance = null;
+ protected Float mLastComputedTaskBottomPushOutDistance = null;
protected boolean mEnableDrawingLiveTile = false;
protected final Rect mTempRect = new Rect();
protected final RectF mTempRectF = new RectF();
@@ -361,9 +413,11 @@
private boolean mOverviewGridEnabled;
private boolean mOverviewFullscreenEnabled;
- private float mAdjacentPageOffset = 0;
+ private float mAdjacentPageHorizontalOffset = 0;
+ private float mAdjacentPageVerticalOffset = 0;
protected float mTaskViewsSecondaryTranslation = 0;
- protected float mTaskViewsPrimaryTranslation = 0;
+ protected float mTaskViewsPrimarySplitTranslation = 0;
+ protected float mTaskViewsSecondarySplitTranslation = 0;
// Progress from 0 to 1 where 0 is a carousel and 1 is a 2 row grid.
private float mGridProgress = 0;
private final IntSet mTopRowIdSet = new IntSet();
@@ -371,6 +425,10 @@
// The GestureEndTarget that is still in progress.
protected GestureState.GestureEndTarget mCurrentGestureEndTarget;
+ // TODO(b/187528071): Remove these and replace with a real scrim.
+ private float mColorTint;
+ private final int mTintingColor;
+
private int mOverScrollShift = 0;
/**
@@ -436,6 +494,7 @@
private final PinnedStackAnimationListener mIPipAnimationListener =
new PinnedStackAnimationListener();
+ private int mPipCornerRadius;
// Used to keep track of the last requested task list id, so that we do not request to load the
// tasks again if we have already requested it and the task list has not changed
@@ -583,6 +642,8 @@
mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
mLiveTileTaskViewSimulator.setDrawsBelowRecents(true);
+
+ mTintingColor = getForegroundScrimDimColor(context);
}
public OverScroller getScroller() {
@@ -609,28 +670,9 @@
// Draw overscroll
if (mAllowOverScroll && (!mEdgeGlowRight.isFinished() || !mEdgeGlowLeft.isFinished())) {
final int restoreCount = canvas.save();
- final int width = getWidth();
- final int height = getHeight();
- int primarySize = mOrientationHandler.getPrimaryValue(width, height);
- int secondarySize = mOrientationHandler.getSecondaryValue(width, height);
- float effectiveShift = 0;
- if (!mEdgeGlowLeft.isFinished()) {
- mEdgeGlowLeft.setSize(secondarySize, primarySize);
- if (((TranslateEdgeEffect) mEdgeGlowLeft).getTranslationShift(mTempFloat)) {
- effectiveShift = mTempFloat[0];
- postInvalidateOnAnimation();
- }
- }
- if (!mEdgeGlowRight.isFinished()) {
- mEdgeGlowRight.setSize(secondarySize, primarySize);
- if (((TranslateEdgeEffect) mEdgeGlowRight).getTranslationShift(mTempFloat)) {
- effectiveShift -= mTempFloat[0];
- postInvalidateOnAnimation();
- }
- }
-
- int scroll = OverScroll.dampedScroll(effectiveShift * primarySize, primarySize);
+ int primarySize = mOrientationHandler.getPrimaryValue(getWidth(), getHeight());
+ int scroll = OverScroll.dampedScroll(getUndampedOverScrollShift(), primarySize);
mOrientationHandler.set(canvas, CANVAS_TRANSLATE, scroll);
if (mOverScrollShift != scroll) {
@@ -652,6 +694,31 @@
}
}
+ private float getUndampedOverScrollShift() {
+ final int width = getWidth();
+ final int height = getHeight();
+ int primarySize = mOrientationHandler.getPrimaryValue(width, height);
+ int secondarySize = mOrientationHandler.getSecondaryValue(width, height);
+
+ float effectiveShift = 0;
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.setSize(secondarySize, primarySize);
+ if (((TranslateEdgeEffect) mEdgeGlowLeft).getTranslationShift(mTempFloat)) {
+ effectiveShift = mTempFloat[0];
+ postInvalidateOnAnimation();
+ }
+ }
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.setSize(secondarySize, primarySize);
+ if (((TranslateEdgeEffect) mEdgeGlowRight).getTranslationShift(mTempFloat)) {
+ effectiveShift -= mTempFloat[0];
+ postInvalidateOnAnimation();
+ }
+ }
+
+ return effectiveShift * primarySize;
+ }
+
/**
* Returns the view shift due to overscroll
*/
@@ -705,16 +772,6 @@
updateTaskStackListenerState();
}
- @Override
- public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
- if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) == 0) {
- return;
- }
- mModel.getIconCache().clear();
- unloadVisibleTaskData(TaskView.FLAG_UPDATE_ICON);
- loadVisibleTaskData(TaskView.FLAG_UPDATE_ICON);
- }
-
public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) {
mActionsView = actionsView;
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
@@ -739,8 +796,7 @@
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier);
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
- mIdp.addOnChangeListener(this);
- mIPipAnimationListener.setActivity(mActivity);
+ mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
mIPipAnimationListener);
mOrientationState.initListeners();
@@ -758,10 +814,9 @@
mSyncTransactionApplier = null;
mLiveTileParams.setSyncTransactionApplier(null);
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
- mIdp.removeOnChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
SplitScreenBounds.INSTANCE.removeOnChangeListener(this);
- mIPipAnimationListener.setActivity(null);
+ mIPipAnimationListener.setActivityAndRecentsView(null, null);
mOrientationState.destroyListeners();
mTaskOverlayFactory.removeListeners();
}
@@ -1033,12 +1088,6 @@
}
protected void applyLoadPlan(ArrayList<Task> tasks) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "applyLoadPlan: taskCount=" + tasks.size());
- for (Task t : tasks) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "\t" + t);
- }
- }
if (mPendingAnimation != null) {
mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks));
return;
@@ -1100,11 +1149,6 @@
resetTaskVisuals();
onTaskStackUpdated();
updateEnabledOverlays();
-
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "applyLoadPlan: taskViewCount="
- + getTaskViewCount());
- }
}
private boolean isModal() {
@@ -1125,12 +1169,6 @@
}
public int getTaskViewCount() {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getTaskViewCount:"
- + " numChildren=" + getChildCount()
- + " start=" + mTaskViewStartIndex
- + " clearAll=" + indexOfChild(mClearAllButton));
- }
int taskViewCount = getChildCount() - mTaskViewStartIndex;
if (indexOfChild(mClearAllButton) != -1) {
taskViewCount--;
@@ -1175,6 +1213,8 @@
// Update the set of visible task's data
loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
setTaskModalness(0);
+ updateVerticalPageOffsets();
+ setColorTint(0);
}
public void setFullscreenProgress(float fullscreenProgress) {
@@ -1204,13 +1244,51 @@
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
- resetPaddingFromTaskSize();
+
+ // Update DeviceProfile dependant state.
DeviceProfile dp = mActivity.getDeviceProfile();
+ setOverviewGridEnabled(
+ mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
+
+ // Propagate DeviceProfile change event.
mLiveTileTaskViewSimulator.setDp(dp);
mActionsView.setDp(dp);
+ mOrientationState.setDeviceProfile(dp);
+
+ // Update RecentsView adn TaskView's DeviceProfile dependent layout.
+ updateOrientationHandler();
}
- private void resetPaddingFromTaskSize() {
+ private void updateOrientationHandler() {
+ // Handle orientation changes.
+ mOrientationHandler = mOrientationState.getOrientationHandler();
+ mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
+ setLayoutDirection(mIsRtl
+ ? View.LAYOUT_DIRECTION_RTL
+ : View.LAYOUT_DIRECTION_LTR);
+ mClearAllButton.setLayoutDirection(mIsRtl
+ ? View.LAYOUT_DIRECTION_LTR
+ : View.LAYOUT_DIRECTION_RTL);
+ mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
+ mActivity.getDragLayer().recreateControllers();
+ boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
+ || mOrientationState.getRecentsActivityRotation() != ROTATION_0;
+ mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
+ !mOrientationState.canRecentsActivityRotate() && isInLandscape);
+
+ // Update TaskView's DeviceProfile dependent layout.
+ updateChildTaskOrientations();
+
+ // Recalculate DeviceProfile dependent layout.
+ updateSizeAndPadding();
+
+ requestLayout();
+ // Reapply the current page to update page scrolls.
+ setCurrentPage(mCurrentPage);
+ }
+
+ // Update task size and padding that are dependent on DeviceProfile and insets.
+ private void updateSizeAndPadding() {
DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(mTempRect);
mTaskWidth = mTempRect.width();
@@ -1594,7 +1672,7 @@
return;
}
AnimatorSet pa = setRecentsChangedOrientation(true);
- pa.addListener(AnimationSuccessListener.forRunnable(() -> {
+ pa.addListener(AnimatorListeners.forSuccessCallback(() -> {
setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
mActivity.getDragLayer().recreateControllers();
updateChildTaskOrientations();
@@ -1631,13 +1709,21 @@
/**
* Called when a gesture from an app has finished, and an end target has been determined.
*/
- public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
+ public void onPrepareGestureEndAnimation(
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ if (mSizeStrategy.stateFromGestureEndTarget(endTarget)
+ .displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
+ if (animatorSet == null) {
+ setGridProgress(1);
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
+ }
+ }
mCurrentGestureEndTarget = endTarget;
if (endTarget == GestureState.GestureEndTarget.NEW_TASK
|| endTarget == GestureState.GestureEndTarget.LAST_TASK) {
// When switching to tasks in quick switch, ensures the snapped page's scroll maintain
- // invariant between quick switch and overview grid, to ensure a smooth animation
- // transition.
+ // invariant between quick switch and overview, to ensure a smooth animation transition.
updateGridProperties();
}
}
@@ -1839,15 +1925,28 @@
final int boxLength = Math.max(mLastComputedGridTaskSize.width(),
mLastComputedGridTaskSize.height());
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
- float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
- float taskGridVerticalDiff = mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
+
+ /*
+ * taskGridVerticalDiff is used to position the top of a task in the top row of the grid
+ * heightOffset is the vertical space one grid task takes + space between top and
+ * bottom row
+ * Summed together they provide the top position for bottom row of grid tasks
+ */
+ final float taskGridVerticalDiff =
+ mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
+ final float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
int topRowWidth = 0;
int bottomRowWidth = 0;
float topAccumulatedTranslationX = 0;
float bottomAccumulatedTranslationX = 0;
+
+ // Contains whether the child index is in top or bottom of grid (for non-focused task)
+ // Different from mTopRowIdSet, which contains the taskId of what task is in top row
IntSet topSet = new IntSet();
IntSet bottomSet = new IntSet();
+
+ // Horizontal grid translation for each task
float[] gridTranslations = new float[taskCount];
int focusedTaskIndex = Integer.MAX_VALUE;
@@ -1901,7 +2000,6 @@
boolean isTopRow = isTaskDismissal ? mTopRowIdSet.contains(taskId)
: topRowWidth <= bottomRowWidth;
if (isTopRow) {
- gridTranslations[i] += topAccumulatedTranslationX;
topRowWidth += taskWidthAndSpacing;
topSet.add(i);
mTopRowIdSet.add(taskId);
@@ -1917,11 +2015,10 @@
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
- float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += gridTranslationX;
- topAccumulatedTranslationX += gridTranslationX;
+ float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
+ gridTranslations[i] += topAccumulatedTranslationX + currentTaskTranslationX;
+ topAccumulatedTranslationX += currentTaskTranslationX;
} else {
- gridTranslations[i] += bottomAccumulatedTranslationX;
bottomRowWidth += taskWidthAndSpacing;
bottomSet.add(i);
@@ -1937,9 +2034,9 @@
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
- float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += gridTranslationX;
- bottomAccumulatedTranslationX += gridTranslationX;
+ float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
+ gridTranslations[i] += bottomAccumulatedTranslationX + currentTaskTranslationX;
+ bottomAccumulatedTranslationX += currentTaskTranslationX;
}
if (taskView == snappedTaskView) {
snappedTaskRowWidth = isTopRow ? topRowWidth : bottomRowWidth;
@@ -2130,18 +2227,43 @@
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
// alpha is set to 0 so that it can be recycled in the view pool properly
anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2);
- FloatProperty<TaskView> secondaryViewTranslate =
- taskView.getSecondaryDissmissTranslationProperty();
- int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
- int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
ResourceProvider rp = DynamicResource.provider(mActivity);
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
.setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
+ FloatProperty<TaskView> dismissingTaskViewTranslate =
+ taskView.getSecondaryDissmissTranslationProperty();;
+ // TODO(b/186800707) translate entire grid size distance
+ int translateDistance = mOrientationHandler.getSecondaryDimension(taskView);
+ int positiveNegativeFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ if (splitController.isSplitSelectActive()) {
+ // Have the task translate towards whatever side was just pinned
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitController
+ .getActiveSplitPositionOption(), mActivity.getDeviceProfile());
+ switch (dir) {
+ case PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
- anim.add(ObjectAnimator.ofFloat(taskView, secondaryViewTranslate,
- verticalFactor * secondaryTaskDimension).setDuration(duration), LINEAR, sp);
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = 1;
+ break;
+
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
+ default:
+ throw new IllegalStateException("Invalid split task translation: " + dir);
+ }
+ }
+ anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate,
+ positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp);
if (LIVE_TILE.get() && taskView.isRunningTask()) {
anim.addOnFrameCallback(() -> {
@@ -2206,18 +2328,6 @@
}
}
- // Additional offset for fake landscape, if the pinning happens to the right or
- // left, we need to scroll all the tasks away from the direction of the splaceholder
- // view
- if (isSplitSelectionActive()) {
- int splitPosition = getSplitPlaceholder().getSplitController()
- .getActiveSplitPositionOption().mStagePosition;
- int direction = mOrientationHandler
- .getSplitTranslationDirectionFactor(splitPosition);
- int splitOffset = mOrientationHandler.getSplitAnimationTranslation(
- mSplitPlaceholderView.getHeight(), mActivity.getDeviceProfile());
- offset += direction * splitOffset;
- }
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
FloatProperty translationProperty = child instanceof TaskView
@@ -2249,7 +2359,8 @@
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
- if (LIVE_TILE.get() && taskView.isRunningTask() && success) {
+ if (LIVE_TILE.get() && mEnableDrawingLiveTile && taskView.isRunningTask()
+ && success) {
finishRecentsAnimation(true /* toHome */, () -> onEnd(success));
} else {
onEnd(success);
@@ -2347,7 +2458,7 @@
return true;
}
- protected void runDismissAnimation(PendingAnimation pendingAnim) {
+ private void runDismissAnimation(PendingAnimation pendingAnim) {
AnimatorPlaybackController controller = pendingAnim.createPlaybackController();
controller.dispatchOnStart();
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
@@ -2493,28 +2604,6 @@
}
}
- private void updateOrientationHandler() {
- mOrientationHandler = mOrientationState.getOrientationHandler();
- mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
- setLayoutDirection(mIsRtl
- ? View.LAYOUT_DIRECTION_RTL
- : View.LAYOUT_DIRECTION_LTR);
- mClearAllButton.setLayoutDirection(mIsRtl
- ? View.LAYOUT_DIRECTION_LTR
- : View.LAYOUT_DIRECTION_RTL);
- mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
- mActivity.getDragLayer().recreateControllers();
- boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
- || mOrientationState.getRecentsActivityRotation() != ROTATION_0;
- mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
- !mOrientationState.canRecentsActivityRotate() && isInLandscape);
- updateChildTaskOrientations();
- resetPaddingFromTaskSize();
- requestLayout();
- // Reapply the current page to update page scrolls.
- setCurrentPage(mCurrentPage);
- }
-
public RecentsOrientedState getPagedViewOrientedState() {
return mOrientationState;
}
@@ -2596,13 +2685,15 @@
setTaskModalness(mTaskModalness);
mLastComputedTaskStartPushOutDistance = null;
mLastComputedTaskEndPushOutDistance = null;
+ mLastComputedTaskBottomPushOutDistance = null;
updatePageOffsets();
+ updateVerticalPageOffsets();
setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
}
private void updatePageOffsets() {
- float offset = mAdjacentPageOffset;
+ float offset = mAdjacentPageHorizontalOffset;
float modalOffset = ACCEL_0_75.getInterpolation(mTaskModalness);
int count = getChildCount();
@@ -2613,10 +2704,10 @@
float midpointOffsetSize = 0;
float leftOffsetSize = midpoint - 1 >= 0
- ? -getOffsetSize(midpoint - 1, midpoint, offset)
+ ? -getHorizontalOffsetSize(midpoint - 1, midpoint, offset)
: 0;
float rightOffsetSize = midpoint + 1 < count
- ? getOffsetSize(midpoint + 1, midpoint, offset)
+ ? getHorizontalOffsetSize(midpoint + 1, midpoint, offset)
: 0;
boolean showAsGrid = showAsGrid();
@@ -2630,14 +2721,14 @@
// calculation is the task directly next to the focus task in the grid.
int referenceIndex = modalMidpoint == 0 ? 1 : 0;
gridOffsetSize = referenceIndex < count
- ? getOffsetSize(referenceIndex, modalMidpoint, modalOffset)
+ ? getHorizontalOffsetSize(referenceIndex, modalMidpoint, modalOffset)
: 0;
} else {
modalLeftOffsetSize = modalMidpoint - 1 >= 0
- ? getOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset)
+ ? getHorizontalOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset)
: 0;
modalRightOffsetSize = modalMidpoint + 1 < count
- ? getOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset)
+ ? getHorizontalOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset)
: 0;
}
@@ -2688,7 +2779,7 @@
* translating away from the given midpoint.
* @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
*/
- private float getOffsetSize(int childIndex, int midpointIndex, float offsetProgress) {
+ private float getHorizontalOffsetSize(int childIndex, int midpointIndex, float offsetProgress) {
if (offsetProgress == 0) {
// Don't bother calculating everything below if we won't offset anyway.
return 0;
@@ -2750,6 +2841,64 @@
return distanceToOffscreen * offsetProgress;
}
+ private void updateVerticalPageOffsets() {
+ float offset = mAdjacentPageVerticalOffset;
+ int count = getTaskViewCount();
+
+ TaskView runningTask = mRunningTaskId == -1 || !mRunningTaskTileHidden
+ ? null : getTaskView(mRunningTaskId);
+ int midpoint = runningTask == null ? -1 : indexOfChild(runningTask);
+
+ float offsetSize = getVerticalOffsetSize(offset);
+ float midpointOffsetSize = 0;
+
+ for (int i = 0; i < count; i++) {
+ float translation = i == midpoint
+ ? midpointOffsetSize
+ : offsetSize;
+ int directionFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor() * -1;
+ translation *= directionFactor;
+ TaskView child = getTaskViewAt(i);
+ FloatProperty translationProperty = child.getSecondaryTaskOffsetTranslationProperty();
+ translationProperty.set(child, translation);
+ if (LIVE_TILE.get() && mEnableDrawingLiveTile && i == getRunningTaskIndex()) {
+ mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = translation;
+ redrawLiveTile();
+ }
+ }
+ }
+
+ /**
+ * Computes the distance to offset the given child such that it is completely offscreen when
+ * translating away from its position in overview.
+ * @param offsetProgress From 0 to 1 where 0 means no offset and 1 means offset offscreen.
+ */
+ private float getVerticalOffsetSize(float offsetProgress) {
+ if (offsetProgress == 0) {
+ // Don't bother calculating everything below if we won't offset anyway.
+ return 0;
+ }
+ // First, find the distance to offscreen from the normal (centered) task position.
+ mTempRectF.set(mLastComputedTaskSize);
+ RectF taskPosition = mTempRectF;
+ float desiredTop = getHeight();
+ float distanceToOffscreen = desiredTop - taskPosition.top;
+ // Next, we need to account for the resistance translation if any (e.g. long swipe up).
+ float translationY = mTaskViewsSecondaryTranslation;
+ distanceToOffscreen -= translationY;
+ // Finally, we need to account for RecentsView scale, because it moves tasks based on its
+ // pivot. To do this, we move the task position to where it would be offscreen at scale = 1
+ // (computed above), then we apply the scale via getMatrix() to determine how much that
+ // moves the task from its desired position, and adjust the computed distance accordingly.
+ if (mLastComputedTaskBottomPushOutDistance == null) {
+ taskPosition.offsetTo(0, desiredTop + translationY);
+ getMatrix().mapRect(taskPosition);
+ mLastComputedTaskBottomPushOutDistance = (taskPosition.top - desiredTop) / getScaleY();
+ }
+ distanceToOffscreen -= mLastComputedTaskBottomPushOutDistance;
+ return distanceToOffscreen * offsetProgress;
+ }
+
protected void setTaskViewsResistanceTranslation(float translation) {
mTaskViewsSecondaryTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
@@ -2759,20 +2908,20 @@
mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
}
- protected void setTaskViewsPrimaryTranslation(float translation) {
- mTaskViewsPrimaryTranslation = translation;
+ protected void setTaskViewsPrimarySplitTranslation(float translation) {
+ mTaskViewsPrimarySplitTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView task = getTaskViewAt(i);
- task.getPrimaryDismissTranslationProperty().set(task, translation / getScaleY());
+ task.getPrimarySplitTranslationProperty().set(task, translation);
}
- mLiveTileTaskViewSimulator.recentsViewPrimaryTranslation.value = translation;
}
- /**
- * TODO: Do not assume motion across X axis for adjacent page
- */
- public float getPageOffsetScale() {
- return Math.max(getWidth(), 1);
+ protected void setTaskViewsSecondarySplitTranslation(float translation) {
+ mTaskViewsSecondarySplitTranslation = translation;
+ for (int i = 0; i < getTaskViewCount(); i++) {
+ TaskView task = getTaskViewAt(i);
+ task.getSecondarySplitTranslationProperty().set(task, translation);
+ }
}
/**
@@ -2788,8 +2937,9 @@
public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
mSplitHiddenTaskView = taskView;
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
- splitController.setInitialTaskSelect(taskView,
- splitPositionOption);
+ Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
+ taskView.getBottom());
+ splitController.setInitialTaskSelect(taskView, splitPositionOption, initialBounds);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
mSplitPlaceholderView.setLayoutParams(
splitController.getLayoutParamsForActivePosition(getResources(),
@@ -2809,7 +2959,10 @@
}
public PendingAnimation cancelSplitSelect(boolean animate) {
- mSplitPlaceholderView.getSplitController().resetState();
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
+ SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
+ Rect initialBounds = splitController.getInitialBounds();
+ splitController.resetState();
int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
PendingAnimation pendingAnim = new PendingAnimation(duration);
if (!animate) {
@@ -2824,8 +2977,6 @@
getPageScrolls(oldScroll, false,
view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
- // x is correct, y is before tasks move up
- int[] locationOnScreen = mSplitHiddenTaskView.getLocationOnScreen();
int[] newScroll = new int[getChildCount()];
getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
@@ -2833,20 +2984,42 @@
for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
View child = getChildAt(i);
if (child == mSplitHiddenTaskView) {
+ TaskView taskView = (TaskView) child;
- int left = newScroll[i] + getPaddingStart();
- int topMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
- int top = -mSplitHiddenTaskView.getHeight() - locationOnScreen[1];
- mSplitHiddenTaskView.layout(left, top,
- left + mSplitHiddenTaskView.getWidth(),
- top + mSplitHiddenTaskView.getHeight());
- pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, TRANSLATION_Y,
- -top + mSplitPlaceholderView.getHeight() - topMargin));
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
+ mActivity.getDeviceProfile());
+ FloatProperty<TaskView> dismissingTaskViewTranslate;
+ Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
+ taskView.getRight(), taskView.getBottom());
+ int distanceDelta = 0;
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE) {
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ distanceDelta = initialBounds.top - hiddenBounds.top;
+ taskView.layout(initialBounds.left, hiddenBounds.top, initialBounds.right,
+ hiddenBounds.bottom);
+ } else {
+ dismissingTaskViewTranslate = taskView
+ .getPrimaryDismissTranslationProperty();
+ distanceDelta = initialBounds.left - hiddenBounds.left;
+ taskView.layout(hiddenBounds.left, initialBounds.top, hiddenBounds.right,
+ initialBounds.bottom);
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE) {
+ distanceDelta *= -1;
+ }
+ }
+ pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView,
+ dismissingTaskViewTranslate,
+ distanceDelta));
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, ALPHA, 1));
} else {
// If insertion is on last index (furthest from clear all), we directly add the view
// else we translate all views to the right of insertion index further right,
// ignore views to left
+ if (showAsGrid()) {
+ // TODO(b/186800707) handle more elegantly for grid
+ continue;
+ }
int scrollDiff = newScroll[i] - oldScroll[i];
if (scrollDiff != 0) {
FloatProperty translationProperty = child instanceof TaskView
@@ -2872,6 +3045,12 @@
pendingAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
+ // TODO(b/186800707) Figure out how to undo for grid view
+ // Need to handle cases where dismissed task is
+ // * Top Row
+ // * Bottom Row
+ // * Focused Task
+ updateGridProperties();
resetFromSplitSelectionState();
}
});
@@ -2881,13 +3060,16 @@
private void resetFromSplitSelectionState() {
mSplitHiddenTaskView.setTranslationY(0);
- int pageToSnapTo = mCurrentPage;
- if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
- pageToSnapTo += 1;
- } else {
- pageToSnapTo = mSplitHiddenTaskViewIndex;
+ if (!showAsGrid()) {
+ // TODO(b/186800707)
+ int pageToSnapTo = mCurrentPage;
+ if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
+ pageToSnapTo += 1;
+ } else {
+ pageToSnapTo = mSplitHiddenTaskViewIndex;
+ }
+ snapToPageImmediately(pageToSnapTo);
}
- snapToPageImmediately(pageToSnapTo);
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
resetTaskVisuals();
mSplitHiddenTaskView = null;
@@ -3027,6 +3209,11 @@
return new PendingAnimation(duration);
}
+ // When swiping down from overview to tasks, ensures the snapped page's scroll maintain
+ // invariant between quick switch and overview, to ensure a smooth animation transition.
+ updateGridProperties();
+ updateScrollSynchronously();
+
int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
final boolean[] passedOverviewThreshold = new boolean[] {false};
ValueAnimator progressAnim = ValueAnimator.ofFloat(0, 1);
@@ -3200,6 +3387,13 @@
return;
}
+ final boolean sendUserLeaveHint = toRecents && LIVE_TILE.get();
+ if (sendUserLeaveHint) {
+ // Notify the SysUI to use fade-in animation when entering PiP from live tile.
+ final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
+ systemUiProxy.notifySwipeToHomeFinished();
+ systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
+ }
mRecentsAnimationController.finish(toRecents, () -> {
if (onFinishComplete != null) {
onFinishComplete.run();
@@ -3211,7 +3405,7 @@
// taps on QSB (3) user goes back to Overview and launch the most recent task.
setCurrentTask(-1);
mRecentsAnimationController = null;
- });
+ }, sendUserLeaveHint);
}
public void setDisallowScrollToClearAll(boolean disallowScrollToClearAll) {
@@ -3349,8 +3543,16 @@
if (pageIndex == -1) {
return 0;
}
+
+ int overScrollShift = getOverScrollShift();
+ if (mAdjacentPageVerticalOffset > 0) {
+ // Don't dampen the scroll (due to overscroll) if the adjacent tasks are offscreen, so
+ // that the page can move freely given there's no visual indication why it shouldn't.
+ overScrollShift = (int) Utilities.mapRange(mAdjacentPageVerticalOffset, overScrollShift,
+ getUndampedOverScrollShift());
+ }
return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this)
- + getOverScrollShift();
+ + overScrollShift;
}
/**
@@ -3433,6 +3635,12 @@
* capturing the snapshot at the same time.
*/
public void switchToScreenshot(Runnable onFinishRunnable) {
+ if (mRecentsAnimationController == null) {
+ if (onFinishRunnable != null) {
+ onFinishRunnable.run();
+ }
+ return;
+ }
switchToScreenshot(mRunningTaskId == -1 ? null
: mRecentsAnimationController.screenshotTask(mRunningTaskId), onFinishRunnable);
}
@@ -3482,7 +3690,6 @@
public void onSecondaryWindowBoundsChanged() {
// Invalidate the task view size
setInsets(mInsets);
- requestLayout();
}
/**
@@ -3504,9 +3711,34 @@
* tasks to be dimmed while other elements in the recents view are left alone.
*/
public void showForegroundScrim(boolean show) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(this, COLOR_TINT, show ? 0.5f : 0f);
+ anim.setAutoCancel(true);
+ anim.start();
+ }
+
+ /** Tint the RecentsView and TaskViews in to simulate a scrim. */
+ // TODO(b/187528071): Replace this tinting with a scrim on top of RecentsView
+ private void setColorTint(float tintAmount) {
+ mColorTint = tintAmount;
+
for (int i = 0; i < getTaskViewCount(); i++) {
- getTaskViewAt(i).showColorTint(show);
+ getTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
}
+
+ Drawable scrimBg = mActivity.getScrimView().getBackground();
+ if (scrimBg != null) {
+ if (tintAmount == 0f) {
+ scrimBg.setTintList(null);
+ } else {
+ scrimBg.setTintBlendMode(BlendMode.SRC_OVER);
+ scrimBg.setTint(
+ ColorUtils.setAlphaComponent(mTintingColor, (int) (255 * tintAmount)));
+ }
+ }
+ }
+
+ private float getColorTint() {
+ return mColorTint;
}
private boolean showAsGrid() {
@@ -3550,6 +3782,14 @@
mScrollListeners.remove(listener);
}
+ /**
+ * @return Corner radius in pixel value for PiP window, which is updated via
+ * {@link #mIPipAnimationListener}
+ */
+ public int getPipCornerRadius() {
+ return mPipCornerRadius;
+ }
+
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
@@ -3566,9 +3806,11 @@
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
IPipAnimationListener.Stub {
private T mActivity;
+ private RecentsView mRecentsView;
- public void setActivity(T activity) {
+ public void setActivityAndRecentsView(T activity, RecentsView recentsView) {
mActivity = activity;
+ mRecentsView = recentsView;
}
@Override
@@ -3581,5 +3823,19 @@
}
});
}
+
+ @Override
+ public void onPipCornerRadiusChanged(int cornerRadius) {
+ if (mRecentsView != null) {
+ mRecentsView.mPipCornerRadius = cornerRadius;
+ }
+ }
+ }
+
+ /** Get the color used for foreground scrimming the RecentsView for sharing. */
+ public static int getForegroundScrimDimColor(Context context) {
+ int baseColor = Themes.getAttrColor(context, R.attr.overviewScrimColor);
+ // The Black blending is temporary until we have the proper color token.
+ return ColorUtils.blendARGB(Color.BLACK, baseColor, 0.25f);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 685f725..5b8d4ce 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -53,7 +53,6 @@
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
-import com.android.launcher3.util.Themes;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
import com.android.systemui.plugins.OverviewScreenshotActions;
@@ -121,7 +120,7 @@
// Initialize with placeholder value. It is overridden later by TaskView
mFullscreenParams = TEMP_PARAMS.get(context);
- mDimColor = Themes.getColorBackgroundFloating(context);
+ mDimColor = RecentsView.getForegroundScrimDimColor(context);
mDimmingPaintAfterClearing.setColor(mDimColor);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 3349b74..f8be5b6 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -32,7 +32,6 @@
import static com.android.launcher3.Utilities.comp;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
@@ -65,6 +64,7 @@
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.Toast;
@@ -88,7 +88,6 @@
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TransformingTouchDelegate;
import com.android.launcher3.util.ViewPool.Reusable;
import com.android.quickstep.RecentsModel;
@@ -147,6 +146,9 @@
public static final long SCALE_ICON_DURATION = 120;
private static final long DIM_ANIM_DURATION = 700;
+
+ private static final Interpolator FULLSCREEN_INTERPOLATOR = ACCEL_DEACCEL;
+
/**
* This technically can be a vanilla {@link TouchDelegate} class, however that class requires
* setting the touch bounds at construction, so we'd repeatedly be created many instances
@@ -172,6 +174,32 @@
}
};
+ private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_X =
+ new FloatProperty<TaskView>("splitSelectTranslationX") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setSplitSelectTranslationX(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mSplitSelectTranslationX;
+ }
+ };
+
+ private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_Y =
+ new FloatProperty<TaskView>("splitSelectTranslationY") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setSplitSelectTranslationY(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mSplitSelectTranslationY;
+ }
+ };
+
private static final FloatProperty<TaskView> DISMISS_TRANSLATION_X =
new FloatProperty<TaskView>("dismissTranslationX") {
@Override
@@ -302,19 +330,6 @@
}
};
- private static final FloatProperty<TaskView> COLOR_TINT =
- new FloatProperty<TaskView>("colorTint") {
- @Override
- public void setValue(TaskView taskView, float v) {
- taskView.setColorTint(v);
- }
-
- @Override
- public Float get(TaskView taskView) {
- return taskView.getColorTint();
- }
- };
-
private final TaskOutlineProvider mOutlineProvider;
private Task mTask;
@@ -345,6 +360,9 @@
// The following grid translations scales with mGridProgress.
private float mGridTranslationX;
private float mGridTranslationY;
+ // Used when in SplitScreenSelectState
+ private float mSplitSelectTranslationY;
+ private float mSplitSelectTranslationX;
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
@@ -364,11 +382,6 @@
private final float[] mIconCenterCoords = new float[2];
private final float[] mChipCenterCoords = new float[2];
- // Colored tint for the task view and all its supplementary views (like the task icon and well
- // being banner.
- private final int mTintingColor;
- private float mTintAmount;
-
private boolean mIsClickableAsLiveTile = true;
public TaskView(Context context) {
@@ -390,8 +403,6 @@
mOutlineProvider = new TaskOutlineProvider(getContext(), mCurrentFullscreenParams,
mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx);
setOutlineProvider(mOutlineProvider);
-
- mTintingColor = Themes.getColorBackgroundFloating(context);
}
/**
@@ -553,6 +564,7 @@
@Override
public void onAnimationEnd(Animator animator) {
+ recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(true);
mIsClickableAsLiveTile = true;
}
});
@@ -777,8 +789,7 @@
float upperClamp = invert ? 1 : iconScalePercentage;
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
.getInterpolation(progress);
- mIconView.setScaleX(scale);
- mIconView.setScaleY(scale);
+ mIconView.setAlpha(scale);
if (mContextualChipWrapper != null && mContextualChipWrapper != null) {
mContextualChipWrapper.setAlpha(scale);
mContextualChipWrapper.setScaleX(Math.min(scale, comp(mModalness)));
@@ -826,14 +837,16 @@
protected void resetViewTransforms() {
// fullscreenTranslation and accumulatedTranslation should not be reset, as
// resetViewTransforms is called during Quickswitch scrolling.
- mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX = 0f;
- mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f;
+ mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX =
+ mSplitSelectTranslationX = 0f;
+ mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY =
+ mSplitSelectTranslationY = 0f;
applyTranslationX();
applyTranslationY();
setTranslationZ(0);
setAlpha(mStableAlpha);
setIconScaleAndDim(1);
- setColorTint(0);
+ setColorTint(0, 0);
}
public void setStableAlpha(float parentAlpha) {
@@ -951,12 +964,21 @@
private void applyScale() {
float scale = 1;
- float fullScreenProgress = EXAGGERATED_EASE.getInterpolation(mFullscreenProgress);
+ float fullScreenProgress = FULLSCREEN_INTERPOLATOR.getInterpolation(mFullscreenProgress);
scale *= Utilities.mapRange(fullScreenProgress, 1f, mFullscreenScale);
setScaleX(scale);
setScaleY(scale);
}
+ private void setSplitSelectTranslationX(float x) {
+ mSplitSelectTranslationX = x;
+ applyTranslationX();
+ }
+
+ private void setSplitSelectTranslationY(float y) {
+ mSplitSelectTranslationY = y;
+ applyTranslationY();
+ }
private void setDismissTranslationX(float x) {
mDismissTranslationX = x;
applyTranslationX();
@@ -1057,12 +1079,12 @@
private void applyTranslationX() {
setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
- + getPersistentTranslationX());
+ + mSplitSelectTranslationX + getPersistentTranslationX());
}
private void applyTranslationY() {
setTranslationY(mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY
- + getPersistentTranslationY());
+ + mSplitSelectTranslationY + getPersistentTranslationY());
}
/**
@@ -1086,6 +1108,16 @@
+ getGridTrans(mGridTranslationY);
}
+ public FloatProperty<TaskView> getPrimarySplitTranslationProperty() {
+ return getPagedOrientationHandler().getPrimaryValue(
+ SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
+ }
+
+ public FloatProperty<TaskView> getSecondarySplitTranslationProperty() {
+ return getPagedOrientationHandler().getSecondaryValue(
+ SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
+ }
+
public FloatProperty<TaskView> getPrimaryDismissTranslationProperty() {
return getPagedOrientationHandler().getPrimaryValue(
DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y);
@@ -1101,6 +1133,11 @@
TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
}
+ public FloatProperty<TaskView> getSecondaryTaskOffsetTranslationProperty() {
+ return getPagedOrientationHandler().getSecondaryValue(
+ TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y);
+ }
+
public FloatProperty<TaskView> getTaskResistanceTranslationProperty() {
return getPagedOrientationHandler().getSecondaryValue(
TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y);
@@ -1370,7 +1407,7 @@
}
private float getFullscreenTrans(float endTranslation) {
- float progress = ACCEL_DEACCEL.getInterpolation(mFullscreenProgress);
+ float progress = FULLSCREEN_INTERPOLATOR.getInterpolation(mFullscreenProgress);
return Utilities.mapRange(progress, 0, endTranslation);
}
@@ -1417,24 +1454,13 @@
getRecentsView().initiateSplitSelect(this, splitPositionOption);
}
- private void setColorTint(float amount) {
- mSnapshotView.setDimAlpha(amount);
- mIconView.setIconColorTint(mTintingColor, amount);
- mDigitalWellBeingToast.setBannerColorTint(mTintingColor, amount);
- }
-
- private float getColorTint() {
- return mTintAmount;
- }
-
/**
- * Show the task view with a color tint (animates value).
+ * Set a color tint on the snapshot and supporting views.
*/
- public void showColorTint(boolean enable) {
- ObjectAnimator tintAnimator = ObjectAnimator.ofFloat(
- this, COLOR_TINT, enable ? MAX_PAGE_SCRIM_ALPHA : 0);
- tintAnimator.setAutoCancel(true);
- tintAnimator.start();
+ public void setColorTint(float amount, int tintColor) {
+ mSnapshotView.setDimAlpha(amount);
+ mIconView.setIconColorTint(tintColor, amount);
+ mDigitalWellBeingToast.setBannerColorTint(tintColor, amount);
}
/**
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 88f1850..9630d27 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -61,6 +61,8 @@
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.quickstep.views.RecentsView;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@@ -141,6 +143,21 @@
}
}
+ @Before
+ public void setUp() {
+ mLauncher.onTestStart();
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ // Limits UI tests affecting tests running after them.
+ AbstractQuickStepTest.checkDetectedLeaks(mLauncher);
+ } finally {
+ mLauncher.onTestFinish();
+ }
+ }
+
// b/143488140
//@NavigationModeSwitch
@Test
@@ -171,13 +188,13 @@
protected <T> T getFromRecents(Function<RecentsActivity, T> f) {
if (!TestHelpers.isInLauncherProcess()) return null;
if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "getFromRecents");
+ Log.d(TestProtocol.FALLBACK_ACTIVITY_NO_SET, "getFromRecents");
}
Object[] result = new Object[1];
Wait.atMost("Failed to get from recents", () -> MAIN_EXECUTOR.submit(() -> {
RecentsActivity activity = RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "activity=" + activity);
+ Log.d(TestProtocol.FALLBACK_ACTIVITY_NO_SET, "activity=" + activity);
}
if (activity == null) {
return false;
@@ -205,10 +222,6 @@
BaseOverview overview = mLauncher.getBackground().switchToOverview();
executeOnRecents(recents -> {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.GET_RECENTS_FAILED, "isLoading=" +
- recents.<RecentsView>getOverviewPanel().isLoadingTasks());
- }
assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3);
});
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index a700e16..a5038a1 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -189,12 +189,10 @@
@NavigationModeSwitch
@PortraitLandscape
public void testSwitchToOverview() throws Exception {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "testSwitchToOverview");
assertNotNull("Workspace.switchToOverview() returned null",
mLauncher.pressHome().switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "testSwitchToOverview finished");
}
@Test
diff --git a/res/color/all_apps_tab_text.xml b/res/color/all_apps_tab_text.xml
index f0c6310..0c9acf9 100644
--- a/res/color/all_apps_tab_text.xml
+++ b/res/color/all_apps_tab_text.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?android:attr/colorAccent" android:state_selected="true"/>
+ <item android:color="@android:color/white" android:state_selected="true"/>
<item android:color="?android:attr/textColorTertiary"/>
</selector>
\ No newline at end of file
diff --git a/res/color/cell_layout_bg_color_active.xml b/res/color/cell_layout_bg_color_active.xml
index e826489..d1a3d7c 100644
--- a/res/color/cell_layout_bg_color_active.xml
+++ b/res/color/cell_layout_bg_color_active.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:alpha="0.4"
+ <item android:alpha="0.3"
android:color="?android:attr/colorAccent"/>
</selector>
diff --git a/res/color/cell_layout_bg_color_inactive.xml b/res/color/cell_layout_bg_color_inactive.xml
index d60a27a..0632100 100644
--- a/res/color/cell_layout_bg_color_inactive.xml
+++ b/res/color/cell_layout_bg_color_inactive.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:alpha="0.3"
+ <item android:alpha="0.25"
android:color="?android:attr/colorAccent"/>
</selector>
\ No newline at end of file
diff --git a/res/drawable/all_apps_tabs_background.xml b/res/drawable/all_apps_tabs_background.xml
new file mode 100644
index 0000000..ca2beec
--- /dev/null
+++ b/res/drawable/all_apps_tabs_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shape android:shape="rectangle"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <solid android:color="?androidprv:attr/colorSurfaceVariant" />
+ <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/res/layout/all_apps_personal_work_tabs.xml b/res/layout/all_apps_personal_work_tabs.xml
index 5fb5bcb..cefd0ab 100644
--- a/res/layout/all_apps_personal_work_tabs.xml
+++ b/res/layout/all_apps_personal_work_tabs.xml
@@ -19,7 +19,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabs"
android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_height="@dimen/all_apps_header_pill_height"
+ android:background="@drawable/all_apps_tabs_background"
android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
android:orientation="horizontal"
diff --git a/res/layout/all_apps_tabs.xml b/res/layout/all_apps_tabs.xml
index 2accd2d..de4a69d 100644
--- a/res/layout/all_apps_tabs.xml
+++ b/res/layout/all_apps_tabs.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:layout_below="@id/search_container_all_apps"
android:layout_gravity="center_horizontal|top"
- android:layout_marginTop="@dimen/all_apps_header_tab_height"
+ android:layout_marginTop="@dimen/all_apps_header_pill_height"
android:clipChildren="true"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml
index e3c60ec..94fcdb9 100644
--- a/res/layout/secondary_launcher.xml
+++ b/res/layout/secondary_launcher.xml
@@ -70,7 +70,7 @@
<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
android:id="@+id/tabs"
android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_height="@dimen/all_apps_header_pill_height"
android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
android:orientation="horizontal"
diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml
index a9d523a..85c6488 100644
--- a/res/layout/widgets_bottom_sheet_content.xml
+++ b/res/layout/widgets_bottom_sheet_content.xml
@@ -15,10 +15,12 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<View
+ android:id="@+id/collapse_handle"
android:layout_width="48dp"
android:layout_height="2dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
+ android:visibility="gone"
android:background="?android:attr/textColorSecondary"/>
<TextView
style="@style/TextHeadline"
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
index bfce01d..ce7a682 100644
--- a/res/layout/widgets_full_sheet_search_and_recommendations.xml
+++ b/res/layout/widgets_full_sheet_search_and_recommendations.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout
+<com.android.launcher3.widget.picker.SearchAndRecommendationsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_and_recommendations_container"
android:layout_width="match_parent"
@@ -49,4 +49,4 @@
android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
android:layout_marginTop="16dp"
android:visibility="gone"/>
-</LinearLayout>
+</com.android.launcher3.widget.picker.SearchAndRecommendationsView>
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
index 3d3ae6a..3402415 100644
--- a/res/layout/widgets_personal_work_tabs.xml
+++ b/res/layout/widgets_personal_work_tabs.xml
@@ -19,7 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tabs"
android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_height="@dimen/all_apps_header_pill_height"
android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
android:orientation="horizontal"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index e516468..b3b0d2b 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Raak en hou die legstuk om dit op die Tuisskerm rond te beweeg"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Voeg by Tuisskerm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> legstukke</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> legstuk</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Style en muurpapiere"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Muurpapier en styl"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tuis-instellings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 5241acd..af30fa5 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ምግብርን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"በመነሻ ገጽ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ወደ መነሻ ገጽ አክል"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ንዑስ ፕሮግራሞች</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ንዑስ ፕሮግራሞች</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ንጥሎች"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ወይም ተጨማሪ ንጥሎች"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"የግድግዳ ወረቀቶች"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ቅጦች እና ልጣፎች"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"የመነሻ ቅንብሮች"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 669aa91..92295db 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"العرض %1$d الطول %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"يمكنك النقر على الأداة مع الاستمرار لتحريكها على الشاشة الرئيسية."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"إضافة إلى الشاشة الرئيسية"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="zero"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> أداة</item>
<item quantity="two">أداتان (<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>)</item>
@@ -111,7 +109,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر أو أكثر"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"الأنماط والخلفيات"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"إعدادات الشاشة الرئيسية"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 931b3ab..8e55585 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"কোনো ৱিজেট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d বহল x %2$d ওখ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ৱিজেটটো গৃহ স্ক্ৰীনৰ আশে-পাশে নিবলৈ সেইটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"গৃহ স্ক্ৰীনত যোগ কৰক"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> টা ৱিজেট</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> টা ৱিজেট</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা বস্তু"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা অথবা তাতকৈ অধিক বস্তু"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ৱালপেপাৰসমূহ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"শৈলী আৰু ৱালপেপাৰ"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"গৃহ ছেটিং"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 8b525f2..62581b8 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Əsas ekranda hərəkət etdirmək üçün vidcetə toxunub saxlayın"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Əsas ekrana əlavə edin"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidcet</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> vidcet</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> element"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> və ya daha çox element"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Üslub və divar kağızları"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Home ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index d4f013a..ce69fd9 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"širina od %1$d i visina od %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite vidžet da biste ga pomerali po početnom ekranu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžet</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžeta</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadine"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Podešavanja početnog ekrana"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator je onemogućio"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotaciju početnog ekrana"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index cf02d48..2efdad4 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Шырына: %1$d, вышыня: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Утрымліваючы віджэт націснутым, перамяшчайце яго па Галоўным экране"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Дадаць на Галоўны экран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджэт</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджэты</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g> ці больш"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стылі і шпалеры"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Налады галоўнага экрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index b3c5ca4..9484a75 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d и височина %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Докоснете приспособлението и го задръжте, за да го местите на началния екран"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Добавяне към началния екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> приспособления</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> приспособление</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> елемента"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> или повече елементи"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилове и тапети"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Настройки за началния екран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 283ac70..95b0b8d 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"হোম স্ক্রিনের যেকোনও জায়গায় উইজেটটি নিয়ে যেতে, টাচ করে ধরে থাকুন"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"হোম স্ক্রিনে যোগ করুন"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>টি উইজেট</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>টি উইজেট</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি আইটেম"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি বা তার বেশি আইটেম"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"স্টাইল এবং ওয়ালপেপার"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"হোম সেটিংস"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"হোম স্ক্রিন ঘোরানোর অনুমতি দিন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index fcd6f3f..f79b99c 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i držite vidžet da ga pomjerate po Početnom ekranu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžet</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidžeta</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, br. stavki: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadinske slike"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadinske slike"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog ekrana"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index d54670b..ecfaebe 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premut el widget per moure\'l per la pantalla d\'inici"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Afegeix a la pantalla d\'inici"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elements"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o més elements"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estils i fons de pantalla"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Config. pantalla d\'inici"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a9ea587..4cfadc1 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pokud widgetem chcete pohybovat po ploše, dotkněte se ho a podržte ho"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Přidat na plochu"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgety</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetu</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g> nebo více"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styly a tapety"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Nastavení plochy"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index e5dacac..502d5eb 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Hold widgetten nede for at flytte den rundt på startskærmen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Føj til startskærm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Layout og baggrunde"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Baggrund og stil"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Indstillinger for startskærm"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 31b9b20..f040310 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Wenn du das Widget auf dem Startbildschirm verschieben möchtest, halte es gedrückt"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Zum Startbildschirm hinzufügen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> Widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> Widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> Elemente"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> oder mehr Elemente"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Designs und Hintergründe"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Startbildschirm-Einstellungen"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Drehen des Startbildschirms zulassen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index a9deedb..8d00829 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Πλάτος %1$d επί ύψος %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Αγγίξτε παρατεταμένα το γραφικό στοιχείο για να το μετακινήσετε στην Αρχική οθόνη"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Προσθήκη στην Αρχική οθόνη"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> γραφικά στοιχεία</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> γραφικό στοιχείο</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> στοιχεία"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ή περισσότερα στοιχεία"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Στιλ και ταπετσαρίες"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Ρυθμίσεις Αρχ. Οθ."</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index d6b9296..5af3e7d 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -97,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles & wallpapers"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index d6b9296..5af3e7d 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -97,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles & wallpapers"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index d6b9296..5af3e7d 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -97,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles & wallpapers"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index d6b9296..5af3e7d 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -97,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles & wallpapers"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 9fff023..b82f0c9 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -97,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles & wallpapers"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & style"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 0330795..56f31bf 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén presionado el widget para moverlo por la pantalla principal"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Agregar a pantalla principal"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o más elementos"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos y fondos de pantalla"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fondo de pantalla y estilo"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configuración de pantalla principal"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 888436f..d34ff32 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén pulsado el widget para moverlo por la pantalla de inicio"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Añadir a la pantalla de inicio"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">Widgets: <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Widget: <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> elementos)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> o más elementos)"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos y fondos de pantalla"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Ajustes de la pantalla de inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitado por el administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 15b6177..06cac34 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Vidina teisaldamiseks avakuval puudutage vidinat ja hoidke seda all"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lisa avakuvale"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> vidinat</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> vidin</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> üksust"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> või rohkem üksust"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiilid ja taustapildid"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Avakuva seaded"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Luba avakuva pööramine"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 5309052..ad61cb6 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Eduki sakatuta widgeta hasierako pantailan zehar mugitzeko"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Gehitu hasierako pantailan"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu edo gehiago)"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estiloak eta horma-paperak"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Hasierako pantailaren ezarpenak"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Eman hasierako pantaila biratzeko baimena"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index b0c300c..f1ae4d5 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"برای جابهجا کردن ابزارک یا استفاده از کنشهای سفارشی، دوضربه بزنید و نگه دارید."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d عرض در %2$d طول"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ابزارک را لمس کنید و نگه دارید تا آن را در صفحه اصلی حرکت دهید"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"افزودن به صفحه اصلی"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ابزارک</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ابزارک</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد یا بیشتر"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواریها"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"سبک و کاغذدیواری"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"کاغذدیواری و سبک"</string>
<string name="settings_button_text" msgid="8873672322605444408">"تنظیمات صفحه اصلی"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"توسط سرپرست سیستم غیرفعال شده است"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"قابلچرخش بودن صفحه اصلی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 47466cf..1e1b1e3 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Voit siirtää widgetiä aloitusnäytöllä koskettamalla sitä pitkään"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lisää aloitusnäytölle"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetiä</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, ainakin <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Tyylit ja taustakuvat"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Aloitusnäyttö"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index f50d837..1867a5d 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Maintenez le doigt sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> élément(s)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles et fonds d\'écran"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Paramètres d\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f51c3d9..d8b666b 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Appuyez de manière prolongée sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles et fonds d\'écran"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Paramètres de l\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index c3e3596..3609b17 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premido o widget para movelo pola pantalla de inicio"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Engadir á pantalla de inicio"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos ou máis"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos/fondos de pantalla"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Axustes de Inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 0882d64..55eceee 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"વિજેટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"વિજેટને હોમ સ્ક્રીનની આજુબાજુ ખસેડવા માટે, તેને ટચ કરીને થોડીવાર દબાવી રાખો"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"હોમ સ્ક્રીન પર ઉમેરો"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> વિજેટ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> વિજેટ</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> આઇટમ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> કે વધુ આઇટમ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"શૈલીઓ અને વૉલપેપર"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 61776d6..4c17b16 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"होम स्क्रीन पर यहां-वहां ले जाने के लिए विजेट को दबाकर रखें"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रीन पर जोड़ें"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आइटम"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> या इससे ज़्यादा आइटम"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"स्टाइल और वॉलपेपर"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"होम पेज की सेटिंग"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके एडमिन ने बंद किया हुआ है"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 171f5d0..a165fd7 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite widget da biste ga pomicali po početnom zaslonu"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni zaslon"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgeta</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadine"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog zaslona"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index bbb24e9..c89b55b 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tartsa lenyomva a modult a kezdőképernyőn való mozgatáshoz"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Hozzáadás a kezdőképernyőhöz"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> modul</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> modul</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elem"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vagy több elem"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stílusok és háttérképek"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Kezdőképernyő beállításai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index ff8b895..522aa65 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Հպեք վիջեթին և պահեք՝ հիմնական էկրանին տեղափոխելու համար"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ավելացնել հիմնական էկրանին"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> վիջեթ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> վիջեթ</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> տարր"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> կամ ավելի տարրեր"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Ոճեր և պաստառներ"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Գլխավոր էջի կարգավորումներ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index c1889ff..e7a2ee6 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketuk dua kali & tahan untuk memindahkan widget atau gunakan tindakan khusus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh lama widget untuk memindahkannya di sekitar Layar utama"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Tambahkan ke Layar utama"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item atau lebih"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Gaya & wallpaper"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Setelan layar utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan Layar utama diputar"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 1dce7c7..5dcdb52 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Haltu fingri á græjunni til að hreyfa hana um heimaskjáinn"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Bæta á heimaskjá"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> græja</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> græjur</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atriði"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eða fleiri atriði"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stílar og veggfóður"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Heimastillingar"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning á heimaskjá"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 3d1cb5b..c527a2e 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementi"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o più elementi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stili e sfondi"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Impostazioni schermata Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 4cf0eb2..1264738 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"רוחב %1$d על גובה %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"יש ללחוץ לחיצה ארוכה על הווידג\'ט כדי להזיז אותו ברחבי מסך הבית"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"הוספה למסך הבית"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="two"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ווידג\'טים</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ווידג\'טים</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, מספר הפריטים: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> פריטים או יותר"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"טפטים"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"סגנונות וטפטים"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"הגדרות של מסך הבית"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"סיבוב של מסך הבית"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 77efbad..af588b8 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ウィジェットを押し続けると、ホーム画面上に移動できます。"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ホーム画面に追加"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 件のウィジェット</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 件のウィジェット</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件のアイテム"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件以上のアイテム"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"スタイルと壁紙"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ホームの設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index e3be57f..03e0bbb 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ხანგრძლივად შეეხეთ ვიჯეტს მთავარ ეკრანზე მის გადასაადგილებლად"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"მთავარ ეკრანზე დამატება"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ვიჯეტი</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ვიჯეტი</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ერთეული"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ან მეტი ერთეული"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"სტილები და ფონები"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"მთავარი გვერდის პარამეტრები"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 392dc8b..f0a8f80 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Негізгі экран бойымен қозғалту үшін виджетті басып, ұстап тұрыңыз."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Негізгі экранға қосу"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> виджет</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> элемент бар"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> не одан көп элемент бар"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стильдер мен тұсқағаздар"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Негізгі экран параметрлері"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index dd04c01..e0332b9 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទីធាតុក្រាហ្វិក ឬប្រើសកម្មភាពតាមបំណង។"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ចុចធាតុក្រាហ្វិកឱ្យជាប់ ដើម្បីផ្លាស់ទីវាជុំវិញអេក្រង់ដើម"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"បញ្ចូលទៅអេក្រង់ដើម"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">ធាតុក្រាហ្វិក <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">ធាតុក្រាហ្វិក <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g> ឬច្រើនជាងនេះ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំងរូបភាព"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"រចនាប័ទ្ម និងផ្ទាំងរូបភាព"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ការកំណត់ទំព័រដើម"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 73e2255..27f045e 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ಮುಖಪುಟದ ಪರದೆ ಸುತ್ತ ವಿಜೆಟ್ ಅನ್ನು ಸರಿಸಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸಿ"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ವಿಜೆಟ್ಗಳು</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ವಿಜೆಟ್ಗಳು</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಐಟಂಗಳು"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಅಥವಾ ಹೆಚ್ಚಿನ ಐಟಂಗಳು"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್ಪೇಪರ್ಗಳು"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ಶೈಲಿಗಳು & ವಾಲ್ಪೇಪರ್ಗಳು"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ವಾಲ್ಪೇಪರ್ ಮತ್ತು ಶೈಲಿ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 7e24dc3..a240ac3 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"너비 %1$d, 높이 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"홈 화면에서 위젯을 이동하려면 길게 터치하세요."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"홈 화면에 추가"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">위젯 <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>개</item>
<item quantity="one">위젯 <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g>개</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개 이상"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"스타일 및 배경화면"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"홈 설정"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index a4f54bf..f848940 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетти жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Башкы экранга жылдыруу үчүн виджетти коё бербей басып туруңуз"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Башкы экранга кошуу"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> виджет</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g> же андан көбүрөөк"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилдер жана тушкагаздар"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Башкы бет жөндөөлөрү"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды бурууга уруксат берүү"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index a7c2f68..1f3f6b7 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -97,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ລາຍການ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ຫຼື ລາຍການເພີ່ມເຕີມ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ຮູບແບບ ແລະ ຮູບພື້ນຫຼັງ"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າໜ້າຫຼັກ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍຢູ່ໜ້າຫຼັກໄດ້"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 43055a5..2d76f92 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Paliesdami ir palaikydami valdiklį galite judėti pagrindiniame ekrane"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pridėti prie pagrindinio ekrano"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> valdiklis</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> valdikliai</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g> ar daugiau"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ekrano fonai"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiliai ir ekrano fonai"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"„Home“ nustatymai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Išjungė administratorius"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 8bcf250..ada97fb 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pieskarieties logrīkam un turiet to, lai to pārvietotu pa sākuma ekrānu."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pievienot sākuma ekrānam"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="zero"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> logrīku</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> logrīks</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mape <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vienumi"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mape <xliff:g id="NAME">%1$s</xliff:g>, vienumu skaits mapē: vismaz <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fona tapetes"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stili un fona tapetes"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Sākumlapas iestatījumi"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index c4349e6..128b87d 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Допрете го и задржете го виџетот за да го движите наоколу на почетниот екран"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Додај на почетниот екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџет</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџети</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставки"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или повеќе ставки"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилови и тапети"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Поставки за почетен екран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротација на почетниот екран"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index c0cb36b..b64bb99 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"വിജറ്റ് നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ഹോം സ്ക്രീനിന് ചുറ്റും വിജറ്റ് നീക്കാൻ അതിൽ സ്പർശിച്ച് പിടിക്കുക"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ഹോം സ്ക്രീനിലേക്ക് ചേർക്കുക"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> വിജറ്റുകൾ</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> വിജറ്റ്</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ഇനങ്ങൾ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> അല്ലെങ്കിൽ അതിലധികം ഇനങ്ങൾ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"സ്റ്റൈലുകളും വാൾപേപ്പറുകളും"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index b512dc2..4d9acc2 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Жижиг хэрэгслийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Жижиг хэрэгслийг Үндсэн нүүрний эргэн тойронд зөөхийн тулд түүнд хүрээд, удаан дарна уу"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Үндсэн нүүрэнд нэмэх"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> жижиг хэрэгсэл</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> жижиг хэрэгсэл</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> зүйл"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> эсвэл үүнээс олон зүйл"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Дэлгэцийн зураг"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Загвар ба дэлгэцийн зураг"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Нүүр хуудасны тохиргоо"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 7bf6c6c..01c132f 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"होम स्क्रीनवर ते हलवण्यासाठी विजेटला स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रीनवर जोडा"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> विजेट</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> विजेट</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आयटम"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> किंवा त्याहून अधिक आयटम"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"शैली आणि वॉलपेपर"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्ज"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"मुख्य स्क्रीन फिरविण्यास अनुमती द्या"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 91f2a4d..9465be5 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh & tahan widget untuk menggerakkan widget di sekitar Skrin utama"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Tambah pada Skrin utama"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atau lebih banyak item"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Gaya & kertas dinding"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Kertas dinding & gaya"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tetapan laman utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index f042629..063f791 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ပင်မစာမျက်နှာအနီးတွင် ဝိဂျက်ကိုရွှေ့ရန် ၎င်းကို တို့ထိ၍ဖိထားပါ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ပင်မစာမျက်နှာသို့ ထည့်ရန်"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">ဝိဂျက် <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ခု</item>
<item quantity="one">ဝိဂျက် <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ခု</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> ဖိုင်များ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> သို့မဟုတ် နောက်ထပ်ဖိုင်များ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ပုံစံနှင့် နောက်ခံပုံများ"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ပင်မဆက်တင်များ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 540d726..52ff878 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Trykk og hold på modulen for å bevege den rundt på startskjermen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Legg til på startskjermen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> moduler</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> modul</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunner"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiler og bakgrunner"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Startsideinnstillinger"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 0cdeae0..cecc3ab 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"कुनै विजेट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"विजेटलाई होम स्क्रिनमा यताउता सार्न त्यसमा टच एन्ड होल्ड गर्नुहोस्"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रिनमा हाल्नुहोस्"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> वटा विजेट</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> वटा विजेट</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वस्तुहरू"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वा सोभन्दा बढी वस्तुहरू"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"शैली तथा वालपेपरहरू"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"गृहपृष्ठका सेटिङहरू"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई रोटेट हुन दिइयोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index d4478b7..58d1d98 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Houd de widget ingedrukt om deze te verplaatsen op het startscherm"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Toevoegen aan startscherm"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Achtergrond"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stijl en achtergrond"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Achtergrond en stijl"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Instellingen start"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgezet door je beheerder"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 3595f33..ffbc690 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ମୂଳସ୍କ୍ରିନର ଆଖପାଖରେ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଏହାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g>ଟି ୱିଜେଟ୍</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g>ଟି ୱିଜେଟ୍</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ଆଇଟମଗୁଡ଼ିକ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> କିମ୍ବା ଅଧିକ ଆଇଟମ୍"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ୱାଲପେପର୍"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ଷ୍ଟାଇଲ୍ ଏବଂ ୱାଲ୍ପେପର୍"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ହୋମ୍ ସେଟିଂସ୍"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ହୋମ୍ ସ୍କ୍ରିନ୍ ବୁଲାଇବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 355e303..869d854 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ਵਿਜੇਟ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਇੱਧਰ-ਉੱਧਰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ਵਿਜੇਟ</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ਵਿਜੇਟ</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਆਈਟਮਾਂ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਜਾਂ ਹੋਰ ਆਈਟਮਾਂ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ਸ਼ੈਲੀਆਂ ਅਤੇ ਵਾਲਪੇਪਰ"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 306a9a0..acce00a 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść widżet lub użyć działań niestandardowych."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Kliknij i przytrzymaj widżet, by poruszać nim po ekranie głównym."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj do ekranu głównego"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widżety</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widżetów</item>
@@ -105,7 +103,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementy"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, liczba elementów: <xliff:g id="SIZE">%2$d</xliff:g> lub więcej"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Style i tapety"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta i styl"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ustawienia ekranu głównego"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a104931..283529d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagens de fundo"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos e fundo"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Definições de início"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativada pelo gestor"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 35d1e5d..fd793d4 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque no widget e mantenha-o pressionado para movê-lo pela tela inicial"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar à tela inicial"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Planos de fundo"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos e planos de fundo"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Plano de fundo e estilo"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Configurações da tela inicial"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativado pelo administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index f614b18..4faa6e1 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atingeți de două ori și țineți apăsat pentru a muta un widget sau folosiți acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Atingeți lung widgetul pentru a-l muta pe ecranul de pornire"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Adăugați pe ecranul de pornire"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgeturi</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> de widgeturi</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elemente"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> sau mai multe elemente"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagini de fundal"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiluri și imagini de fundal"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Setări ecran de pornire"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permite rotirea ecranului de pornire"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 3336b0b..6b1cc6b 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Чтобы использовать специальные действия или перенести виджет, нажмите на него дважды и удерживайте."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Нажмите на виджет и удерживайте его, чтобы переместить в нужное место на главном экране."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Добавить на главный экран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виджета</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g>)"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g> или больше)"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стили и обои"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Главный экран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index fa3287d..4826639 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"එය මුල් පිටු තිරය වටා ගෙන යාමට විජට් එක ස්පර්ශ කර අල්ලා ගන්න"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"මුල් පිටු තිරය වෙත එක් කරන්න"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one">විජට් <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="other">විජට් <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ෆෝල්ඩර: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>ක් හෝ වැඩි ගණනක්"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"විලාස සහ වෝල්පේපර"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"නිවසේ සැකසීම්"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index bd90155..e23e7a9 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Po pridržaní môžete miniaplikáciu môžete posúvať po ploche"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Pridať na plochu"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> miniaplikácie</item>
<item quantity="many"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgets</item>
@@ -105,7 +103,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> položky"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> alebo viac položiek"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Štýly a tapety"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta a štýl"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Nastavenia plochy"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázané vaším správcom"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index df1db7e..40e202f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pridržite pripomoček, če ga želite premikati po začetnem zaslonu."</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na začetni zaslon"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> pripomoček</item>
<item quantity="two"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> pripomočka</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, št. elementov: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ali več elementov"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ozadja"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Slogi in ozadja"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Domače nastavitve"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogočil skrbnik."</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Omogoči sukanje začetnega zaslona"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 4d97676..68ffed6 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Prek dhe mbaj të shtypur miniaplikacionin për ta lëvizur nëpër \"Ekranin bazë\""</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Shto në \"Ekranin bazë\""</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> miniaplikacione</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> miniaplikacion</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> artikuj"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ose më shumë artikuj"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilet dhe imazhet e sfondit"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Cilësimet e ekranit bazë"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit bazë"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 4103b00..bd90dad 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двапут додирните и задржите да бисте померали виџет или користите прилагођене радње."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ширина од %1$d и висина од %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Додирните и задржите виџет да бисте га померали по почетном екрану"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Додај на почетни екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> виџета</item>
@@ -102,7 +100,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставке"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или више ставки"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Позадине"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилови и позадине"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Подешавања почетног екрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администратор је онемогућио"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index fb3e8c1..cbbd497 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tryck länge på widgeten om du vill flytta den på startskärmen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Lägg till på startskärmen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widgetar</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> objekt"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller fler objekt"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunder"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Format och bakgrunder"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Startinställningar"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 6caadaa..353d74a 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Gusa na ushikilie wijeti ili uisogeze kwenye Skrini ya kwanza"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Weka kwenye Skrini ya kwanza"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">Wijeti <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Wijeti <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g></item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g> au zaidi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mandhari"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mitindo na mandhari"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Mipangilio ya mwanzo"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Imezimwa na msimamizi wako"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml
deleted file mode 100644
index d50115b..0000000
--- a/res/values-sw600dp/config.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
- <bool name="allow_rotation">true</bool>
-
- <!-- Hotseat -->
- <bool name="hotseat_transpose_layout_with_orientation">false</bool>
-</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index ead666c..47a88f2 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -3,7 +3,7 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ You may obtain a copy of the License at`
http://www.apache.org/licenses/LICENSE-2.0
@@ -15,13 +15,6 @@
-->
<resources>
-<!-- All Apps -->
- <dimen name="all_apps_background_canvas_width">850dp</dimen>
- <dimen name="all_apps_background_canvas_height">525dp</dimen>
-
-<!-- Widget tray -->
- <dimen name="widget_section_indent">56dp</dimen>
-
<!-- DragController -->
<dimen name="drag_flingToDeleteMinVelocity">-1000dp</dimen>
</resources>
diff --git a/res/values-sw720dp/config.xml b/res/values-sw720dp/config.xml
deleted file mode 100644
index 33fc553..0000000
--- a/res/values-sw720dp/config.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<resources>
-
-<!-- All Apps & Widgets -->
- <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
- <integer name="config_workspaceSpringLoadShrinkPercentage">90</integer>
-</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
deleted file mode 100644
index 691219a..0000000
--- a/res/values-sw720dp/dimens.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <!-- All Apps -->
- <dimen name="all_apps_empty_search_message_top_offset">64dp</dimen>
- <dimen name="all_apps_empty_search_bg_top_offset">180dp</dimen>
-
- <!-- Fast scroll -->
- <dimen name="fastscroll_popup_width">75dp</dimen>
- <dimen name="fastscroll_popup_height">62dp</dimen>
- <dimen name="fastscroll_popup_padding">13dp</dimen>
- <dimen name="fastscroll_popup_text_size">32dp</dimen>
-
-</resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
deleted file mode 100644
index c1e6eca..0000000
--- a/res/values-sw720dp/styles.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2008 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
- <!-- Workspace -->
- <style name="DropTargetButton" parent="DropTargetButtonBase">
- <item name="android:paddingLeft">60dp</item>
- <item name="android:paddingRight">60dp</item>
- <item name="android:shadowDx">0.0</item>
- <item name="android:shadowDy">0.0</item>
- <item name="android:shadowRadius">2.0</item>
- </style>
-</resources>
\ No newline at end of file
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index a2bc2c5..2badf10 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"முகப்புத் திரைக்கு விட்ஜெட்டை நகர்த்த அதைத் தொட்டுப் பிடிக்கவும்"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"முகப்புத் திரையில் சேர்"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> விட்ஜெட்டுகள்</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> விட்ஜெட்</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> கோப்புகள்"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> அல்லது அதற்கு அதிகமான கோப்புகள்"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ஸ்டைல்கள் & வால்பேப்பர்கள்"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"முகப்பு அமைப்புகள்"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 478bd02..6b4094d 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"విడ్జెట్ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి & హోల్డ్ చేయి."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"విడ్జెట్ను మొదటి స్క్రీన్ చుట్టూ తిప్పడానికి దాన్ని తాకి, & నొక్కి ఉంచండి"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"మొదటి స్క్రీన్కు జోడించు"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> విడ్జెట్లు</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> విడ్జెట్</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ఐటెమ్లు"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> లేదా అంతకంటే ఎక్కువ ఐటెమ్లు"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్పేపర్లు"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"స్టయిల్స్ & వాల్పేపర్లు"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"హోమ్ సెట్టింగ్లు"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ రొటేషన్ను అనుమతించండి"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 1b79b9c..905d5a1 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"แตะสองครั้งค้างไว้เพื่อย้ายวิดเจ็ตหรือใช้การดำเนินการที่กำหนดเอง"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"กว้าง %1$d x สูง %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"แตะวิดเจ็ตค้างไว้เพื่อย้ายไปรอบๆ หน้าจอหลัก"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"เพิ่มลงในหน้าจอหลัก"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other">วิดเจ็ต <xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> รายการ</item>
<item quantity="one">วิดเจ็ต <xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> รายการ</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, อย่างน้อย <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"รูปแบบและวอลเปเปอร์"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"การตั้งค่าหน้าแรก"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 58e8c8a..a3dc55d 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pindutin nang matagal ang widget para ilipat-lipat ito sa Home screen"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Idagdag sa Home screen"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> na widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> (na) item"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o higit pang item"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mga Wallpaper"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mga istilo at wallpaper"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Mga setting ng Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Na-disable ng iyong admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index bc6ad44..94b5574 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Ana ekranda taşımak için widget\'a dokunup basılı tutun"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Ana ekrana ekle"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> widget</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> widget</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> öğe"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> veya daha fazla öğe"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Duvar Kağıtları"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiller ve duvar kağıtları"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Ana ekran ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index fdba5e61..371a583 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина – %1$d, висота – %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Натисніть і втримуйте віджет, щоб переміщувати його головним екраном"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Додати на головний екран"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджет</item>
<item quantity="few"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> віджети</item>
@@ -105,7 +103,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g> або більше"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Фонові малюнки"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стиль і фон"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Налаштування головного екрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 8cc578c..890bc68 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"ویجیٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d چوڑا اور %2$d اونچا"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ویجیٹ کو ہوم اسکرین کے چاروں طرف منتقل کرنے کیلئے اسے ٹچ کریں اور دبائے رکھیں"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"ہوم اسکرین میں شامل کریں"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ویجیٹس</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ویجیٹ</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> آئٹمز"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> یا مزید آئٹمز"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"طرزیں اور وال پیپر"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"ہوم ترتیبات"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 1ab449d..7f0ced4 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Bosh ekranda surish uchun vidjet ustiga bosib turing"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Bosh ekranga chiqarish"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> ta vidjet</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> ta vidjet</item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> fayllar"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> va undan ortiq fayllar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mavzu va fon rasmlari"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fon rasmi va stili"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Bosh ekran sozlamalari"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Bosh ekranni burishga ruxsat"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index acb101b..495b4e4 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Chạm và giữ để di chuyển tiện ích xung quanh Màn hình chính"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Thêm vào Màn hình chính"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> tiện ích</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> tiện ích</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục trở lên"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hình nền"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Kiểu và hình nền"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"Cài đặt màn hình chính"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Bị tắt bởi quản trị viên của bạn"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index d79f181..86685b5 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"宽 %1$d,高 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"轻触并按住该微件即可将其在主屏幕上四处移动"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"添加到主屏幕"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 个微件</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 个微件</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个项目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个或更多项目"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"样式和壁纸"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"主屏幕设置"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 5b06896..9334b8e 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d 闊,%2$d 高"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可將其移至主畫面上任何位置"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"新增至主畫面"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 個小工具</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 個小工具</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個或以上的項目"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"樣式和桌布"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由您的管理員停用"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 9566a8c..da1743f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -32,10 +32,8 @@
<string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"寬度為 %1$d,高度為 %2$d"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可將小工具移到主畫面的任一位置"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"新增到主畫面"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="other"><xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g> 項小工具</item>
<item quantity="one"><xliff:g id="WIDGETS_COUNT_0">%1$d</xliff:g> 項小工具</item>
@@ -99,7 +97,8 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個以上的項目"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"樣式和桌布"</string>
+ <!-- no translation found for styles_wallpaper_button_text (8216961355289236794) -->
+ <skip />
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主畫面"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 0da9ed7..dbdcf17 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -32,10 +32,8 @@
<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>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
- <!-- no translation found for add_item_request_drag_hint (5653291305078645405) -->
- <skip />
- <!-- no translation found for add_to_home_screen (8631549138215492708) -->
- <skip />
+ <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Thinta uphinde ubambe iwijethi ukuyihambisa Kusikrini sasekhaya"</string>
+ <string name="add_to_home_screen" msgid="8631549138215492708">"Engeza kusikrini sasekhaya"</string>
<plurals name="widgets_count" formatted="false" msgid="656794749266073027">
<item quantity="one">Amawijethi angu-<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Amawijethi angu-<xliff:g id="WIDGETS_COUNT_1">%1$d</xliff:g></item>
@@ -99,7 +97,7 @@
<string name="folder_name_format_exact" msgid="8626242716117004803">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> izinto"</string>
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> noma izinto eziningi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Izithombe zangemuva"</string>
- <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Izitayela nezithombe zangemuva"</string>
+ <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Isithombe sangemuva nesitayela"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Izilungiselelo zasekhaya"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Kukhutshazwe umlawuli wakho"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 93d88c2..a81802d 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -127,17 +127,24 @@
<!-- numFolderRows & numFolderColumns defaults to numRows & numColumns, if not specified -->
<attr name="numFolderRows" format="integer" />
<attr name="numFolderColumns" format="integer" />
+ <!-- numAllAppsColumns defaults to numColumns, if not specified -->
+ <attr name="numAllAppsColumns" format="integer" />
+ <!-- Number of columns to use when extending the all-apps size,
+ defaults to 2 * numAllAppsColumns -->
+ <attr name="numExtendedAllAppsColumns" format="integer" />
+
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
+ <!-- Number of icons to use when extending the hotseat size,
+ defaults to 2 * numHotseatIcons -->
+ <attr name="numExtendedHotseatIcons" format="integer" />
+
<attr name="dbFile" format="string" />
<attr name="defaultLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
<attr name="isScalable" format="boolean" />
<attr name="devicePaddingId" format="reference" />
- <!-- whether the grid option is shown to the user -->
- <attr name="visible" format="boolean" />
-
</declare-styleable>
<declare-styleable name="DevicePadding">
@@ -167,8 +174,12 @@
<attr name="iconTextSize" format="float" />
<!-- landscapeIconTextSize defaults to iconTextSize, if not specified -->
<attr name="landscapeIconTextSize" format="float" />
- <!-- If true, this display option is used to determine the default grid -->
- <attr name="canBeDefault" format="boolean" />
+
+ <!-- If set, this display option is used to determine the default grid -->
+ <attr name="canBeDefault" format="boolean|integer" >
+ <!-- The profile can be default on split display devices -->
+ <flag name="split_display" value="0x2" />
+ </attr>
<!-- The following values are only enabled if grid is supported. -->
<!-- allAppsIconSize defaults to iconSize, if not specified -->
@@ -176,11 +187,6 @@
<!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
<attr name="allAppsIconTextSize" format="float" />
- <!-- numAllAppsColumns defaults to GridDisplayOption.numColumns, if not specified -->
- <attr name="numAllAppsColumns" format="integer" />
-
- <!-- numShownHotseatIcons defaults to GridDisplayOption.numHotseatIcons, if not specified -->
- <attr name="numShownHotseatIcons" format="integer" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 83d2deb..56a0e6b 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -58,5 +58,6 @@
<color name="text_color_tertiary_dark">#CCFFFFFF</color>
<color name="wallpaper_popup_scrim">?android:attr/colorAccent</color>
+ <color name="wallpaper_scrim_color">#0D878787</color>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index f8a517d..e65c652 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,7 +1,6 @@
<resources>
<!-- Miscellaneous -->
<bool name="config_largeHeap">false</bool>
- <bool name="allow_rotation">false</bool>
<integer name="extracted_color_gradient_alpha">153</integer>
@@ -35,7 +34,7 @@
<!-- Workspace -->
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->
- <integer name="config_dragOutlineFadeTime">900</integer>
+ <integer name="config_dragOutlineFadeTime">500</integer>
<!-- The alpha value at which to show the most recent drop visualization outline. -->
<integer name="config_dragOutlineMaxAlpha">255</integer>
@@ -55,9 +54,6 @@
<!-- The duration of the caret animation -->
<integer name="config_caretAnimationDuration">200</integer>
- <!-- Hotseat -->
- <bool name="hotseat_transpose_layout_with_orientation">true</bool>
-
<!-- Various classes overriden by projects/build flavors. -->
<string name="folder_name_provider_class" translatable="false"></string>
<string name="stats_log_manager_class" translatable="false"></string>
@@ -80,11 +76,6 @@
<!-- Menu id for feature flags -->
<item type="id" name="menu_apply_flags" />
- <!-- Popup items -->
- <integer name="config_popupOpenCloseDuration">150</integer>
- <integer name="config_popupArrowOpenCloseDuration">40</integer>
- <integer name="config_removeNotificationViewDuration">300</integer>
-
<!-- Default packages -->
<string name="wallpaper_picker_package" translatable="false"></string>
<string name="local_colors_extraction_class" translatable="false"></string>
@@ -145,7 +136,7 @@
<item name="swipe_up_trans_y_stiffness" type="dimen" format="float">200</item>
<item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
- <item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">100</item>
+ <item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
<item name="swipe_up_rect_2_x_damping_ratio" type="dimen" format="float">1</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index dd14eaa..3267a5d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -91,7 +91,9 @@
<dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
<dimen name="all_apps_background_canvas_width">700dp</dimen>
<dimen name="all_apps_background_canvas_height">475dp</dimen>
- <dimen name="all_apps_header_tab_height">50dp</dimen>
+ <dimen name="all_apps_header_pill_height">50dp</dimen>
+ <dimen name="all_apps_header_pill_corner_radius">48dp</dimen>
+ <dimen name="all_apps_header_tab_height">48dp</dimen>
<dimen name="all_apps_tabs_indicator_height">2dp</dimen>
<dimen name="all_apps_header_top_padding">36dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
@@ -136,7 +138,6 @@
<dimen name="widget_section_icon_size">40dp</dimen>
<dimen name="widget_section_vertical_padding">8dp</dimen>
<dimen name="widget_section_horizontal_padding">16dp</dimen>
- <dimen name="widget_section_indent">0dp</dimen>
<dimen name="widget_row_padding">8dp</dimen>
<dimen name="widget_row_divider">2dp</dimen>
@@ -293,7 +294,7 @@
<dimen name="overview_task_margin">0dp</dimen>
<!-- Workspace grid visualization parameters -->
- <dimen name="grid_visualization_rounding_radius">28dp</dimen>
+ <dimen name="grid_visualization_rounding_radius">22dp</dimen>
<dimen name="grid_visualization_cell_spacing">6dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d6936ab..eae32b7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -221,7 +221,7 @@
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
<string name="wallpaper_button_text">Wallpapers</string>
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
- <string name="styles_wallpaper_button_text">Styles & wallpapers</string>
+ <string name="styles_wallpaper_button_text">Wallpaper & style</string>
<!-- Text for settings button [CHAR LIMIT=30]-->
<string name="settings_button_text">Home settings</string>
<!-- Message shown when a feature is disabled by the administrator -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 97a5760..dd72114 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -42,7 +42,7 @@
<item name="isWorkspaceDarkText">false</item>
<item name="workspaceTextColor">@color/workspace_text_color_light</item>
<item name="workspaceShadowColor">#B0000000</item>
- <item name="workspaceAmbientShadowColor">#00000000</item>
+ <item name="workspaceAmbientShadowColor">#40000000</item>
<item name="workspaceKeyShadowColor">#89000000</item>
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
@@ -93,7 +93,7 @@
<item name="android:textColorSecondary">@color/text_color_secondary_dark</item>
<item name="android:textColorTertiary">@color/text_color_tertiary_dark</item>
<item name="android:textColorHint">#A0FFFFFF</item>
- <item name="android:colorControlHighlight">#A0FFFFFF</item>
+ <item name="android:colorControlHighlight">#19FFFFFF</item>
<item name="android:colorPrimary">#FF212121</item>
<item name="allAppsScrimColor">?android:attr/colorBackgroundFloating</item>
<item name="allAppsNavBarScrimColor">#80000000</item>
@@ -123,7 +123,7 @@
</style>
<style name="LauncherTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark">
- <item name="android:colorControlHighlight">#75212121</item>
+ <item name="android:colorControlHighlight">#19212121</item>
<item name="folderFillColor">#CDFFFFFF</item>
<item name="folderTextColor">?attr/workspaceTextColor</item>
<item name="workspaceTextColor">@color/workspace_text_color_dark</item>
@@ -241,7 +241,7 @@
<item name="android:shadowRadius">2.0</item>
<item name="android:shadowColor">?attr/workspaceShadowColor</item>
<item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
- <item name="ambientShadowBlur">2.5dp</item>
+ <item name="ambientShadowBlur">1.5dp</item>
<item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
<item name="keyShadowBlur">.5dp</item>
<item name="keyShadowOffsetX">.5dp</item>
@@ -274,12 +274,12 @@
<style name="AllAppsEmptySearchBackground">
<item name="android:colorPrimary">#E0E0E0</item>
- <item name="android:colorControlHighlight">#BDBDBD</item>
+ <item name="android:colorControlHighlight">#19BDBDBD</item>
<item name="android:colorForeground">@color/all_apps_bg_hand_fill</item>
</style>
<style name="AllAppsEmptySearchBackground.Dark">
<item name="android:colorPrimary">#9AA0A6</item>
- <item name="android:colorControlHighlight">#DFE1E5</item>
+ <item name="android:colorControlHighlight">#19DFE1E5</item>
<item name="android:colorForeground">@color/all_apps_bg_hand_fill_dark</item>
</style>
diff --git a/res/xml/dynamic_resources.xml b/res/xml/dynamic_resources.xml
index f5d2628..3a3e239 100644
--- a/res/xml/dynamic_resources.xml
+++ b/res/xml/dynamic_resources.xml
@@ -4,6 +4,6 @@
<entry id="@color/delete_target_hover_tint" />
<entry id="@color/delete_target_hover_tint" />
<entry id="@color/delete_target_hover_tint" />
+ <entry id="@color/wallpaper_scrim_color" />
-
-</DynamicResources>
\ No newline at end of file
+</DynamicResources>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 8195cc1..90de498 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -45,7 +45,7 @@
android:key="pref_allowRotation"
android:title="@string/allow_rotation_title"
android:summary="@string/allow_rotation_desc"
- android:defaultValue="@bool/allow_rotation"
+ android:defaultValue="false"
android:persistent="true"
launcher:logIdOn="615"
launcher:logIdOff="616" />
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
index 344f532..b58e4b7 100644
--- a/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
@@ -18,11 +18,15 @@
import android.content.Context;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.uioverrides.DeviceFlag;
import com.android.launcher3.util.LooperExecutor;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
/**
* Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
@@ -30,6 +34,9 @@
@Implements(value = DeviceFlag.class, isInAndroidSdk = false)
public class ShadowDeviceFlag {
+ @RealObject private DeviceFlag mRealObject;
+ @Nullable private Boolean mValue;
+
/**
* Mock change listener as it uses internal system classes not available to robolectric
*/
@@ -40,4 +47,16 @@
protected static boolean getDeviceValue(String key, boolean defaultValue) {
return defaultValue;
}
+
+ @Implementation
+ public boolean get() {
+ if (mValue != null) {
+ return mValue;
+ }
+ return Shadow.directlyOn(mRealObject, DeviceFlag.class, "get");
+ }
+
+ public void setValue(boolean value) {
+ mValue = new Boolean(value);
+ }
}
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
index 4d151f1..ea75548 100644
--- a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
+++ b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
@@ -161,7 +161,7 @@
private static MotionEvent createScrollEvent(int scroll) {
DeviceProfile dp = InvariantDeviceProfile.INSTANCE
- .get(RuntimeEnvironment.application).portraitProfile;
+ .get(RuntimeEnvironment.application).supportedProfiles.get(0);
final PointerProperties[] pointerProperties = new PointerProperties[1];
pointerProperties[0] = new PointerProperties();
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index 92f77f2..d977011 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -17,6 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+
import android.content.Context;
import android.graphics.Point;
@@ -109,10 +112,14 @@
private InvariantDeviceProfile createIDP() {
DeviceProfile profile = Mockito.mock(DeviceProfile.class);
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(CELL_SIZE, CELL_SIZE);
+ return null;
+ }).when(profile).getCellSize(any(Point.class));
Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
InvariantDeviceProfile idp = new InvariantDeviceProfile();
- idp.landscapeProfile = idp.portraitProfile = profile;
+ idp.supportedProfiles.add(profile);
return idp;
}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 95cdbdd..32b2c9a 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -39,6 +39,7 @@
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.LocalColorExtractor;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -108,12 +109,21 @@
protected boolean mIsOpen;
+ // Index used to get background color when using local wallpaper color extraction.
+ protected int mColorExtractionIndex;
+
public AbstractFloatingView(Context context, AttributeSet attrs) {
super(context, attrs);
+ init(context);
}
public AbstractFloatingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ private void init(Context context) {
+ mColorExtractionIndex = LocalColorExtractor.getColorIndex(context);
}
/**
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 5d41bb5..c1f3ac5 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -1,5 +1,7 @@
package com.android.launcher3;
+import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget;
+
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH;
import static com.android.launcher3.Utilities.ATLEAST_S;
@@ -10,7 +12,9 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
@@ -25,16 +29,14 @@
import android.widget.ImageButton;
import android.widget.ImageView;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
public class AppWidgetResizeFrame extends AbstractFloatingView implements View.OnKeyListener {
private static final int SNAP_DURATION = 150;
@@ -43,22 +45,6 @@
private static final Rect sTmpRect = new Rect();
- // Represents the cell size on the grid in the two orientations.
- public static final MainThreadInitializedObject<Point[]> CELL_SIZE =
- new MainThreadInitializedObject<>(c -> {
- InvariantDeviceProfile inv = LauncherAppState.getIDP(c);
- return new Point[] {inv.landscapeProfile.getCellSize(),
- inv.portraitProfile.getCellSize()};
- });
-
- // Represents the border spacing size on the grid in the two orientations.
- public static final MainThreadInitializedObject<int[]> BORDER_SPACING_SIZE =
- new MainThreadInitializedObject<>(c -> {
- InvariantDeviceProfile inv = LauncherAppState.getIDP(c);
- return new int[] {inv.landscapeProfile.cellLayoutBorderSpacingPx,
- inv.portraitProfile.cellLayoutBorderSpacingPx};
- });
-
private static final int HANDLE_COUNT = 4;
private static final int INDEX_LEFT = 0;
private static final int INDEX_TOP = 1;
@@ -71,6 +57,22 @@
private final View[] mDragHandles = new View[HANDLE_COUNT];
private final List<Rect> mSystemGestureExclusionRects = new ArrayList<>(HANDLE_COUNT);
+ private final OnAttachStateChangeListener mWidgetViewAttachStateChangeListener =
+ new OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ // Do nothing
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ // When the app widget view is detached, we should close the resize frame.
+ // An example is when the dragging starts, the widget view is detached from
+ // CellLayout and then reattached to DragLayout.
+ close(false);
+ }
+ };
+
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
@@ -191,7 +193,11 @@
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
DragLayer dragLayer) {
mCellLayout = cellLayout;
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
mWidgetView = widgetView;
+ mWidgetView.addOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo)
widgetView.getAppWidgetInfo();
mResizeMode = info.resizeMode;
@@ -202,7 +208,7 @@
mMaxHSpan = info.maxSpanX;
mMaxVSpan = info.maxSpanY;
- mWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(getContext(),
+ mWidgetPadding = getDefaultPaddingForWidget(getContext(),
widgetView.getAppWidgetInfo().provider, null);
if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) {
@@ -392,81 +398,82 @@
mWidgetView.requestLayout();
}
- public static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher,
- int spanX, int spanY) {
- List<SizeF> sizes = getWidgetSizes(launcher, spanX, spanY);
+ public static void updateWidgetSizeRanges(
+ AppWidgetHostView widgetView, Context context, int spanX, int spanY) {
+ List<SizeF> sizes = getWidgetSizes(context, spanX, spanY);
if (ATLEAST_S) {
widgetView.updateAppWidgetSize(new Bundle(), sizes);
} else {
- Rect bounds = getMinMaxSizes(sizes, null /* outRect */);
+ Rect bounds = getMinMaxSizes(sizes);
widgetView.updateAppWidgetSize(new Bundle(), bounds.left, bounds.top, bounds.right,
bounds.bottom);
}
}
- private static SizeF getWidgetSize(Context context, Point cellSize, int spanX, int spanY,
- int borderSpacing) {
- final float density = context.getResources().getDisplayMetrics().density;
- final float hBorderSpacing = (spanX - 1) * borderSpacing;
- final float vBorderSpacing = (spanY - 1) * borderSpacing;
-
- return new SizeF(((spanX * cellSize.x) + hBorderSpacing) / density,
- ((spanY * cellSize.y) + vBorderSpacing) / density);
- }
-
/** Returns the list of sizes for a widget of given span, in dp. */
public static ArrayList<SizeF> getWidgetSizes(Context context, int spanX, int spanY) {
- final Point[] cellSize = CELL_SIZE.get(context);
- final int[] borderSpacing = BORDER_SPACING_SIZE.get(context);
-
- SizeF landSize = getWidgetSize(context, cellSize[0], spanX, spanY, borderSpacing[0]);
- SizeF portSize = getWidgetSize(context, cellSize[1], spanX, spanY, borderSpacing[1]);
-
ArrayList<SizeF> sizes = new ArrayList<>(2);
- sizes.add(landSize);
- sizes.add(portSize);
+ final float density = context.getResources().getDisplayMetrics().density;
+ Point cellSize = new Point();
+
+ for (DeviceProfile profile : LauncherAppState.getIDP(context).supportedProfiles) {
+ final float hBorderSpacing = (spanX - 1) * profile.cellLayoutBorderSpacingPx;
+ final float vBorderSpacing = (spanY - 1) * profile.cellLayoutBorderSpacingPx;
+ profile.getCellSize(cellSize);
+ sizes.add(new SizeF(
+ ((spanX * cellSize.x) + hBorderSpacing) / density,
+ ((spanY * cellSize.y) + vBorderSpacing) / density));
+ }
return sizes;
}
/**
+ * Returns the bundle to be used as the default options for a widget with provided size
+ */
+ public static Bundle getWidgetSizeOptions(
+ Context context, ComponentName provider, int spanX, int spanY) {
+ ArrayList<SizeF> sizes = getWidgetSizes(context, spanX, spanY);
+ Rect padding = getDefaultPaddingForWidget(context, provider, null);
+ float density = context.getResources().getDisplayMetrics().density;
+ float xPaddingDips = (padding.left + padding.right) / density;
+ float yPaddingDips = (padding.top + padding.bottom) / density;
+
+ ArrayList<SizeF> paddedSizes = sizes.stream()
+ .map(size -> new SizeF(
+ Math.max(0.f, size.getWidth() - xPaddingDips),
+ Math.max(0.f, size.getHeight() - yPaddingDips)))
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ Rect rect = AppWidgetResizeFrame.getMinMaxSizes(paddedSizes);
+ Bundle options = new Bundle();
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, rect.left);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, rect.top);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, rect.right);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, rect.bottom);
+ options.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, paddedSizes);
+ return options;
+ }
+
+ /**
* Returns the min and max widths and heights given a list of sizes, in dp.
*
* @param sizes List of sizes to get the min/max from.
- * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If
- * null, a new rectangle will be allocated.
* @return A rectangle with the left (resp. top) is used for the min width (resp. height) and
* the right (resp. bottom) for the max. The returned rectangle is set with 0s if the list is
* empty.
*/
- public static Rect getMinMaxSizes(List<SizeF> sizes, @Nullable Rect outRect) {
- if (outRect == null) {
- outRect = new Rect();
- }
+ private static Rect getMinMaxSizes(List<SizeF> sizes) {
if (sizes.isEmpty()) {
- outRect.set(0, 0, 0, 0);
+ return new Rect();
} else {
SizeF first = sizes.get(0);
- outRect.set((int) first.getWidth(), (int) first.getHeight(), (int) first.getWidth(),
- (int) first.getHeight());
+ Rect result = new Rect((int) first.getWidth(), (int) first.getHeight(),
+ (int) first.getWidth(), (int) first.getHeight());
for (int i = 1; i < sizes.size(); i++) {
- outRect.union((int) sizes.get(i).getWidth(), (int) sizes.get(i).getHeight());
+ result.union((int) sizes.get(i).getWidth(), (int) sizes.get(i).getHeight());
}
+ return result;
}
- return outRect;
- }
-
- /**
- * Returns the range of sizes a widget may be displayed, given its span.
- *
- * @param context Context in which the View is rendered.
- * @param spanX Width of the widget, in cells.
- * @param spanY Height of the widget, in cells.
- * @param outRect Rectangle in which the result can be stored, to avoid extra allocations. If
- * null, a new rectangle will be allocated.
- */
- public static Rect getWidgetSizeRanges(Context context, int spanX, int spanY,
- @Nullable Rect outRect) {
- return getMinMaxSizes(getWidgetSizes(context, spanX, spanY), outRect);
}
@Override
@@ -641,6 +648,9 @@
@Override
protected void handleClose(boolean animate) {
mDragLayer.removeView(this);
+ if (mWidgetView != null) {
+ mWidgetView.removeOnAttachStateChangeListener(mWidgetViewAttachStateChangeListener);
+ }
}
@Override
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index f64ce5c..9778b61 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -132,6 +132,7 @@
private final ViewCache mViewCache = new ViewCache();
+ @Override
public ViewCache getViewCache() {
return mViewCache;
}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 2ace796..3d044d6 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -317,7 +317,8 @@
@UiThread
protected void applyIconAndLabel(ItemInfoWithIcon info) {
- FastBitmapDrawable iconDrawable = info.newIcon(getContext());
+ boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER;
+ FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme);
mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
setIcon(iconDrawable);
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 00317f7..af77bf8 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -74,7 +74,6 @@
protected final Launcher mLauncher;
- private int mBottomDragPadding;
protected DropTargetBar mDropTargetBar;
/** Whether this drop target is active for the current drag */
@@ -103,7 +102,6 @@
mLauncher = Launcher.getLauncher(context);
Resources resources = getResources();
- mBottomDragPadding = resources.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
}
@@ -276,7 +274,7 @@
@Override
public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
super.getHitRect(outRect);
- outRect.bottom += mBottomDragPadding;
+ outRect.bottom += mLauncher.getDeviceProfile().dropTargetDragPaddingPx;
sTempCords[0] = sTempCords[1] = 0;
mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index a037675..1df9df6 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -195,6 +195,7 @@
private final Rect mTempRect = new Rect();
private final RectF mTempRectF = new RectF();
+ private final float[] mTmpFloatArray = new float[4];
private static final Paint sPaint = new Paint();
@@ -504,7 +505,7 @@
}
private void updateBgAlpha() {
- mBackground.setAlpha((int) (mSpringLoadedProgress * mScrollProgress * 255));
+ mBackground.setAlpha((int) (mSpringLoadedProgress * 255));
}
/**
@@ -527,9 +528,12 @@
}
protected void visualizeGrid(Canvas canvas) {
- mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding,
- mCellWidth - mGridVisualizationPadding,
- mCellHeight - mGridVisualizationPadding);
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding);
+ int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding);
+ mVisualizeGridRect.set(paddingX, paddingY,
+ mCellWidth - paddingX,
+ mCellHeight - paddingY);
mVisualizeGridPaint.setStrokeWidth(8);
int paintAlpha = (int) (120 * mGridAlpha);
@@ -539,9 +543,9 @@
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
int transX = i * mCellWidth + (i * mBorderSpacing) + getPaddingLeft()
- + mGridVisualizationPadding;
+ + paddingX;
int transY = j * mCellHeight + (j * mBorderSpacing) + getPaddingTop()
- + mGridVisualizationPadding;
+ + paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
mVisualizeGridPaint.setStyle(Paint.Style.FILL);
@@ -562,14 +566,14 @@
int spanX = mDragOutlines[i].cellHSpan;
int spanY = mDragOutlines[i].cellVSpan;
- mVisualizeGridRect.set(mGridVisualizationPadding, mGridVisualizationPadding,
- mCellWidth * spanX - mGridVisualizationPadding,
- mCellHeight * spanY - mGridVisualizationPadding);
+ mVisualizeGridRect.set(paddingX, paddingY,
+ mCellWidth * spanX - paddingX,
+ mCellHeight * spanY - paddingY);
int transX = x * mCellWidth + (x * mBorderSpacing)
- + getPaddingLeft() + mGridVisualizationPadding;
+ + getPaddingLeft() + paddingX;
int transY = y * mCellHeight + (y * mBorderSpacing)
- + getPaddingTop() + mGridVisualizationPadding;
+ + getPaddingTop() + paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
@@ -1077,7 +1081,7 @@
// Now get the rect in drag layer coordinates.
getBoundsForViewInDragLayer(launcher.getDragLayer(), workspace, mTempRect, false,
- mTempRectF);
+ mTmpFloatArray, mTempRectF);
Utilities.setRect(mTempRectF, mTempRect);
((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index fd97936..e5ad243 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,10 +16,12 @@
package com.android.launcher3;
+import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -31,7 +33,6 @@
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Surface;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -42,7 +43,6 @@
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.WindowBounds;
@@ -52,9 +52,6 @@
@SuppressLint("NewApi")
public class DeviceProfile {
- private static final float TABLET_MIN_DPS = 600;
- private static final float LARGE_TABLET_MIN_DPS = 720;
-
private static final int DEFAULT_DOT_SIZE = 100;
public final InvariantDeviceProfile inv;
@@ -63,9 +60,10 @@
// Device properties
public final boolean isTablet;
- public final boolean isLargeTablet;
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
+ public final boolean isTwoPanels;
+ public final boolean allowRotation;
// Device properties in current orientation
public final boolean isLandscape;
@@ -164,6 +162,7 @@
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
+ public final int numShownAllAppsColumns;
public float allAppsIconTextSizePx;
// Overview
@@ -176,6 +175,8 @@
// Drop Target
public int dropTargetBarSizePx;
+ public int dropTargetDragPaddingPx;
+ public int dropTargetTextSizePx;
// Insets
private final Rect mInsets = new Rect();
@@ -194,42 +195,38 @@
// How much of the bottom inset is due to Taskbar rather than other system elements.
public int nonOverlappingTaskbarInset;
- DeviceProfile(Context context, InvariantDeviceProfile inv, Info info,
- Point minSize, Point maxSize, int width, int height, boolean isLandscape,
+ // DragController
+ public int flingToDeleteThresholdVelocity;
+
+ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
- Point windowPosition) {
+ boolean useTwoPanels) {
this.inv = inv;
- this.isLandscape = isLandscape;
+ this.isLandscape = windowBounds.isLandscape();
this.isMultiWindowMode = isMultiWindowMode;
this.transposeLayoutWithOrientation = transposeLayoutWithOrientation;
- windowX = windowPosition.x;
- windowY = windowPosition.y;
+ windowX = windowBounds.bounds.left;
+ windowY = windowBounds.bounds.top;
isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
// Determine sizes.
- widthPx = width;
- heightPx = height;
- int nonFinalAvailableHeightPx;
- if (isLandscape) {
- availableWidthPx = maxSize.x;
- nonFinalAvailableHeightPx = minSize.y;
- } else {
- availableWidthPx = minSize.x;
- nonFinalAvailableHeightPx = maxSize.y;
- }
+ widthPx = windowBounds.bounds.width();
+ heightPx = windowBounds.bounds.height();
+ availableWidthPx = windowBounds.availableSize.x;
+ int nonFinalAvailableHeightPx = windowBounds.availableSize.y;
mInfo = info;
+ // If the device's pixel density was scaled (usually via settings for A11y), use the
+ // original dimensions to determine if rotation is allowed of not.
+ float originalSmallestWidth = dpiFromPx(Math.min(widthPx, heightPx), DENSITY_DEVICE_STABLE);
+ allowRotation = originalSmallestWidth >= MIN_TABLET_WIDTH;
+ // Tablet UI does not support emulated landscape.
+ isTablet = allowRotation && info.isTablet(windowBounds);
+ isPhone = !isTablet;
+ isTwoPanels = isTablet && useTwoPanels;
- // Constants from resources
- float swDPs = dpiFromPx(Math.min(info.smallestSize.x, info.smallestSize.y),
- info.densityDpi);
- boolean allowRotation = context.getResources().getBoolean(R.bool.allow_rotation);
- // Tablet UI is built with assumption that simulated landscape is disabled.
- isTablet = allowRotation && swDPs >= TABLET_MIN_DPS;
- isLargeTablet = isTablet && swDPs >= LARGE_TABLET_MIN_DPS;
- isPhone = !isTablet && !isLargeTablet;
aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx);
boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0;
@@ -284,7 +281,7 @@
? 0
: res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
- if (FeatureFlags.ENABLE_TWO_PANEL_HOME.get() && isTablet) {
+ if (isTwoPanels) {
cellLayoutPaddingLeftRightPx =
res.getDimensionPixelSize(R.dimen.two_panel_home_side_padding);
cellLayoutBottomPaddingPx = 0;
@@ -303,13 +300,20 @@
iconDrawablePaddingOriginalPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
+
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
+ dropTargetDragPaddingPx = res.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
+ dropTargetTextSizePx = res.getDimensionPixelSize(R.dimen.drop_target_text_size);
+
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
- numShownHotseatIcons = inv.numShownHotseatIcons;
+ numShownHotseatIcons =
+ isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
+ numShownAllAppsColumns =
+ isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
hotseatBarBottomPaddingPx = (isTallDevice ? 0
@@ -367,6 +371,9 @@
}
updateWorkspacePadding();
+ flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
+ R.dimen.drag_flingToDeleteMinVelocity);
+
// This is done last, after iconSizePx is calculated above.
Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
@@ -393,11 +400,12 @@
}
public Builder toBuilder(Context context) {
- Point size = new Point(availableWidthPx, availableHeightPx);
+ WindowBounds bounds =
+ new WindowBounds(widthPx, heightPx, availableWidthPx, availableHeightPx);
+ bounds.bounds.offsetTo(windowX, windowY);
return new Builder(context, inv, mInfo)
- .setSizeRange(size, size)
- .setSize(widthPx, heightPx)
- .setWindowPosition(windowX, windowY)
+ .setWindowBounds(bounds)
+ .setUseTwoPanels(isTwoPanels)
.setMultiWindowMode(isMultiWindowMode);
}
@@ -409,15 +417,8 @@
* TODO: Move this to the builder as part of setMultiWindowMode
*/
public DeviceProfile getMultiWindowProfile(Context context, WindowBounds windowBounds) {
- // We take the minimum sizes of this profile and it's multi-window variant to ensure that
- // the system decor is always excluded.
- Point mwSize = new Point(Math.min(availableWidthPx, windowBounds.availableSize.x),
- Math.min(availableHeightPx, windowBounds.availableSize.y));
-
DeviceProfile profile = toBuilder(context)
- .setSizeRange(mwSize, mwSize)
- .setSize(windowBounds.bounds.width(), windowBounds.bounds.height())
- .setWindowPosition(windowBounds.bounds.left, windowBounds.bounds.top)
+ .setWindowBounds(windowBounds)
.setMultiWindowMode(true)
.build();
@@ -434,14 +435,6 @@
}
/**
- * Inverse of {@link #getMultiWindowProfile(Context, WindowBounds)}
- * @return device profile corresponding to the current orientation in non multi-window mode.
- */
- public DeviceProfile getFullScreenProfile() {
- return isLandscape ? inv.landscapeProfile : inv.portraitProfile;
- }
-
- /**
* Checks if there is enough space for labels on the workspace.
* If there is not, labels on the Workspace are hidden.
* It is important to call this method after the All Apps variables have been set.
@@ -553,7 +546,7 @@
}
// All apps
- if (allAppsHasDifferentNumColumns()) {
+ if (numShownAllAppsColumns != inv.numColumns) {
allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mMetrics);
allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
@@ -667,18 +660,20 @@
}
public Point getCellSize() {
- return getCellSize(inv.numColumns, inv.numRows);
+ return getCellSize(null);
}
- private Point getCellSize(int numColumns, int numRows) {
- Point result = new Point();
+ public Point getCellSize(Point result) {
+ if (result == null) {
+ result = new Point();
+ }
// Since we are only concerned with the overall padding, layout direction does
// not matter.
Point padding = getTotalWorkspacePadding();
result.x = calculateCellWidth(availableWidthPx - padding.x
- - cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, numColumns);
+ - cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, inv.numColumns);
result.y = calculateCellHeight(availableHeightPx - padding.y
- - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, numRows);
+ - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows);
return result;
}
@@ -723,7 +718,7 @@
padding.set(availablePaddingX / 2, edgeMarginPx + availablePaddingY / 2,
availablePaddingX / 2, paddingBottom + availablePaddingY / 2);
- if (FeatureFlags.ENABLE_TWO_PANEL_HOME.get()) {
+ if (isTwoPanels) {
padding.set(0, padding.top, 0, padding.bottom);
}
} else {
@@ -751,7 +746,7 @@
// for this, we pad the left and right of the hotseat with half of the difference of a
// workspace cell vs a hotseat cell.
float workspaceCellWidth = (float) widthPx / inv.numColumns;
- float hotseatCellWidth = (float) widthPx / inv.numShownHotseatIcons;
+ float hotseatCellWidth = (float) widthPx / numShownHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
mHotseatPadding.set(
hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
@@ -802,13 +797,6 @@
}
/**
- * Returns true when the number of workspace columns and all apps columns differs.
- */
- private boolean allAppsHasDifferentNumColumns() {
- return inv.numAllAppsColumns != inv.numColumns;
- }
-
- /**
* Updates orientation information and returns true if it has changed from the previous value.
*/
public boolean updateIsSeascape(Context context) {
@@ -828,7 +816,7 @@
}
public boolean shouldFadeAdjacentWorkspaceScreens() {
- return isVerticalBarLayout() || isLargeTablet;
+ return isVerticalBarLayout();
}
public int getCellHeight(@ContainerType int containerType) {
@@ -853,14 +841,15 @@
writer.println(prefix + "DeviceProfile:");
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
+ writer.println(prefix + "\tallowRotation:" + allowRotation);
writer.println(prefix + "\tisTablet:" + isTablet);
- writer.println(prefix + "\tisLargeTablet:" + isLargeTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
+ transposeLayoutWithOrientation);
writer.println(prefix + "\tisLandscape:" + isLandscape);
writer.println(prefix + "\tisMultiWindowMode:" + isMultiWindowMode);
+ writer.println(prefix + "\tisTwoPanels:" + isTwoPanels);
writer.println(prefix + pxToDpStr("windowX", windowX));
writer.println(prefix + pxToDpStr("windowY", windowY));
@@ -907,6 +896,7 @@
writer.println(prefix + pxToDpStr("allAppsIconDrawablePaddingPx",
allAppsIconDrawablePaddingPx));
writer.println(prefix + pxToDpStr("allAppsCellHeightPx", allAppsCellHeightPx));
+ writer.println(prefix + "\tnumShownAllAppsColumns: " + numShownAllAppsColumns);
writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
@@ -916,6 +906,7 @@
hotseatBarSidePaddingStartPx));
writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
hotseatBarSidePaddingEndPx));
+ writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
@@ -967,41 +958,16 @@
private InvariantDeviceProfile mInv;
private Info mInfo;
- private final Point mWindowPosition = new Point();
- private Point mMinSize, mMaxSize;
- private int mWidth, mHeight;
+ private WindowBounds mWindowBounds;
+ private boolean mUseTwoPanels;
- private boolean mIsLandscape;
private boolean mIsMultiWindowMode = false;
- private boolean mTransposeLayoutWithOrientation;
+ private Boolean mTransposeLayoutWithOrientation;
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
mInv = inv;
mInfo = info;
- mTransposeLayoutWithOrientation = context.getResources()
- .getBoolean(R.bool.hotseat_transpose_layout_with_orientation);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "transposeLayout=" + mTransposeLayoutWithOrientation);
- }
- }
-
- public Builder setSizeRange(Point minSize, Point maxSize) {
- mMinSize = minSize;
- mMaxSize = maxSize;
- return this;
- }
-
- public Builder setSize(int width, int height) {
- mWidth = width;
- mHeight = height;
- mIsLandscape = mWidth > mHeight;
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "isLandscape=" + mIsLandscape + " w=" + mWidth + " h=" + mHeight);
- }
- return this;
}
public Builder setMultiWindowMode(boolean isMultiWindowMode) {
@@ -1009,11 +975,14 @@
return this;
}
- /**
- * Sets the window position if not full-screen
- */
- public Builder setWindowPosition(int x, int y) {
- mWindowPosition.set(x, y);
+ public Builder setUseTwoPanels(boolean useTwoPanels) {
+ mUseTwoPanels = useTwoPanels;
+ return this;
+ }
+
+
+ public Builder setWindowBounds(WindowBounds bounds) {
+ mWindowBounds = bounds;
return this;
}
@@ -1023,9 +992,14 @@
}
public DeviceProfile build() {
- return new DeviceProfile(mContext, mInv, mInfo, mMinSize, mMaxSize,
- mWidth, mHeight, mIsLandscape, mIsMultiWindowMode,
- mTransposeLayoutWithOrientation, mWindowPosition);
+ if (mWindowBounds == null) {
+ throw new IllegalArgumentException("Window bounds not set");
+ }
+ if (mTransposeLayoutWithOrientation == null) {
+ mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
+ }
+ return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds,
+ mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels);
}
}
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index c768493..4a1b084 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -25,6 +25,7 @@
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewDebug;
@@ -114,6 +115,7 @@
}
setLayoutParams(lp);
for (ButtonDropTarget button : mDropTargets) {
+ button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx);
button.setToolTipLocation(tooltipLocation);
}
}
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 4312939..20c6938 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3;
+import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
+
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -25,7 +27,7 @@
import android.widget.EditText;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.views.ActivityContext;
/**
@@ -99,7 +101,7 @@
}
public void hideKeyboard() {
- UiThreadHelper.hideKeyboardAsync(Launcher.getLauncher(getContext()), getWindowToken());
+ hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
}
private boolean showSoftInput() {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 8496fd5..b2a9e75 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -90,11 +90,11 @@
public void resetLayout(boolean hasVerticalHotseat) {
removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
- InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
+ DeviceProfile dp = mActivity.getDeviceProfile();
if (hasVerticalHotseat) {
- setGridSize(1, idp.numShownHotseatIcons);
+ setGridSize(1, dp.numShownHotseatIcons);
} else {
- setGridSize(idp.numShownHotseatIcons, 1);
+ setGridSize(dp.numShownHotseatIcons, 1);
}
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 1332e14..318dde1 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -16,20 +16,17 @@
package com.android.launcher3;
-import static com.android.launcher3.Utilities.getDevicePrefs;
+import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.getPointString;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
-import static com.android.launcher3.util.DisplayController.CHANGE_SIZE;
+import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetHostView;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -48,13 +45,13 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.WindowBounds;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -62,6 +59,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
public class InvariantDeviceProfile {
@@ -73,15 +71,13 @@
public static final String KEY_MIGRATION_SRC_WORKSPACE_SIZE = "migration_src_workspace_size";
public static final String KEY_MIGRATION_SRC_HOTSEAT_COUNT = "migration_src_hotseat_count";
+ private static final int DEFAULT_TRUE = -1;
+ private static final int DEFAULT_SPLIT_DISPLAY = 2;
+
private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
- public static final int CHANGE_FLAG_GRID = 1 << 0;
- public static final int CHANGE_FLAG_ICON_PARAMS = 1 << 1;
-
- public static final String KEY_ICON_PATH_REF = "pref_icon_shape_path";
-
// Constants that affects the interpolation curve between statically defined device profile
// buckets.
private static final float KNEARESTNEIGHBOR = 3;
@@ -90,9 +86,6 @@
// used to offset float not being able to express extremely small weights in extreme cases.
private static final float WEIGHT_EFFICIENT = 100000f;
- private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier(
- "config_icon_mask", "string", "android");
-
/**
* Number of icons per row and column in the workspace.
*/
@@ -105,7 +98,6 @@
public int numFolderRows;
public int numFolderColumns;
public float iconSize;
- public String iconShapePath;
public float landscapeIconSize;
public float landscapeIconTextSize;
public int iconBitmapSize;
@@ -136,6 +128,7 @@
* Number of columns in the all apps list.
*/
public int numAllAppsColumns;
+ public int numDatabaseAllAppsColumns;
/**
* Do not query directly. see {@link DeviceProfile#isScalableGrid}.
@@ -147,8 +140,7 @@
public int defaultLayoutId;
int demoModeLayoutId;
- public DeviceProfile landscapeProfile;
- public DeviceProfile portraitProfile;
+ public final List<DeviceProfile> supportedProfiles = new ArrayList<>();
@Nullable public DevicePaddings devicePaddings;
@@ -156,7 +148,6 @@
public Rect defaultWidgetPadding;
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
- private OverlayMonitor mOverlayMonitor;
@VisibleForTesting
public InvariantDeviceProfile() {}
@@ -167,7 +158,6 @@
numFolderRows = p.numFolderRows;
numFolderColumns = p.numFolderColumns;
iconSize = p.iconSize;
- iconShapePath = p.iconShapePath;
landscapeIconSize = p.landscapeIconSize;
iconBitmapSize = p.iconBitmapSize;
iconTextSize = p.iconTextSize;
@@ -175,6 +165,7 @@
numShownHotseatIcons = p.numShownHotseatIcons;
numDatabaseHotseatIcons = p.numDatabaseHotseatIcons;
numAllAppsColumns = p.numAllAppsColumns;
+ numDatabaseAllAppsColumns = p.numDatabaseAllAppsColumns;
isScalable = p.isScalable;
devicePaddingId = p.devicePaddingId;
minCellHeight = p.minCellHeight;
@@ -186,7 +177,6 @@
defaultLayoutId = p.defaultLayoutId;
demoModeLayoutId = p.demoModeLayoutId;
mExtraAttrs = p.mExtraAttrs;
- mOverlayMonitor = p.mOverlayMonitor;
devicePaddings = p.devicePaddings;
}
@@ -204,11 +194,10 @@
DisplayController.INSTANCE.get(context).addChangeListener(
(displayContext, info, flags) -> {
- if ((flags & (CHANGE_SIZE | CHANGE_DENSITY)) != 0) {
+ if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS)) != 0) {
onConfigChanged(displayContext);
}
});
- mOverlayMonitor = new OverlayMonitor(context);
}
/**
@@ -232,66 +221,62 @@
// Get the display info based on default display and interpolate it to existing display
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
DisplayController.INSTANCE.get(context).getInfo(),
- getPredefinedDeviceProfiles(context, gridName));
+ getPredefinedDeviceProfiles(context, gridName, false), false);
Info myInfo = new Info(context, display);
DisplayOption myDisplayOption = invDistWeightedInterpolate(
- myInfo, getPredefinedDeviceProfiles(context, gridName));
+ myInfo, getPredefinedDeviceProfiles(context, gridName, false), false);
DisplayOption result = new DisplayOption(defaultDisplayOption.grid)
.add(myDisplayOption);
result.iconSize = defaultDisplayOption.iconSize;
result.landscapeIconSize = defaultDisplayOption.landscapeIconSize;
- result.numShownHotseatIcons = myDisplayOption.numShownHotseatIcons;
if (defaultDisplayOption.allAppsIconSize < myDisplayOption.allAppsIconSize) {
result.allAppsIconSize = defaultDisplayOption.allAppsIconSize;
- result.numAllAppsColumns = defaultDisplayOption.numAllAppsColumns;
} else {
result.allAppsIconSize = myDisplayOption.allAppsIconSize;
- result.numAllAppsColumns = myDisplayOption.numAllAppsColumns;
}
result.minCellHeight = defaultDisplayOption.minCellHeight;
result.minCellWidth = defaultDisplayOption.minCellWidth;
result.borderSpacing = defaultDisplayOption.borderSpacing;
- initGrid(context, myInfo, result);
+ initGrid(context, myInfo, result, false);
}
public static String getCurrentGridName(Context context) {
- if (ENABLE_TWO_PANEL_HOME.get()) {
- return ENABLE_TWO_PANEL_HOME.key;
- }
return Utilities.isGridOptionsEnabled(context)
? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null;
}
- /**
- * Retrieve system defined or RRO overriden icon shape.
- */
- private static String getIconShapePath(Context context) {
- if (CONFIG_ICON_MASK_RES_ID == 0) {
- Log.e(TAG, "Icon mask res identifier failed to retrieve.");
- return "";
- }
- return context.getResources().getString(CONFIG_ICON_MASK_RES_ID);
- }
-
private String initGrid(Context context, String gridName) {
Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
- ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
+ // Determine if we have split display
- DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
- initGrid(context, displayInfo, displayOption);
+ boolean isTablet = false, isPhone = false;
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ if (displayInfo.isTablet(bounds)) {
+ isTablet = true;
+ } else {
+ isPhone = true;
+ }
+ }
+ boolean isSplitDisplay = isPhone && isTablet && ENABLE_TWO_PANEL_HOME.get();
+
+ ArrayList<DisplayOption> allOptions =
+ getPredefinedDeviceProfiles(context, gridName, isSplitDisplay);
+ DisplayOption displayOption =
+ invDistWeightedInterpolate(displayInfo, allOptions, isSplitDisplay);
+ initGrid(context, displayInfo, displayOption, isSplitDisplay);
return displayOption.grid.name;
}
private void initGrid(
- Context context, Info displayInfo, DisplayOption displayOption) {
+ Context context, Info displayInfo, DisplayOption displayOption,
+ boolean isSplitDisplay) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
- numDatabaseHotseatIcons = closestProfile.numDatabaseHotseatIcons;
dbFile = closestProfile.dbFile;
defaultLayoutId = closestProfile.defaultLayoutId;
demoModeLayoutId = closestProfile.demoModeLayoutId;
@@ -303,7 +288,6 @@
mExtraAttrs = closestProfile.extraAttrs;
iconSize = displayOption.iconSize;
- iconShapePath = getIconShapePath(context);
landscapeIconSize = displayOption.landscapeIconSize;
iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
iconTextSize = displayOption.iconTextSize;
@@ -313,8 +297,14 @@
minCellHeight = displayOption.minCellHeight;
minCellWidth = displayOption.minCellWidth;
borderSpacing = displayOption.borderSpacing;
- numShownHotseatIcons = Math.round(displayOption.numShownHotseatIcons);
- numAllAppsColumns = Math.round(displayOption.numAllAppsColumns);
+
+ numShownHotseatIcons = closestProfile.numHotseatIcons;
+ numDatabaseHotseatIcons = isSplitDisplay
+ ? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
+
+ numAllAppsColumns = closestProfile.numAllAppsColumns;
+ numDatabaseAllAppsColumns = isSplitDisplay
+ ? closestProfile.numDatabaseAllAppsColumns : closestProfile.numAllAppsColumns;
if (Utilities.isGridOptionsEnabled(context)) {
allAppsIconSize = displayOption.allAppsIconSize;
@@ -332,31 +322,26 @@
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, metrics);
- Point realSize = new Point(displayInfo.realSize);
- // The real size never changes. smallSide and largeSide will remain the
- // same in any orientation.
- int smallSide = Math.min(realSize.x, realSize.y);
- int largeSide = Math.max(realSize.x, realSize.y);
+ supportedProfiles.clear();
+ defaultWallpaperSize = new Point(displayInfo.currentSize);
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ supportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
+ .setUseTwoPanels(isSplitDisplay)
+ .setWindowBounds(bounds).build());
- DeviceProfile.Builder builder = new DeviceProfile.Builder(context, this, displayInfo)
- .setSizeRange(new Point(displayInfo.smallestSize),
- new Point(displayInfo.largestSize));
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED,
- "largeSide=" + largeSide + " smallSide=" + smallSide);
- }
+ // Wallpaper size should be the maximum of the all possible sizes Launcher expects
+ int displayWidth = bounds.bounds.width();
+ int displayHeight = bounds.bounds.height();
+ defaultWallpaperSize.y = Math.max(defaultWallpaperSize.y, displayHeight);
- landscapeProfile = builder.setSize(largeSide, smallSide).build();
- portraitProfile = builder.setSize(smallSide, largeSide).build();
-
- // We need to ensure that there is enough extra space in the wallpaper
- // for the intended parallax effects
- if (context.getResources().getConfiguration().smallestScreenWidthDp >= 720) {
- defaultWallpaperSize = new Point(
- (int) (largeSide * wallpaperTravelToScreenWidthRatio(largeSide, smallSide)),
- largeSide);
- } else {
- defaultWallpaperSize = new Point(Math.max(smallSide * 2, largeSide), largeSide);
+ // We need to ensure that there is enough extra space in the wallpaper
+ // for the intended parallax effects
+ float parallaxFactor =
+ dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.densityDpi) < 720
+ ? 2
+ : wallpaperTravelToScreenWidthRatio(displayWidth, displayHeight);
+ defaultWallpaperSize.x =
+ Math.max(defaultWallpaperSize.x, Math.round(parallaxFactor * displayWidth));
}
ComponentName cn = new ComponentName(context.getPackageName(), getClass().getName());
@@ -376,18 +361,6 @@
mChangeListeners.remove(listener);
}
- public void verifyConfigChangedInBackground(final Context context) {
- String savedIconMaskPath = getDevicePrefs(context).getString(KEY_ICON_PATH_REF, "");
- // Good place to check if grid size changed in themepicker when launcher was dead.
- if (savedIconMaskPath.isEmpty()) {
- getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
- .apply();
- } else if (!savedIconMaskPath.equals(getIconShapePath(context))) {
- getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
- .apply();
- apply(context, CHANGE_FLAG_ICON_PARAMS);
- }
- }
public void setCurrentGrid(Context context, String gridName) {
Context appContext = context.getApplicationContext();
@@ -396,43 +369,17 @@
}
private void onConfigChanged(Context context) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "IDP.onConfigChanged");
- }
- // Config changes, what shall we do?
- InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this);
-
// Re-init grid
String gridName = getCurrentGridName(context);
initGrid(context, gridName);
- int changeFlags = 0;
- if (numRows != oldProfile.numRows ||
- numColumns != oldProfile.numColumns ||
- numFolderColumns != oldProfile.numFolderColumns ||
- numFolderRows != oldProfile.numFolderRows ||
- numDatabaseHotseatIcons != oldProfile.numDatabaseHotseatIcons) {
- changeFlags |= CHANGE_FLAG_GRID;
- }
-
- if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize ||
- !iconShapePath.equals(oldProfile.iconShapePath)) {
- changeFlags |= CHANGE_FLAG_ICON_PARAMS;
- }
- if (!iconShapePath.equals(oldProfile.iconShapePath)) {
- IconShape.init(context);
- }
-
- apply(context, changeFlags);
- }
-
- private void apply(Context context, int changeFlags) {
for (OnIDPChangeListener listener : mChangeListeners) {
- listener.onIdpChanged(changeFlags, this);
+ listener.onIdpChanged(this);
}
}
- static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
+ private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(
+ Context context, String gridName, boolean isSplitDisplay) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
@@ -449,8 +396,9 @@
&& type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG) && "display-option".equals(
parser.getName())) {
- profiles.add(new DisplayOption(
- gridOption, context, Xml.asAttributeSet(parser)));
+ profiles.add(new DisplayOption(gridOption, context,
+ Xml.asAttributeSet(parser),
+ isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE));
}
}
}
@@ -521,17 +469,29 @@
return (float) Math.hypot(x1 - x0, y1 - y0);
}
- @VisibleForTesting
- static DisplayOption invDistWeightedInterpolate(
- Info displayInfo, ArrayList<DisplayOption> points) {
- Point smallestSize = new Point(displayInfo.smallestSize);
- Point largestSize = new Point(displayInfo.largestSize);
+ private static DisplayOption invDistWeightedInterpolate(
+ Info displayInfo, ArrayList<DisplayOption> points, boolean isSplitDisplay) {
+ int minWidthPx = Integer.MAX_VALUE;
+ int minHeightPx = Integer.MAX_VALUE;
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ boolean isTablet = displayInfo.isTablet(bounds);
+ if (isTablet && isSplitDisplay) {
+ // For split displays, take half width per page
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.x / 2);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
- // This guarantees that width < height
- float width = Utilities.dpiFromPx((float) Math.min(smallestSize.x, smallestSize.y),
- displayInfo.densityDpi);
- float height = Utilities.dpiFromPx((float) Math.min(largestSize.x, largestSize.y),
- displayInfo.densityDpi);
+ } else if (!isTablet && bounds.isLandscape()) {
+ // We will use transposed layout in this case
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.y);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.x);
+ } else {
+ minWidthPx = Math.min(minWidthPx, bounds.availableSize.x);
+ minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
+ }
+ }
+
+ float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
+ float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
// Sort the profiles based on the closeness to the device size
Collections.sort(points, (a, b) ->
@@ -556,33 +516,25 @@
return out.multiply(1.0f / weights);
}
- @VisibleForTesting
- static DisplayOption invDistWeightedInterpolate(float width, float height,
- ArrayList<DisplayOption> points) {
- float weights = 0;
-
- DisplayOption p = points.get(0);
- if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
- return p;
- }
-
- DisplayOption out = new DisplayOption();
- for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
- p = points.get(i);
- float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
- weights += w;
- out.add(new DisplayOption().add(p).multiply(w));
- }
- return out.multiply(1.0f / weights);
- }
-
public DeviceProfile getDeviceProfile(Context context) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "getDeviceProfile: orientation="
- + context.getResources().getConfiguration().orientation);
+ Resources res = context.getResources();
+ Configuration config = context.getResources().getConfiguration();
+
+ float availableWidth = config.screenWidthDp * res.getDisplayMetrics().density;
+ float availableHeight = config.screenHeightDp * res.getDisplayMetrics().density;
+
+ DeviceProfile bestMatch = supportedProfiles.get(0);
+ float minDiff = Float.MAX_VALUE;
+
+ for (DeviceProfile profile : supportedProfiles) {
+ float diff = Math.abs(profile.availableWidthPx - availableWidth)
+ + Math.abs(profile.availableHeightPx - availableHeight);
+ if (diff < minDiff) {
+ minDiff = diff;
+ bestMatch = profile;
+ }
}
- return context.getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE ? landscapeProfile : portraitProfile;
+ return bestMatch;
}
private static float weight(float x0, float y0, float x1, float y1, float pow) {
@@ -624,7 +576,10 @@
public interface OnIDPChangeListener {
- void onIdpChanged(int changeFlags, InvariantDeviceProfile profile);
+ /**
+ * Called when the device provide changes
+ */
+ void onIdpChanged(InvariantDeviceProfile profile);
}
@@ -639,6 +594,9 @@
private final int numFolderRows;
private final int numFolderColumns;
+ private final int numAllAppsColumns;
+ private final int numDatabaseAllAppsColumns;
+ private final int numHotseatIcons;
private final int numDatabaseHotseatIcons;
private final String dbFile;
@@ -649,8 +607,6 @@
private final boolean isScalable;
private final int devicePaddingId;
- public final boolean visible;
-
private final SparseArray<TypedValue> extraAttrs;
public GridOption(Context context, AttributeSet attrs) {
@@ -665,8 +621,17 @@
R.styleable.GridDisplayOption_defaultLayoutId, 0);
demoModeLayoutId = a.getResourceId(
R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
- numDatabaseHotseatIcons = a.getInt(
+
+ numAllAppsColumns = a.getInt(
+ R.styleable.GridDisplayOption_numAllAppsColumns, numColumns);
+ numDatabaseAllAppsColumns = a.getInt(
+ R.styleable.GridDisplayOption_numExtendedAllAppsColumns, 2 * numAllAppsColumns);
+
+ numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
+ numDatabaseHotseatIcons = a.getInt(
+ R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
+
numFolderRows = a.getInt(
R.styleable.GridDisplayOption_numFolderRows, numRows);
numFolderColumns = a.getInt(
@@ -677,24 +642,21 @@
devicePaddingId = a.getResourceId(
R.styleable.GridDisplayOption_devicePaddingId, 0);
- visible = a.getBoolean(R.styleable.GridDisplayOption_visible, true);
-
a.recycle();
-
extraAttrs = Themes.createValueMap(context, attrs,
IntArray.wrap(R.styleable.GridDisplayOption));
}
}
- private static final class DisplayOption {
- private final GridOption grid;
+ @VisibleForTesting
+ static final class DisplayOption {
+
+ public final GridOption grid;
private final float minWidthDps;
private final float minHeightDps;
private final boolean canBeDefault;
- private float numShownHotseatIcons;
- private float numAllAppsColumns;
private float minCellHeight;
private float minCellWidth;
private float borderSpacing;
@@ -706,7 +668,7 @@
private float allAppsIconSize;
private float allAppsIconTextSize;
- DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
+ DisplayOption(GridOption grid, Context context, AttributeSet attrs, int defaultFlagValue) {
this.grid = grid;
TypedArray a = context.obtainStyledAttributes(
@@ -714,12 +676,9 @@
minWidthDps = a.getFloat(R.styleable.ProfileDisplayOption_minWidthDps, 0);
minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
- canBeDefault = a.getBoolean(
- R.styleable.ProfileDisplayOption_canBeDefault, false);
- numShownHotseatIcons = a.getInt(R.styleable.ProfileDisplayOption_numShownHotseatIcons,
- grid.numDatabaseHotseatIcons);
- numAllAppsColumns = a.getInt(R.styleable.ProfileDisplayOption_numAllAppsColumns,
- grid.numColumns);
+
+ canBeDefault = a.getInt(R.styleable.ProfileDisplayOption_canBeDefault, 0)
+ == defaultFlagValue;
minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0);
minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0);
@@ -748,16 +707,12 @@
minWidthDps = 0;
minHeightDps = 0;
canBeDefault = false;
- numShownHotseatIcons = 0;
- numAllAppsColumns = 0;
minCellHeight = 0;
minCellWidth = 0;
borderSpacing = 0;
}
private DisplayOption multiply(float w) {
- numShownHotseatIcons *= w;
- numAllAppsColumns *= w;
iconSize *= w;
landscapeIconSize *= w;
allAppsIconSize *= w;
@@ -771,8 +726,6 @@
}
private DisplayOption add(DisplayOption p) {
- numShownHotseatIcons += p.numShownHotseatIcons;
- numAllAppsColumns += p.numAllAppsColumns;
iconSize += p.iconSize;
landscapeIconSize += p.landscapeIconSize;
allAppsIconSize += p.allAppsIconSize;
@@ -785,18 +738,4 @@
return this;
}
}
-
- private class OverlayMonitor extends BroadcastReceiver {
-
- private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
-
- OverlayMonitor(Context context) {
- context.registerReceiver(this, getPackageFilter("android", ACTION_OVERLAY_CHANGED));
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- onConfigChanged(context);
- }
- }
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f640118..7b67807 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -124,6 +124,7 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.dragndrop.LauncherDragController;
import com.android.launcher3.folder.FolderGridOrganizer;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.icons.BitmapRenderer;
@@ -189,7 +190,6 @@
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.WidgetAddFlowHandler;
-import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetManagerHelper;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
@@ -429,7 +429,7 @@
mIconCache = app.getIconCache();
mAccessibilityDelegate = createAccessibilityDelegate();
- mDragController = new DragController(this);
+ mDragController = new LauncherDragController(this);
mAllAppsController = new AllAppsTransitionController(this);
mStateManager = new StateManager<>(this, NORMAL);
@@ -555,25 +555,12 @@
onIdpChanged(mDeviceProfile.inv);
}
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "onConfigurationChanged: diff=" + diff);
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "newConfig=" + newConfig);
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "oldConfig=" + mOldConfig);
- }
-
mOldConfig.setTo(newConfig);
super.onConfigurationChanged(newConfig);
}
@Override
- public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
- onIdpChanged(idp);
- }
-
- private void onIdpChanged(InvariantDeviceProfile idp) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "onIdpChanged");
- }
+ public void onIdpChanged(InvariantDeviceProfile idp) {
initDeviceProfile(idp);
dispatchDeviceProfileChanged();
reapplyUi();
@@ -918,7 +905,7 @@
} else {
mOverlayManager.onActivityStopped(this);
}
-
+ hideKeyboard();
logStopAndResume(false /* isResume */);
mAppWidgetHost.setActivityStarted(false);
NotificationListener.removeNotificationsChangedListener();
@@ -1197,7 +1184,7 @@
// Setup the drag controller (drop targets have to be added in reverse order in priority)
mDropTargetBar.setup(mDragController);
- mAllAppsController.setupViews(mAppsView);
+ mAllAppsController.setupViews(mScrimView, mAppsView);
}
/**
@@ -1351,14 +1338,7 @@
private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- // Reset AllApps to its initial state only if we are not in the middle of
- // processing a multi-step drop
- if (mPendingRequestArgs == null) {
- if (!isInState(NORMAL)) {
- onUiChangedWhileSleeping();
- }
- mStateManager.goToState(NORMAL);
- }
+ onScreenOff();
}
};
@@ -1479,7 +1459,7 @@
&& AbstractFloatingView.getTopOpenView(this) == null;
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this, intent);
-
+ hideKeyboard();
if (isActionMain) {
if (!internalStateHandled) {
// In all these cases, only animate if we're already on home
@@ -1501,9 +1481,6 @@
}
}
- // Handle HOME_INTENT
- hideKeyboard();
-
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onHomeIntent(internalStateHandled);
}
@@ -1928,6 +1905,17 @@
}
}
+ protected void onScreenOff() {
+ // Reset AllApps to its initial state only if we are not in the middle of
+ // processing a multi-step drop
+ if (mPendingRequestArgs == null) {
+ if (!isInState(NORMAL)) {
+ onUiChangedWhileSleeping();
+ }
+ mStateManager.goToState(NORMAL);
+ }
+ }
+
@TargetApi(Build.VERSION_CODES.M)
@Override
protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
@@ -2164,12 +2152,29 @@
*/
@Override
public void bindItems(final List<ItemInfo> items, final boolean forceAnimateIcons) {
+ bindItems(items, forceAnimateIcons, /* focusFirstItemForAccessibility= */ false);
+ }
+
+
+ /**
+ * Bind the items start-end from the list.
+ *
+ * Implementation of the method from LauncherModel.Callbacks.
+ *
+ * @param focusFirstItemForAccessibility true iff the first item to be added to the workspace
+ * should be focused for accessibility.
+ */
+ public void bindItems(
+ final List<ItemInfo> items,
+ final boolean forceAnimateIcons,
+ final boolean focusFirstItemForAccessibility) {
// Get the list of added items and intersect them with the set of items here
final Collection<Animator> bounceAnims = new ArrayList<>();
final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
Workspace workspace = mWorkspace;
int newItemsScreenId = -1;
int end = items.size();
+ View newView = null;
for (int i = 0; i < end; i++) {
final ItemInfo item = items.get(i);
@@ -2234,12 +2239,25 @@
bounceAnims.add(createNewAppBounceAnimation(view, i));
newItemsScreenId = item.screenId;
}
+
+ if (newView == null) {
+ newView = view;
+ }
}
- // Animate to the correct page
+ View viewToFocus = newView;
+ // Animate to the correct pager
if (animateIcons && newItemsScreenId > -1) {
AnimatorSet anim = new AnimatorSet();
anim.playTogether(bounceAnims);
+ if (focusFirstItemForAccessibility && viewToFocus != null) {
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ }
+ });
+ }
int currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
@@ -2262,6 +2280,8 @@
} else {
mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);
}
+ } else if (focusFirstItemForAccessibility && viewToFocus != null) {
+ viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
workspace.requestLayout();
}
@@ -2332,8 +2352,7 @@
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
- Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this,
- pendingInfo);
+ Bundle options = pendingInfo.getDefaultSizeOptions(this);
boolean isDirectConfig =
item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG);
@@ -2782,7 +2801,7 @@
* @see LauncherState#getOverviewScaleAndOffset(Launcher)
*/
public float[] getNormalOverviewScaleAndOffset() {
- return new float[] {NO_SCALE, NO_OFFSET};
+ return new float[] {NO_SCALE, NO_OFFSET, NO_OFFSET};
}
/**
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 11585f9..834b5a7 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,7 +16,8 @@
package com.android.launcher3;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
+import static com.android.launcher3.Utilities.getDevicePrefs;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@@ -24,12 +25,13 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
-import android.os.Handler;
+import android.os.UserHandle;
import android.util.Log;
import androidx.annotation.Nullable;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
@@ -39,6 +41,7 @@
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -47,6 +50,7 @@
public class LauncherAppState {
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
+ private static final String KEY_ICON_STATE = "pref_icon_shape_path";
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<LauncherAppState> INSTANCE =
@@ -54,16 +58,11 @@
private final Context mContext;
private final LauncherModel mModel;
+ private final IconProvider mIconProvider;
private final IconCache mIconCache;
private final WidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
- private SettingsCache.OnChangeListener mNotificationSettingsChangedListener;
-
- private SettingsCache mSettingsCache;
- private InstallSessionTracker mInstallSessionTracker;
- private SimpleBroadcastReceiver mModelChangeReceiver;
- private SafeCloseable mCalendarChangeTracker;
- private SafeCloseable mUserChangeListener;
+ private final RunnableList mOnTerminateCallback = new RunnableList();
public static LauncherAppState getInstance(final Context context) {
return INSTANCE.get(context);
@@ -80,40 +79,47 @@
public LauncherAppState(Context context) {
this(context, LauncherFiles.APP_ICONS_DB);
- mModelChangeReceiver = new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
+ mInvariantDeviceProfile.addOnChangeListener(idp -> refreshAndReloadLauncher());
mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
- mModelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
+
+ SimpleBroadcastReceiver modelChangeReceiver =
+ new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
+ modelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
if (FeatureFlags.IS_STUDIO_BUILD) {
- mModelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
+ modelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
-
- mCalendarChangeTracker = IconProvider.registerIconChangeListener(mContext,
- mModel::onAppIconChanged, MODEL_EXECUTOR.getHandler());
+ mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
// TODO: remove listener on terminate
FeatureFlags.APP_SEARCH_IMPROVEMENTS.addChangeListener(context, mModel::forceReload);
CustomWidgetManager.INSTANCE.get(mContext)
.setWidgetRefreshCallback(mModel::refreshAndBindWidgetsAndShortcuts);
- mUserChangeListener = UserCache.INSTANCE.get(mContext)
+ SafeCloseable userChangeListener = UserCache.INSTANCE.get(mContext)
.addUserChangeListener(mModel::forceReload);
+ mOnTerminateCallback.add(userChangeListener::close);
- mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
- new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
+ IconObserver observer = new IconObserver();
+ SafeCloseable iconChangeTracker = mIconProvider.registerIconChangeListener(
+ observer, MODEL_EXECUTOR.getHandler());
+ mOnTerminateCallback.add(iconChangeTracker::close);
+ MODEL_EXECUTOR.execute(observer::verifyIconChanged);
- mInstallSessionTracker = InstallSessionHelper.INSTANCE.get(context)
- .registerInstallTracker(mModel);
+ InstallSessionTracker installSessionTracker =
+ InstallSessionHelper.INSTANCE.get(context).registerInstallTracker(mModel);
+ mOnTerminateCallback.add(installSessionTracker::unregister);
// Register an observer to rebind the notification listener when dots are re-enabled.
- mSettingsCache = SettingsCache.INSTANCE.get(mContext);
- mNotificationSettingsChangedListener = this::onNotificationSettingsChanged;
- mSettingsCache.register(NOTIFICATION_BADGING_URI,
- mNotificationSettingsChangedListener);
- onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI));
+ SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext);
+ SettingsCache.OnChangeListener notificationLister = this::onNotificationSettingsChanged;
+ settingsCache.register(NOTIFICATION_BADGING_URI, notificationLister);
+ onNotificationSettingsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI));
+ mOnTerminateCallback.add(() ->
+ settingsCache.unregister(NOTIFICATION_BADGING_URI, notificationLister));
}
public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
@@ -122,30 +128,25 @@
mContext = context;
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
-
- mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
+ mIconProvider = new IconProvider(context, ENABLE_THEMED_ICONS.get());
+ mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
+ iconCacheFileName, mIconProvider);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
}
- protected void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
+ private void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
if (areNotificationDotsEnabled) {
NotificationListener.requestRebind(new ComponentName(
mContext, NotificationListener.class));
}
}
- private void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
- if (changeFlags == 0) {
- return;
- }
-
- if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) != 0) {
- LauncherIcons.clearPool();
- mIconCache.updateIconParams(idp.fillResIconDpi, idp.iconBitmapSize);
- mWidgetCache.refresh();
- }
-
+ private void refreshAndReloadLauncher() {
+ LauncherIcons.clearPool();
+ mIconCache.updateIconParams(
+ mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
+ mWidgetCache.refresh();
mModel.forceReload();
}
@@ -154,25 +155,13 @@
*/
public void onTerminate() {
mModel.destroy();
- if (mModelChangeReceiver != null) {
- mContext.unregisterReceiver(mModelChangeReceiver);
- }
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
- if (mInstallSessionTracker != null) {
- mInstallSessionTracker.unregister();
- }
- if (mCalendarChangeTracker != null) {
- mCalendarChangeTracker.close();
- }
- if (mUserChangeListener != null) {
- mUserChangeListener.close();
- }
CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
+ mOnTerminateCallback.executeAllAndDestroy();
+ }
- if (mSettingsCache != null) {
- mSettingsCache.unregister(NOTIFICATION_BADGING_URI,
- mNotificationSettingsChangedListener);
- }
+ public IconProvider getIconProvider() {
+ return mIconProvider;
}
public IconCache getIconCache() {
@@ -197,4 +186,26 @@
public static InvariantDeviceProfile getIDP(Context context) {
return InvariantDeviceProfile.INSTANCE.get(context);
}
+
+ private class IconObserver implements IconProvider.IconChangeListener {
+
+ @Override
+ public void onAppIconChanged(String packageName, UserHandle user) {
+ mModel.onAppIconChanged(packageName, user);
+ }
+
+ @Override
+ public void onSystemIconStateChanged(String iconState) {
+ IconShape.init(mContext);
+ refreshAndReloadLauncher();
+ getDevicePrefs(mContext).edit().putString(KEY_ICON_STATE, iconState).apply();
+ }
+
+ void verifyIconChanged() {
+ String iconState = mIconProvider.getSystemIconState();
+ if (!iconState.equals(getDevicePrefs(mContext).getString(KEY_ICON_STATE, ""))) {
+ onSystemIconStateChanged(iconState);
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 4c11725..9d50edd 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -172,10 +172,12 @@
}
/**
- * Returns an array of two elements.
+ * Returns an array of three elements.
* The first specifies the scale for the overview
* The second is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview
* should be shifted horizontally.
+ * The third is the factor ([0, 1], 0 => center-screen; 1 => offscreen) by which overview
+ * should be shifted vertically.
*/
public float[] getOverviewScaleAndOffset(Launcher launcher) {
return launcher.getNormalOverviewScaleAndOffset();
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index fb21698..b26a7ea 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -59,7 +59,7 @@
import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
-import java.util.List;
+import java.util.function.Consumer;
/**
* An abstraction of the original Workspace which supports browsing through a
@@ -295,18 +295,16 @@
}
/**
- * Returns the currently visible pages.
+ * Executes the callback against each visible page
*/
- public Iterable<View> getVisiblePages() {
+ public void forEachVisiblePage(Consumer<View> callback) {
int panelCount = getPanelCount();
- List<View> visiblePages = new ArrayList<>(panelCount);
for (int i = mCurrentPage; i < mCurrentPage + panelCount; i++) {
View page = getPageAt(i);
if (page != null) {
- visiblePages.add(page);
+ callback.accept(page);
}
}
- return visiblePages;
}
/**
@@ -461,11 +459,6 @@
}
}
- // we moved this functionality to a helper function so SmoothPagedView can reuse it
- protected boolean computeScrollHelper() {
- return computeScrollHelper(true);
- }
-
protected void announcePageForAccessibility() {
if (isAccessibilityEnabled(getContext())) {
// Notify the user when the page changes
@@ -473,7 +466,7 @@
}
}
- protected boolean computeScrollHelper(boolean shouldInvalidate) {
+ protected boolean computeScrollHelper() {
if (mScroller.computeScrollOffset()) {
// Don't bother scrolling if the page does not need to be moved
int oldPos = mOrientationHandler.getPrimaryScroll(this);
@@ -481,23 +474,29 @@
if (oldPos != newPos) {
mOrientationHandler.set(this, VIEW_SCROLL_TO, mScroller.getCurrX());
}
- if (shouldInvalidate) {
- if (mAllowOverScroll) {
- if (newPos < mMinScroll && oldPos >= mMinScroll) {
- mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
- mScroller.abortAnimation();
- } else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
- mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
- mScroller.abortAnimation();
- }
+
+ if (mAllowOverScroll) {
+ if (newPos < mMinScroll && oldPos >= mMinScroll) {
+ mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
+ mScroller.abortAnimation();
+ } else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
+ mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
+ mScroller.abortAnimation();
}
-
- invalidate();
}
- return true;
- } else if (mNextPage != INVALID_PAGE && shouldInvalidate) {
- sendScrollAccessibilityEvent();
+ // If the scroller has scrolled to the final position and there is no edge effect, then
+ // finish the scroller to skip waiting for additional settling
+ int finalPos = mOrientationHandler.getPrimaryValue(mScroller.getFinalX(),
+ mScroller.getFinalY());
+ if (newPos == finalPos && mEdgeGlowLeft.isFinished() && mEdgeGlowRight.isFinished()) {
+ mScroller.abortAnimation();
+ }
+
+ invalidate();
+ return true;
+ } else if (mNextPage != INVALID_PAGE) {
+ sendScrollAccessibilityEvent();
int prevPage = mCurrentPage;
mCurrentPage = validateNewPage(mNextPage);
mNextPage = INVALID_PAGE;
@@ -835,18 +834,25 @@
return;
}
+ // Add the current page's views as focusable and the next possible page's too. If the
+ // last focus change action was left then the left neighbour's views will be added, and
+ // if it was right then the right neighbour's views will be added.
+ // Unfortunately mCurrentPage can be outdated if there were multiple control actions in a
+ // short period of time, but mNextPage is up to date because it is always updated by
+ // method snapToPage.
+ int nextPage = getNextPage();
// XXX-RTL: This will be fixed in a future CL
- if (mCurrentPage >= 0 && mCurrentPage < getPageCount()) {
- getPageAt(mCurrentPage).addFocusables(views, direction, focusableMode);
+ if (nextPage >= 0 && nextPage < getPageCount()) {
+ getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
if (direction == View.FOCUS_LEFT) {
- if (mCurrentPage > 0) {
- int nextPage = validateNewPage(mCurrentPage - 1);
+ if (nextPage > 0) {
+ nextPage = validateNewPage(nextPage - 1);
getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
} else if (direction == View.FOCUS_RIGHT) {
- if (mCurrentPage < getPageCount() - 1) {
- int nextPage = validateNewPage(mCurrentPage + 1);
+ if (nextPage < getPageCount() - 1) {
+ nextPage = validateNewPage(nextPage + 1);
getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
}
@@ -1034,7 +1040,7 @@
// Try canceling the long press. It could also have been scheduled
// by a distant descendant, so use the mAllowLongPress flag to block
// everything
- getVisiblePages().forEach(View::cancelLongPress);
+ forEachVisiblePage(View::cancelLongPress);
}
protected float getScrollProgress(int screenCenter, View v, int page) {
@@ -1416,6 +1422,14 @@
@Override
public void requestChildFocus(View child, View focused) {
super.requestChildFocus(child, focused);
+
+ // In case the device is controlled by a controller, mCurrentPage isn't updated properly
+ // which results in incorrect navigation
+ int nextPage = getNextPage();
+ if (nextPage != mCurrentPage) {
+ setCurrentPage(nextPage);
+ }
+
int page = indexToPage(indexOfChild(child));
if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
snapToPage(page);
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index fe58da9..558538c 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -24,10 +24,10 @@
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import androidx.annotation.WorkerThread;
+import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.util.Executors;
@@ -71,7 +71,7 @@
return;
}
- Log.d(LOG,
+ FileLog.d(LOG,
"Adding package name to install queue. Package name: " + info.getAppPackageName()
+ ", has app icon: " + (info.getAppIcon() != null)
+ ", has app label: " + !TextUtils.isEmpty(info.getAppLabel()));
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 073a46c..7c00362 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -75,9 +75,9 @@
import com.android.launcher3.graphics.GridCustomizationsProvider;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
+import com.android.launcher3.icons.ThemedIconDrawable.ThemedAdaptiveIcon;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
@@ -242,8 +242,8 @@
* @param outRect The out rect where we return the bounds of {@param view} in drag layer coords.
*/
public static void getBoundsForViewInDragLayer(BaseDragLayer dragLayer, View view,
- Rect viewBounds, boolean ignoreTransform, RectF outRect) {
- float[] points = sTmpFloatArray;
+ Rect viewBounds, boolean ignoreTransform, float[] recycle, RectF outRect) {
+ float[] points = recycle == null ? new float[4] : recycle;
points[0] = viewBounds.left;
points[1] = viewBounds.top;
points[2] = viewBounds.right;
@@ -646,13 +646,23 @@
*/
public static Drawable getFullDrawable(Launcher launcher, ItemInfo info, int width, int height,
Object[] outObj) {
+ Drawable icon = loadFullDrawableWithoutTheme(launcher, info, width, height, outObj);
+ if (icon instanceof ThemedAdaptiveIcon) {
+ icon = ((ThemedAdaptiveIcon) icon).getThemedDrawable(launcher);
+ }
+ return icon;
+ }
+
+ private static Drawable loadFullDrawableWithoutTheme(Launcher launcher, ItemInfo info,
+ int width, int height, Object[] outObj) {
LauncherAppState appState = LauncherAppState.getInstance(launcher);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
LauncherActivityInfo activityInfo = launcher.getSystemService(LauncherApps.class)
.resolveActivity(info.getIntent(), info.user);
outObj[0] = activityInfo;
- return activityInfo == null ? null : new IconProvider(launcher).getIcon(
- activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
+ return activityInfo == null ? null : LauncherAppState.getInstance(launcher)
+ .getIconProvider().getIcon(
+ activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 05d6e04..5ba7623 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -25,6 +25,7 @@
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
+import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
@@ -456,7 +457,7 @@
}
private boolean isTwoPanelEnabled() {
- return mLauncher.mDeviceProfile.isTablet && FeatureFlags.ENABLE_TWO_PANEL_HOME.get();
+ return mLauncher.mDeviceProfile.isTwoPanels;
}
@Override
@@ -1163,10 +1164,6 @@
mWallpaperOffset.syncWithScroll();
}
- public void computeScrollWithoutInvalidation() {
- computeScrollHelper(false);
- }
-
@Override
public void announceForAccessibility(CharSequence text) {
// Don't announce if apps is on top of us.
@@ -1950,8 +1947,8 @@
}
parent.onDropChild(cell);
- mLauncher.getStateManager().goToState(
- NORMAL, SPRING_LOADED_EXIT_DELAY, onCompleteRunnable);
+ mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY,
+ onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable));
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
@@ -2974,7 +2971,7 @@
List<CellLayout> cellLayouts = new ArrayList<>(getPanelCount() + 1);
cellLayouts.add(getHotseat());
- getVisiblePages().forEach(page -> cellLayouts.add((CellLayout) page));
+ forEachVisiblePage(page -> cellLayouts.add((CellLayout) page));
// Order: App icons, app in folder. Items in hotseat get returned first.
if (ADAPTIVE_ICON_WINDOW_ANIM.get()) {
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index aa99d52..c771e3e 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -34,9 +34,9 @@
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
@@ -166,10 +166,9 @@
propertySetter.setFloat(sysUiScrim, SYSUI_PROGRESS,
state.hasFlag(FLAG_HAS_SYS_UI_SCRIM) ? 1 : 0, LINEAR);
-
propertySetter.setViewBackgroundColor(mLauncher.getScrimView(),
state.getWorkspaceScrimColor(mLauncher),
- config.getInterpolator(ANIM_WORKSPACE_SCRIM_FADE, LINEAR));
+ config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
}
public void applyChildState(LauncherState state, CellLayout cl, int childIndex) {
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index a5852ba..2b36f19 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -3,6 +3,7 @@
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import android.appwidget.AppWidgetProviderInfo;
@@ -32,6 +33,7 @@
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.keyboard.KeyboardDragAndDropView;
import com.android.launcher3.model.data.AppInfo;
@@ -219,27 +221,26 @@
} else if (action == ADD_TO_WORKSPACE) {
final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates);
- mLauncher.getStateManager().goToState(NORMAL, true, new Runnable() {
+ mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
+ if (item instanceof AppInfo) {
+ WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
+ mLauncher.getModelWriter().addItemToDatabase(info,
+ Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates[0], coordinates[1]);
- @Override
- public void run() {
- if (item instanceof AppInfo) {
- WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
- mLauncher.getModelWriter().addItemToDatabase(info,
- Favorites.CONTAINER_DESKTOP,
- screenId, coordinates[0], coordinates[1]);
-
- mLauncher.bindItems(Collections.singletonList(info), true);
- announceConfirmation(R.string.item_added_to_workspace);
- } else if (item instanceof PendingAddItemInfo) {
- PendingAddItemInfo info = (PendingAddItemInfo) item;
- Workspace workspace = mLauncher.getWorkspace();
- workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
- mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP,
- screenId, coordinates, info.spanX, info.spanY);
- }
+ mLauncher.bindItems(
+ Collections.singletonList(info),
+ /* forceAnimateIcons= */ true,
+ /* focusFirstItemForAccessibility= */ true);
+ announceConfirmation(R.string.item_added_to_workspace);
+ } else if (item instanceof PendingAddItemInfo) {
+ PendingAddItemInfo info = (PendingAddItemInfo) item;
+ Workspace workspace = mLauncher.getWorkspace();
+ workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
+ mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates, info.spanX, info.spanY);
}
- });
+ }));
return true;
} else if (action == MOVE_TO_WORKSPACE) {
Folder folder = Folder.getOpen(mLauncher);
@@ -290,7 +291,12 @@
return actions;
}
- CellLayout layout = (CellLayout) host.getParent().getParent();
+ CellLayout layout;
+ if (host.getParent() instanceof DragView) {
+ layout = (CellLayout) ((DragView) host.getParent()).getContentViewParent().getParent();
+ } else {
+ layout = (CellLayout) host.getParent().getParent();
+ }
if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
index 1733e5d..f96afa8 100644
--- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
@@ -17,6 +17,7 @@
package com.android.launcher3.accessibility;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import android.view.KeyEvent;
import android.view.View;
@@ -67,19 +68,14 @@
final WorkspaceItemInfo info = ((DeepShortcutView) host.getParent()).getFinalInfo();
final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates);
- Runnable onComplete = new Runnable() {
- @Override
- public void run() {
- mLauncher.getModelWriter().addItemToDatabase(info,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screenId, coordinates[0], coordinates[1]);
- mLauncher.bindItems(Collections.singletonList(info), true);
- AbstractFloatingView.closeAllOpenViews(mLauncher);
- announceConfirmation(R.string.item_added_to_workspace);
- }
- };
-
- mLauncher.getStateManager().goToState(NORMAL, true, onComplete);
+ mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
+ mLauncher.getModelWriter().addItemToDatabase(info,
+ LauncherSettings.Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates[0], coordinates[1]);
+ mLauncher.bindItems(Collections.singletonList(info), true);
+ AbstractFloatingView.closeAllOpenViews(mLauncher);
+ announceConfirmation(R.string.item_added_to_workspace);
+ }));
return true;
} else if (action == DISMISS_NOTIFICATION) {
if (!(host instanceof NotificationMainView)) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 40f7ab1..47236b6 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -26,6 +26,7 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
@@ -44,6 +45,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
+import androidx.core.graphics.ColorUtils;
import androidx.core.os.BuildCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -66,6 +68,7 @@
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.RecyclerViewFastScroller;
+import com.android.launcher3.views.ScrimView;
import com.android.launcher3.views.SpringRelativeLayout;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
@@ -73,13 +76,16 @@
* The all apps view container.
*/
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
- Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
+ Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
+ ScrimView.ScrimDrawingController {
- private static final float FLING_VELOCITY_MULTIPLIER = 1800f;
+ private static final float FLING_VELOCITY_MULTIPLIER = 1000f;
// Starts the springs after at least 25% of the animation has passed.
private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
+ private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
protected final BaseDraggingActivity mLauncher;
protected final AdapterHolder[] mAH;
private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
@@ -93,7 +99,7 @@
private View mSearchContainer;
private AllAppsPagedView mViewPager;
- private FloatingHeaderView mHeader;
+ protected FloatingHeaderView mHeader;
private WorkModeSwitch mWorkModeSwitch;
@@ -107,7 +113,14 @@
private Rect mInsets = new Rect();
- SearchAdapterProvider mSearchAdapterProvider;
+ private SearchAdapterProvider mSearchAdapterProvider;
+ private final int mHeaderTopPadding;
+ private final int mScrimColor;
+ private final int mHeaderProtectionColor;
+ private final float mHeaderThreshold;
+ private ScrimView mScrimView;
+ private int mHeaderColor;
+
public AllAppsContainerView(Context context) {
this(context, null);
@@ -121,8 +134,19 @@
super(context, attrs, defStyleAttr);
mLauncher = BaseDraggingActivity.fromContext(context);
+
+ mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ mHeaderThreshold = getResources().getDimensionPixelSize(
+ R.dimen.dynamic_grid_cell_border_spacing);
+ mHeaderTopPadding = context.getResources()
+ .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
+ int accentColor = Themes.getColorAccent(getContext());
+ mHeaderProtectionColor = ColorUtils.blendARGB(mScrimColor, accentColor, .3f);
+
mLauncher.addOnDeviceProfileChangeListener(this);
+
+
mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this);
mSearchQueryBuilder = new SpannableStringBuilder();
Selection.setSelection(mSearchQueryBuilder, 0);
@@ -157,7 +181,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
for (AdapterHolder holder : mAH) {
- holder.adapter.setAppsPerRow(dp.inv.numAllAppsColumns);
+ holder.adapter.setAppsPerRow(dp.numShownAllAppsColumns);
if (holder.recyclerView != null) {
// Remove all views and clear the pool, while keeping the data same. After this
// call, all the viewHolders will be recreated.
@@ -300,6 +324,7 @@
}
// Reset the search bar and base recycler view after transitioning home
mSearchUiManager.resetSearch();
+ updateHeaderScroll(0);
}
@Override
@@ -611,7 +636,7 @@
public void onAnimationUpdate(ValueAnimator valueAnimator) {
if (shouldSpring
&& valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
- absorbSwipeUpVelocity(-Math.abs(
+ absorbSwipeUpVelocity(Math.abs(
Math.round(velocity * FLING_VELOCITY_MULTIPLIER)));
shouldSpring = false;
}
@@ -625,6 +650,26 @@
outRect.offset(0, (int) getTranslationY());
}
+ @Override
+ public void setTranslationY(float translationY) {
+ super.setTranslationY(translationY);
+ invalidateHeader();
+ }
+
+ public void setScrimView(ScrimView scrimView) {
+ mScrimView = scrimView;
+ }
+
+ @Override
+ public void drawOnScrim(Canvas canvas) {
+ mHeaderPaint.setColor(mHeaderColor);
+ mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
+ if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
+ canvas.drawRect(0, 0, getWidth(), mHeaderTopPadding + getTranslationY(),
+ mHeaderPaint);
+ }
+ }
+
public class AdapterHolder {
public static final int MAIN = 0;
public static final int WORK = 1;
@@ -725,4 +770,24 @@
return mOverlay;
}
}
+
+
+ protected void updateHeaderScroll(int scrolledOffset) {
+ float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold));
+ int headerColor = ColorUtils.setAlphaComponent(mHeaderProtectionColor, (int) (prog * 255));
+ if (headerColor != mHeaderColor) {
+ mHeaderColor = headerColor;
+ getSearchView().setBackgroundColor(mHeaderColor);
+ invalidateHeader();
+ }
+ }
+
+ /**
+ * redraws header protection
+ */
+ public void invalidateHeader() {
+ if (mScrimView != null) {
+ mScrimView.invalidate();
+ }
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 5b4c4c5..70588ea 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -283,7 +283,7 @@
mOnIconClickListener = launcher.getItemOnClickListener();
mSearchAdapterProvider = searchAdapterProvider;
- setAppsPerRow(mLauncher.getDeviceProfile().inv.numAllAppsColumns);
+ setAppsPerRow(mLauncher.getDeviceProfile().numShownAllAppsColumns);
}
public void setAppsPerRow(int appsPerRow) {
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index b1c764c..197d74c 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -38,6 +38,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.logging.StatsLogManager;
@@ -52,6 +53,7 @@
public class AllAppsRecyclerView extends BaseRecyclerView {
private static final String TAG = "AllAppsContainerView";
private static final boolean DEBUG = false;
+ private final Launcher mLauncher;
private AlphabeticalAppsList mApps;
private final int mNumAppsPerRow;
@@ -87,6 +89,7 @@
R.dimen.all_apps_empty_search_bg_top_offset);
mNumAppsPerRow = LauncherAppState.getIDP(context).numColumns;
mFastScrollHelper = new AllAppsFastScrollHelper(this);
+ mLauncher = Launcher.getLauncher(context);
}
/**
@@ -200,6 +203,12 @@
}
@Override
+ public void onScrolled(int dx, int dy) {
+ super.onScrolled(dx, dy);
+ mLauncher.getAppsView().updateHeaderScroll(getCurrentScrollY());
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent e) {
boolean result = super.onInterceptTouchEvent(e);
if (!result && e.getAction() == MotionEvent.ACTION_DOWN
@@ -410,7 +419,7 @@
/**
* Returns the available scroll height:
- * AvailableScrollHeight = Total height of the all items - last page height
+ * AvailableScrollHeight = Total height of the all items - last page height
*/
@Override
protected int getAvailableScrollHeight() {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index c61c0d6..2cfbdf9 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -15,18 +15,20 @@
*/
package com.android.launcher3.allapps;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_ALLAPPS;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
+import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.util.FloatProperty;
import android.view.View;
@@ -37,12 +39,13 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.views.ScrimView;
/**
* Handles AllApps view transition.
@@ -86,6 +89,7 @@
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
private float mScrollRangeDelta = 0;
+ private ScrimView mScrimView;
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
@@ -154,9 +158,9 @@
return;
}
- Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
- ? config.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
- : FAST_OUT_SLOW_IN;
+ Interpolator interpolator = toState.equals(ALL_APPS)
+ ? (config.userControlled ? ACCEL_2 : ACCEL_0_75) :
+ (config.userControlled ? DEACCEL_2 : DEACCEL);
Animator anim = createSpringAnimation(mProgress, targetProgress);
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
@@ -179,19 +183,28 @@
Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
setter.setViewAlpha(mAppsView, hasAllAppsContent ? 1 : 0, allAppsFade);
+
+ boolean shouldProtectHeader =
+ ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
+ mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
}
- public AnimatorListenerAdapter getProgressAnimatorListener() {
- return AnimationSuccessListener.forRunnable(this::onProgressAnimationEnd);
+ public AnimatorListener getProgressAnimatorListener() {
+ return AnimatorListeners.forSuccessCallback(this::onProgressAnimationEnd);
}
- public void setupViews(AllAppsContainerView appsView) {
+ /**
+ * see Launcher#setupViews
+ */
+ public void setupViews(ScrimView scrimView, AllAppsContainerView appsView) {
+ mScrimView = scrimView;
mAppsView = appsView;
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) {
mLauncher.getSystemUiController().updateUiState(UI_STATE_ALLAPPS,
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
+ mAppsView.setScrimView(scrimView);
}
/**
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 6957850..88d95fa 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -30,6 +30,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.TreeMap;
/**
@@ -181,11 +182,10 @@
* Sets results list for search
*/
public boolean setSearchResults(ArrayList<AdapterItem> results) {
- if (results == null || mSearchResults != results) {
- boolean same = mSearchResults != null && mSearchResults.equals(results);
+ if (!Objects.equals(results, mSearchResults)) {
mSearchResults = results;
updateAdapterItems();
- return !same;
+ return true;
}
return false;
}
diff --git a/src/com/android/launcher3/anim/AnimationSuccessListener.java b/src/com/android/launcher3/anim/AnimationSuccessListener.java
index 9905e81..a312070 100644
--- a/src/com/android/launcher3/anim/AnimationSuccessListener.java
+++ b/src/com/android/launcher3/anim/AnimationSuccessListener.java
@@ -40,24 +40,4 @@
public abstract void onAnimationSuccess(Animator animator);
- /**
- * Returns an AnimationSuccessListener which runs the provided action on success
- */
- public static AnimationSuccessListener forRunnable(Runnable r) {
- return new RunnableSuccessListener(r);
- }
-
- private static class RunnableSuccessListener extends AnimationSuccessListener {
-
- private final Runnable mRunnable;
-
- private RunnableSuccessListener(Runnable r) {
- mRunnable = r;
- }
-
- @Override
- public void onAnimationSuccess(Animator animator) {
- mRunnable.run();
- }
- }
}
diff --git a/src/com/android/launcher3/anim/AnimatorListeners.java b/src/com/android/launcher3/anim/AnimatorListeners.java
new file mode 100644
index 0000000..3799700
--- /dev/null
+++ b/src/com/android/launcher3/anim/AnimatorListeners.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.anim;
+
+import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+
+import java.util.function.Consumer;
+
+/**
+ * Utility class for creating common {@link AnimatorListener}
+ */
+public class AnimatorListeners {
+
+ /**
+ * Returns an AnimatorListener which executes the callback on successful animation completion
+ */
+ public static AnimatorListener forSuccessCallback(Runnable callback) {
+ return new RunnableSuccessListener(callback);
+ }
+
+ /**
+ * Returns an AnimatorListener which executes the callback on animation completion,
+ * with the boolean representing success
+ */
+ public static AnimatorListener forEndCallback(Consumer<Boolean> callback) {
+ return new EndStateCallbackWrapper(callback);
+ }
+
+ /**
+ * Returns an AnimatorListener which executes the callback on animation completion
+ */
+ public static AnimatorListener forEndCallback(Runnable callback) {
+ return new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ callback.run();
+ }
+ };
+ }
+
+ private static class EndStateCallbackWrapper extends AnimatorListenerAdapter {
+
+ private final Consumer<Boolean> mListener;
+ private boolean mListenerCalled = false;
+
+ EndStateCallbackWrapper(Consumer<Boolean> listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ if (!mListenerCalled) {
+ mListenerCalled = true;
+ mListener.accept(false);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (!mListenerCalled) {
+ ValueAnimator anim = (ValueAnimator) animation;
+ mListener.accept(anim.getAnimatedFraction() > SUCCESS_TRANSITION_PROGRESS);
+ }
+ }
+ }
+
+ private static class RunnableSuccessListener extends AnimationSuccessListener {
+
+ private final Runnable mRunnable;
+
+ private RunnableSuccessListener(Runnable r) {
+ mRunnable = r;
+ }
+
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ mRunnable.run();
+ }
+ }
+}
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 11e831e..9d73bba 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -53,6 +53,9 @@
public static final Interpolator AGGRESSIVE_EASE = new PathInterpolator(0.2f, 0f, 0f, 1f);
public static final Interpolator AGGRESSIVE_EASE_IN_OUT = new PathInterpolator(0.6f,0, 0.4f, 1);
+ public static final Interpolator DECELERATED_EASE = new PathInterpolator(0, 0, .2f, 1f);
+ public static final Interpolator ACCELERATED_EASE = new PathInterpolator(0.4f, 0, 1f, 1f);
+
public static final Interpolator EXAGGERATED_EASE;
public static final Interpolator INSTANT = t -> 1;
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 8057475..01f7de6 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -15,13 +15,11 @@
*/
package com.android.launcher3.anim;
-import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
@@ -182,32 +180,6 @@
if (mProgressAnimator == null) {
mProgressAnimator = ValueAnimator.ofFloat(0, 1);
}
- mProgressAnimator.addListener(new EndStateCallbackWrapper(listener));
- }
-
- private static class EndStateCallbackWrapper extends AnimatorListenerAdapter {
-
- private final Consumer<Boolean> mListener;
- private boolean mCalled = false;
-
- EndStateCallbackWrapper(Consumer<Boolean> listener) {
- mListener = listener;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- if (!mCalled) {
- mCalled = true;
- mListener.accept(false);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mCalled) {
- ValueAnimator anim = (ValueAnimator) animation;
- mListener.accept(anim.getAnimatedFraction() > SUCCESS_TRANSITION_PROGRESS);
- }
- }
+ mProgressAnimator.addListener(AnimatorListeners.forEndCallback(listener));
}
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index bad8704..7ef43ed 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -87,6 +87,10 @@
public static final BooleanFlag ENABLE_QUICKSTEP_LIVE_TILE = getDebugFlag(
"ENABLE_QUICKSTEP_LIVE_TILE", true, "Enable live tile in Quickstep overview");
+ public static final BooleanFlag ENABLE_QUICKSTEP_WIDGET_APP_START = getDebugFlag(
+ "ENABLE_QUICKSTEP_WIDGET_APP_START", true,
+ "Enable Quickstep animation when launching activities from an app widget");
+
// Keep as DeviceFlag to allow remote disable in emergency.
public static final BooleanFlag ENABLE_SUGGESTED_ACTIONS_OVERVIEW = new DeviceFlag(
"ENABLE_SUGGESTED_ACTIONS_OVERVIEW", true, "Show chip hints on the overview screen");
@@ -137,8 +141,8 @@
public static final BooleanFlag MULTI_DB_GRID_MIRATION_ALGO = getDebugFlag(
"MULTI_DB_GRID_MIRATION_ALGO", true, "Use the multi-db grid migration algorithm");
- public static final BooleanFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = getDebugFlag(
- "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker");
+ public static final BooleanFlag ENABLE_THEMED_ICONS = getDebugFlag(
+ "ENABLE_THEMED_ICONS", false, "Enable themed icons on workspace");
// Keep as DeviceFlag for remote disable in emergency.
public static final BooleanFlag ENABLE_OVERVIEW_SELECTIONS = new DeviceFlag(
@@ -170,12 +174,12 @@
"Replace Smartspace with the enhanced version. "
+ "Ignored if ENABLE_SMARTSPACE_UNIVERSAL is enabled.");
- public static final BooleanFlag ENABLE_SMARTSPACE_FEEDBACK = new DeviceFlag(
+ public static final BooleanFlag ENABLE_SMARTSPACE_FEEDBACK = getDebugFlag(
"ENABLE_SMARTSPACE_FEEDBACK", true,
"Adds a menu option to send feedback for Enhanced Smartspace.");
- public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = new DeviceFlag(
- "ENABLE_SMARTSPACE_DISMISS", false,
+ public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = getDebugFlag(
+ "ENABLE_SMARTSPACE_DISMISS", true,
"Adds a menu option to dismiss the current Enhanced Smartspace card.");
public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS =
@@ -226,12 +230,20 @@
public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = new DeviceFlag(
"ENABLE_ENFORCED_ROUNDED_CORNERS", true, "Enforce rounded corners on all App Widgets");
+ public static final BooleanFlag ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER = new DeviceFlag(
+ "ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER", true,
+ "Enables a local filter for recommended widgets.");
+
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false,
"Sends a notification whenever launcher encounters an uncaught exception.");
public static final BooleanFlag PROTOTYPE_APP_CLOSE = getDebugFlag(
"PROTOTYPE_APP_CLOSE", false, "Enables new app close");
+ public static final BooleanFlag ENABLE_WALLPAPER_SCRIM = getDebugFlag(
+ "ENABLE_WALLPAPER_SCRIM", false,
+ "Enables scrim over wallpaper for text protection.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index d5a04a6..5ba36f2 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -64,7 +64,6 @@
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.WidgetCellPreview;
-import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetImageView;
import com.android.launcher3.widget.WidgetManagerHelper;
@@ -234,7 +233,7 @@
PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(widgetInfo);
pendingInfo.spanX = Math.min(mIdp.numColumns, widgetInfo.spanX);
pendingInfo.spanY = Math.min(mIdp.numRows, widgetInfo.spanY);
- mWidgetOptions = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo);
+ mWidgetOptions = pendingInfo.getDefaultSizeOptions(this);
mWidgetCell.getWidgetView().setTag(pendingInfo);
applyWidgetItemAsync(() -> new WidgetItem(widgetInfo, mIdp, mApp.getIconCache()));
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d7f6cdb..5731db4 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -16,46 +16,37 @@
package com.android.launcher3.dragndrop;
-import static com.android.launcher3.AbstractFloatingView.TYPE_DISCOVERY_BOUNCE;
-import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.Utilities.ATLEAST_Q;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import android.animation.ValueAnimator;
import android.content.ComponentName;
-import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.DragEvent;
-import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.TouchController;
+import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.Optional;
/**
* Class for initiating a drag within a view or across multiple views.
+ * @param <T>
*/
-public class DragController implements DragDriver.EventListener, TouchController {
- private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
+public abstract class DragController<T extends ActivityContext>
+ implements DragDriver.EventListener, TouchController {
/**
* When a drag is started from a deep press, you need to drag this much farther than normal to
@@ -63,8 +54,7 @@
*/
private static final int DEEP_PRESS_DISTANCE_FACTOR = 3;
- private final Launcher mLauncher;
- private final FlingToDeleteHelper mFlingToDeleteHelper;
+ protected final T mActivity;
// temporaries to avoid gc thrash
private final Rect mRectTemp = new Rect();
@@ -74,30 +64,30 @@
* Drag driver for the current drag/drop operation, or null if there is no active DND operation.
* It's null during accessible drag operations.
*/
- private DragDriver mDragDriver = null;
+ protected DragDriver mDragDriver = null;
/** Options controlling the drag behavior. */
- private DragOptions mOptions;
+ protected DragOptions mOptions;
/** Coordinate for motion down event */
- private final Point mMotionDown = new Point();
+ protected final Point mMotionDown = new Point();
/** Coordinate for last touch event **/
- private final Point mLastTouch = new Point();
+ protected final Point mLastTouch = new Point();
private final Point mTmpPoint = new Point();
- private DropTarget.DragObject mDragObject;
+ protected DropTarget.DragObject mDragObject;
/** Who can receive drop events */
private final ArrayList<DropTarget> mDropTargets = new ArrayList<>();
private final ArrayList<DragListener> mListeners = new ArrayList<>();
- private DropTarget mLastDropTarget;
+ protected DropTarget mLastDropTarget;
private int mLastTouchClassification;
- private int mDistanceSinceScroll = 0;
+ protected int mDistanceSinceScroll = 0;
- private boolean mIsInPreDrag;
+ protected boolean mIsInPreDrag;
/**
* Interface to receive notifications when a drag starts or stops
@@ -120,9 +110,8 @@
/**
* Used to create a new DragLayer from XML.
*/
- public DragController(Launcher launcher) {
- mLauncher = launcher;
- mFlingToDeleteHelper = new FlingToDeleteHelper(launcher);
+ public DragController(T activity) {
+ mActivity = activity;
}
/**
@@ -199,7 +188,7 @@
options);
}
- private DragView startDrag(
+ protected abstract DragView startDrag(
@Nullable Drawable drawable,
@Nullable View view,
DraggableView originalView,
@@ -211,113 +200,19 @@
Rect dragRegion,
float initialDragViewScale,
float dragViewScaleOnDrop,
- DragOptions options) {
- if (PROFILE_DRAWING_DURING_DRAG) {
- android.os.Debug.startMethodTracing("Launcher");
- }
+ DragOptions options);
- mLauncher.hideKeyboard();
- AbstractFloatingView.closeOpenViews(mLauncher, false, TYPE_DISCOVERY_BOUNCE);
-
- mOptions = options;
- if (mOptions.simulatedDndStartPoint != null) {
- mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x;
- mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y;
- }
-
- final int registrationX = mMotionDown.x - dragLayerX;
- final int registrationY = mMotionDown.y - dragLayerY;
-
- final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
- final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
-
- mLastDropTarget = null;
-
- mDragObject = new DropTarget.DragObject(mLauncher.getApplicationContext());
- mDragObject.originalView = originalView;
-
- mIsInPreDrag = mOptions.preDragCondition != null
- && !mOptions.preDragCondition.shouldStartDrag(0);
-
- final Resources res = mLauncher.getResources();
- final float scaleDps = mIsInPreDrag
- ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
- final DragView dragView = mDragObject.dragView = drawable != null
- ? new DragView(
- mLauncher,
- drawable,
- registrationX,
- registrationY,
- initialDragViewScale,
- dragViewScaleOnDrop,
- scaleDps)
- : new DragView(
- mLauncher,
- view,
- view.getMeasuredWidth(),
- view.getMeasuredHeight(),
- registrationX,
- registrationY,
- initialDragViewScale,
- dragViewScaleOnDrop,
- scaleDps);
- dragView.setItemInfo(dragInfo);
- mDragObject.dragComplete = false;
-
- mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
- mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
-
- mDragDriver = DragDriver.create(this, mOptions, mFlingToDeleteHelper::recordMotionEvent);
- if (!mOptions.isAccessibleDrag) {
- mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
- }
-
- mDragObject.dragSource = source;
- mDragObject.dragInfo = dragInfo;
- mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
-
- if (dragOffset != null) {
- dragView.setDragVisualizeOffset(new Point(dragOffset));
- }
- if (dragRegion != null) {
- dragView.setDragRegion(new Rect(dragRegion));
- }
-
- mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- dragView.show(mLastTouch.x, mLastTouch.y);
- mDistanceSinceScroll = 0;
-
- if (!mIsInPreDrag) {
- callOnDragStart();
- } else if (mOptions.preDragCondition != null) {
- mOptions.preDragCondition.onPreDragStart(mDragObject);
- }
-
- handleMoveEvent(mLastTouch.x, mLastTouch.y);
-
- if (!mLauncher.isTouchInProgress() && options.simulatedDndStartPoint == null) {
- // If it is an internal drag and the touch is already complete, cancel immediately
- MAIN_EXECUTOR.submit(this::cancelDrag);
- }
- return dragView;
- }
-
- private void callOnDragStart() {
+ protected void callOnDragStart() {
if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
}
mIsInPreDrag = false;
+ mDragObject.dragView.onDragStart();
for (DragListener listener : new ArrayList<>(mListeners)) {
listener.onDragStart(mDragObject, mOptions);
}
}
- public void addFirstFrameAnimationHelper(ValueAnimator anim) {
- if (mDragObject != null && mDragObject.dragView != null) {
- mDragObject.dragView.mFirstFrameAnimatorHelper.addTo(anim);
- }
- }
-
public Optional<InstanceId> getLogInstanceId() {
return Optional.ofNullable(mDragObject)
.map(dragObject -> dragObject.logInstanceId);
@@ -363,13 +258,15 @@
if (!accepted) {
// If it was not accepted, cleanup the state. If it was accepted, it is the
// responsibility of the drop target to cleanup the state.
- mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
+ exitDrag();
mDragObject.deferDragViewCleanupPostAnimation = false;
}
mDragObject.dragSource.onDropCompleted(dropTarget, mDragObject, accepted);
}
+ protected abstract void exitDrag();
+
public void onAppsRemoved(ItemInfoMatcher matcher) {
// Cancel the current drag if we are removing an app that we are dragging
if (mDragObject != null) {
@@ -383,7 +280,7 @@
}
}
- private void endDrag() {
+ protected void endDrag() {
if (isDragging()) {
mDragDriver = null;
boolean isDeferred = false;
@@ -402,8 +299,6 @@
callOnDragEnd();
}
}
-
- mFlingToDeleteHelper.releaseVelocityTracker();
}
public void animateDragViewToOriginalPosition(final Runnable onComplete,
@@ -449,7 +344,7 @@
* Clamps the position to the drag layer bounds.
*/
private Point getClampedDragLayerPos(float x, float y) {
- mLauncher.getDragLayer().getLocalVisibleRect(mRectTemp);
+ mActivity.getDragLayer().getLocalVisibleRect(mRectTemp);
mTmpPoint.x = (int) Math.max(mRectTemp.left, Math.min(x, mRectTemp.right - 1));
mTmpPoint.y = (int) Math.max(mRectTemp.top, Math.min(y, mRectTemp.bottom - 1));
return mTmpPoint;
@@ -471,19 +366,16 @@
@Override
public void onDriverDragEnd(float x, float y) {
- DropTarget dropTarget;
- Runnable flingAnimation = mFlingToDeleteHelper.getFlingAnimation(mDragObject, mOptions);
- if (flingAnimation != null) {
- dropTarget = mFlingToDeleteHelper.getDropTarget();
- } else {
- dropTarget = findDropTarget((int) x, (int) y, mCoordinatesTemp);
+ if (!endWithFlingAnimation()) {
+ drop(findDropTarget((int) x, (int) y, mCoordinatesTemp), null);
}
-
- drop(dropTarget, flingAnimation);
-
endDrag();
}
+ protected boolean endWithFlingAnimation() {
+ return false;
+ }
+
@Override
public void onDriverDragCancel() {
cancelDrag();
@@ -526,7 +418,7 @@
return mDragDriver != null && mDragDriver.onDragEvent(event);
}
- private void handleMoveEvent(int x, int y) {
+ protected void handleMoveEvent(int x, int y) {
mDragObject.dragView.move(x, y);
// Drop on someone?
@@ -598,7 +490,7 @@
endDrag();
}
- private void drop(DropTarget dropTarget, Runnable flingAnimation) {
+ protected void drop(DropTarget dropTarget, Runnable flingAnimation) {
final int[] coordinates = mCoordinatesTemp;
mDragObject.x = coordinates[0];
mDragObject.y = coordinates[1];
@@ -655,7 +547,7 @@
if (r.contains(x, y)) {
dropCoordinates[0] = x;
dropCoordinates[1] = y;
- mLauncher.getDragLayer().mapCoordInSelfToDescendant((View) target, dropCoordinates);
+ mActivity.getDragLayer().mapCoordInSelfToDescendant((View) target, dropCoordinates);
return target;
}
}
@@ -663,11 +555,11 @@
// cell layout to drop to in the existing drag/drop logic.
dropCoordinates[0] = x;
dropCoordinates[1] = y;
- mLauncher.getDragLayer().mapCoordInSelfToDescendant(mLauncher.getWorkspace(),
- dropCoordinates);
- return mLauncher.getWorkspace();
+ return getDefaultDropTarget(dropCoordinates);
}
+ protected abstract DropTarget getDefaultDropTarget(int[] dropCoordinates);
+
/**
* Sets the drag listener which will be notified when a drag starts or ends.
*/
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 68a8af2..30ee9ec 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -51,7 +51,6 @@
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.FirstFrameAnimatorHelper;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
@@ -62,6 +61,7 @@
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
@@ -85,12 +85,13 @@
private final float mScaleOnDrop;
private final int[] mTempLoc = new int[2];
+ private final RunnableList mOnDragStartCallback = new RunnableList();
+
private Point mDragVisualizeOffset = null;
private Rect mDragRegion = null;
private final Launcher mLauncher;
private final DragLayer mDragLayer;
@Thunk final DragController mDragController;
- final FirstFrameAnimatorHelper mFirstFrameAnimatorHelper;
private boolean mHasDrawn = false;
final ValueAnimator mAnim;
@@ -136,7 +137,6 @@
mLauncher = launcher;
mDragLayer = launcher.getDragLayer();
mDragController = launcher.getDragController();
- mFirstFrameAnimatorHelper = new FirstFrameAnimatorHelper(this);
mContent = content;
mWidth = width;
@@ -276,7 +276,8 @@
}
mFgSpringDrawable.setBounds(bounds);
- new Handler(Looper.getMainLooper()).post(() -> {
+ new Handler(Looper.getMainLooper()).post(() -> mOnDragStartCallback.add(() -> {
+ // TODO: Consider fade-in animation
// Assign the variable on the UI thread to avoid race conditions.
mScaledMaskPath = mask;
// Avoid relayout as we do not care about children affecting layout
@@ -290,11 +291,18 @@
mBadge.setColorFilter(d.getColorFilter());
}
invalidate();
- });
+ }));
}
});
}
+ /**
+ * Called when pre-drag finishes for an icon
+ */
+ public void onDragStart() {
+ mOnDragStartCallback.executeAllAndDestroy();
+ }
+
// TODO(b/183609936): This is only for LauncherAppWidgetHostView that is rendered in a drawable.
// Once LauncherAppWidgetHostView is directly rendered in this view, removes this method.
@Override
diff --git a/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java b/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
index 0a1aba1..336fced 100644
--- a/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
+++ b/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
@@ -22,6 +22,7 @@
import android.view.ViewConfiguration;
import com.android.launcher3.ButtonDropTarget;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@@ -35,15 +36,12 @@
private static final float MAX_FLING_DEGREES = 35f;
private final Launcher mLauncher;
- private final int mFlingToDeleteThresholdVelocity;
private ButtonDropTarget mDropTarget;
private VelocityTracker mVelocityTracker;
public FlingToDeleteHelper(Launcher launcher) {
mLauncher = launcher;
- mFlingToDeleteThresholdVelocity = launcher.getResources()
- .getDimensionPixelSize(R.dimen.drag_flingToDeleteMinVelocity);
}
public void recordMotionEvent(MotionEvent ev) {
@@ -91,12 +89,13 @@
mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
PointF vel = new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
float theta = MAX_FLING_DEGREES + 1;
- if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
+ DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
+ if (mVelocityTracker.getYVelocity() < deviceProfile.flingToDeleteThresholdVelocity) {
// Do a quick dot product test to ensure that we are flinging upwards
PointF upVec = new PointF(0f, -1f);
theta = getAngleBetweenVectors(vel, upVec);
} else if (mLauncher.getDeviceProfile().isVerticalBarLayout() &&
- mVelocityTracker.getXVelocity() < mFlingToDeleteThresholdVelocity) {
+ mVelocityTracker.getXVelocity() < deviceProfile.flingToDeleteThresholdVelocity) {
// Remove icon is on left side instead of top, so check if we are flinging to the left.
PointF leftVec = new PointF(-1f, 0f);
theta = getAngleBetweenVectors(vel, leftVec);
diff --git a/src/com/android/launcher3/dragndrop/LauncherDragController.java b/src/com/android/launcher3/dragndrop/LauncherDragController.java
new file mode 100644
index 0000000..a98d70c
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/LauncherDragController.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.dragndrop;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_DISCOVERY_BOUNCE;
+import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.view.HapticFeedbackConstants;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.accessibility.DragViewStateAnnouncer;
+import com.android.launcher3.model.data.ItemInfo;
+
+/**
+ * Drag controller for Launcher activity
+ */
+public class LauncherDragController extends DragController<Launcher> {
+
+ private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
+
+ private final FlingToDeleteHelper mFlingToDeleteHelper;
+
+ public LauncherDragController(Launcher launcher) {
+ super(launcher);
+ mFlingToDeleteHelper = new FlingToDeleteHelper(launcher);
+ }
+
+ @Override
+ protected DragView startDrag(
+ @Nullable Drawable drawable,
+ @Nullable View view,
+ DraggableView originalView,
+ int dragLayerX,
+ int dragLayerY,
+ DragSource source,
+ ItemInfo dragInfo,
+ Point dragOffset,
+ Rect dragRegion,
+ float initialDragViewScale,
+ float dragViewScaleOnDrop,
+ DragOptions options) {
+ if (PROFILE_DRAWING_DURING_DRAG) {
+ android.os.Debug.startMethodTracing("Launcher");
+ }
+
+ mActivity.hideKeyboard();
+ AbstractFloatingView.closeOpenViews(mActivity, false, TYPE_DISCOVERY_BOUNCE);
+
+ mOptions = options;
+ if (mOptions.simulatedDndStartPoint != null) {
+ mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x;
+ mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y;
+ }
+
+ final int registrationX = mMotionDown.x - dragLayerX;
+ final int registrationY = mMotionDown.y - dragLayerY;
+
+ final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
+ final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
+
+ mLastDropTarget = null;
+
+ mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext());
+ mDragObject.originalView = originalView;
+
+ mIsInPreDrag = mOptions.preDragCondition != null
+ && !mOptions.preDragCondition.shouldStartDrag(0);
+
+ final Resources res = mActivity.getResources();
+ final float scaleDps = mIsInPreDrag
+ ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
+ final DragView dragView = mDragObject.dragView = drawable != null
+ ? new DragView(
+ mActivity,
+ drawable,
+ registrationX,
+ registrationY,
+ initialDragViewScale,
+ dragViewScaleOnDrop,
+ scaleDps)
+ : new DragView(
+ mActivity,
+ view,
+ view.getMeasuredWidth(),
+ view.getMeasuredHeight(),
+ registrationX,
+ registrationY,
+ initialDragViewScale,
+ dragViewScaleOnDrop,
+ scaleDps);
+ dragView.setItemInfo(dragInfo);
+ mDragObject.dragComplete = false;
+
+ mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
+ mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
+
+ mDragDriver = DragDriver.create(this, mOptions, mFlingToDeleteHelper::recordMotionEvent);
+ if (!mOptions.isAccessibleDrag) {
+ mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
+ }
+
+ mDragObject.dragSource = source;
+ mDragObject.dragInfo = dragInfo;
+ mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
+
+ if (dragOffset != null) {
+ dragView.setDragVisualizeOffset(new Point(dragOffset));
+ }
+ if (dragRegion != null) {
+ dragView.setDragRegion(new Rect(dragRegion));
+ }
+
+ mActivity.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ dragView.show(mLastTouch.x, mLastTouch.y);
+ mDistanceSinceScroll = 0;
+
+ if (!mIsInPreDrag) {
+ callOnDragStart();
+ } else if (mOptions.preDragCondition != null) {
+ mOptions.preDragCondition.onPreDragStart(mDragObject);
+ }
+
+ handleMoveEvent(mLastTouch.x, mLastTouch.y);
+
+ if (!mActivity.isTouchInProgress() && options.simulatedDndStartPoint == null) {
+ // If it is an internal drag and the touch is already complete, cancel immediately
+ MAIN_EXECUTOR.submit(this::cancelDrag);
+ }
+ return dragView;
+ }
+
+ @Override
+ protected void exitDrag() {
+ mActivity.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
+ }
+
+ @Override
+ protected boolean endWithFlingAnimation() {
+ Runnable flingAnimation = mFlingToDeleteHelper.getFlingAnimation(mDragObject, mOptions);
+ if (flingAnimation != null) {
+ drop(mFlingToDeleteHelper.getDropTarget(), flingAnimation);
+ return true;
+ }
+ return super.endWithFlingAnimation();
+ }
+
+ @Override
+ protected void endDrag() {
+ super.endDrag();
+ mFlingToDeleteHelper.releaseVelocityTracker();
+ }
+
+ @Override
+ protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
+ mActivity.getDragLayer().mapCoordInSelfToDescendant(mActivity.getWorkspace(),
+ dropCoordinates);
+ return mActivity.getWorkspace();
+ }
+}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index cf1cb45..22d1b1c 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
@@ -31,6 +30,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
@@ -38,6 +38,8 @@
import android.graphics.Insets;
import android.graphics.Path;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.text.InputType;
import android.text.Selection;
@@ -45,6 +47,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
+import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.FocusFinder;
import android.view.KeyEvent;
@@ -96,10 +99,12 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.views.ClipPathView;
+import com.android.launcher3.widget.LocalColorExtractor;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.util.ArrayList;
@@ -152,6 +157,7 @@
private static final float ICON_OVERSCROLL_WIDTH_FACTOR = 0.45f;
private static final int FOLDER_NAME_ANIMATION_DURATION = 633;
+ private static final int FOLDER_COLOR_ANIMATION_DURATION = 150;
private static final int REORDER_DELAY = 250;
private static final int ON_EXIT_CLOSE_DELAY = 400;
@@ -169,8 +175,9 @@
private boolean mIsAnimatingClosed = false;
// Folder can be displayed in Launcher's activity or a separate window (e.g. Taskbar).
- // Anything specific to Launcher should use mLauncher, otherwise should use mActivityContext.
- protected final Launcher mLauncher;
+ // Anything specific to Launcher should use mLauncherDelegate, otherwise should
+ // use mActivityContext.
+ protected final LauncherDelegate mLauncherDelegate;
protected final ActivityContext mActivityContext;
protected DragController mDragController;
@@ -224,6 +231,17 @@
@Nullable private FolderWindowInsetsAnimationCallback mFolderWindowInsetsAnimationCallback;
+ // Wallpaper local color extraction
+ @Nullable private LocalColorExtractor mColorExtractor;
+ @Nullable private LocalColorExtractor.Listener mColorListener;
+
+ // For simplicity, we start the color change only after the open animation has started.
+ private Runnable mColorChangeRunnable;
+ private Animator mColorChangeAnimator;
+ // The background color animator used in the folder open animation. We keep a reference to this,
+ // so that we can cancel it when starting mColorChangeAnimator.
+ private ObjectAnimator mOpenAnimationColorChangeAnimator;
+
/**
* Used to inflate the Workspace from XML.
*
@@ -234,20 +252,20 @@
super(context, attrs);
setAlwaysDrawnWithCacheEnabled(false);
- mLauncher = Launcher.getLauncher(context);
mActivityContext = ActivityContext.lookupContext(context);
+ mLauncherDelegate = LauncherDelegate.from(mActivityContext);
+
mStatsLogManager = StatsLogManager.newInstance(context);
// We need this view to be focusable in touch mode so that when text editing of the folder
// name is complete, we have something to focus on, thus hiding the cursor and giving
// reliable behavior when clicking the text field (since it will always gain focus on click).
setFocusableInTouchMode(true);
-
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- final DeviceProfile dp = mLauncher.getDeviceProfile();
+ final DeviceProfile dp = mActivityContext.getDeviceProfile();
final int paddingLeftRight = dp.folderContentPaddingLeftRight;
mContent = findViewById(R.id.folder_content);
@@ -276,11 +294,50 @@
setWindowInsetsAnimationCallback(mFolderWindowInsetsAnimationCallback);
}
+
+ if (Utilities.ATLEAST_S) {
+ mColorExtractor = LocalColorExtractor.newInstance(getContext());
+ mColorListener = (RectF rect, SparseIntArray extractedColors) -> {
+ mColorChangeRunnable = () -> {
+ mColorChangeRunnable = null;
+ int duration = FOLDER_COLOR_ANIMATION_DURATION;
+
+ // Cancel the open animation color change animator.
+ ObjectAnimator existingAnim = mOpenAnimationColorChangeAnimator;
+ if (existingAnim != null && existingAnim.isRunning()) {
+ duration = (int) Math.max(FOLDER_COLOR_ANIMATION_DURATION,
+ existingAnim.getDuration() * (1f - existingAnim.getDuration()));
+ existingAnim.cancel();
+ mOpenAnimationColorChangeAnimator = null;
+ }
+
+ // Start a new animator to the extracted color.
+ int newColor = extractedColors.get(mColorExtractionIndex);
+ GradientDrawable bg = (GradientDrawable) getBackground();
+ mColorChangeAnimator = ObjectAnimator.ofArgb(bg, "color",
+ bg.getColor().getDefaultColor(), newColor).setDuration(duration);
+ mColorChangeAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mColorChangeAnimator = null;
+ }
+ });
+ mColorChangeAnimator.start();
+ };
+
+ // If the folder open animation has started, we can start the color change now.
+ // Otherwise we wait for it to start.
+ if (mOpenAnimationColorChangeAnimator != null
+ && mOpenAnimationColorChangeAnimator.isStarted()) {
+ post(mColorChangeRunnable);
+ }
+ };
+ }
}
public boolean onLongClick(View v) {
// Return if global dragging is not enabled
- if (!mLauncher.isDraggingEnabled()) return true;
+ if (!mLauncherDelegate.isDraggingEnabled()) return true;
return startDrag(v, new DragOptions());
}
@@ -306,7 +363,7 @@
});
}
- mLauncher.getWorkspace().beginDragShared(v, this, options);
+ mLauncherDelegate.beginDragShared(v, this, options);
}
return true;
}
@@ -362,7 +419,7 @@
if (DEBUG) {
Log.d(TAG, "onBackKey newTitle=" + newTitle);
}
- mInfo.setTitle(newTitle, mLauncher.getModelWriter());
+ mInfo.setTitle(newTitle, mLauncherDelegate.getModelWriter());
mFolderIcon.onTitleChanged(newTitle);
if (TextUtils.isEmpty(mInfo.title)) {
@@ -427,6 +484,7 @@
public void setFolderIcon(FolderIcon icon) {
mFolderIcon = icon;
+ mLauncherDelegate.init(this, icon);
}
@Override
@@ -533,8 +591,8 @@
}
private void startAnimation(final AnimatorSet a) {
- mLauncher.getWorkspace().getVisiblePages()
- .forEach(visiblePage -> addAnimatorListenerForPage(a, (CellLayout) visiblePage));
+ mLauncherDelegate.forEachVisibleWorkspacePage(
+ visiblePage -> addAnimatorListenerForPage(a, (CellLayout) visiblePage));
a.addListener(new AnimatorListenerAdapter() {
@Override
@@ -652,15 +710,18 @@
// dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
mDeleteFolderOnDropCompleted = false;
- if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
- mCurrentAnimator.cancel();
- }
- AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator();
+ cancelRunningAnimations();
+ FolderAnimationManager fam = new FolderAnimationManager(this, true /* isOpening */);
+ AnimatorSet anim = fam.getAnimator();
+ mOpenAnimationColorChangeAnimator = fam.getBgColorAnimator();
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mFolderIcon.setIconVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
+ if (mColorChangeRunnable != null) {
+ mColorChangeRunnable.run();
+ }
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -692,12 +753,12 @@
mFolderName.animate().setDuration(FOLDER_NAME_ANIMATION_DURATION)
.translationX(0)
.setInterpolator(AnimationUtils.loadInterpolator(
- mLauncher, android.R.interpolator.fast_out_slow_in));
+ getContext(), android.R.interpolator.fast_out_slow_in));
mPageIndicator.playEntryAnimation();
if (updateAnimationFlag) {
mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true,
- mLauncher.getModelWriter());
+ mLauncherDelegate.getModelWriter());
}
}
});
@@ -752,6 +813,15 @@
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
+ private void cancelRunningAnimations() {
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
+ }
+ if (mColorChangeAnimator != null && mColorChangeAnimator.isRunning()) {
+ mColorChangeAnimator.cancel();
+ }
+ }
+
private void animateClosed() {
if (mIsAnimatingClosed) {
return;
@@ -760,9 +830,7 @@
mContent.completePendingPageChanges();
mContent.snapToPageImmediately(mContent.getDestinationPage());
- if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
- mCurrentAnimator.cancel();
- }
+ cancelRunningAnimations();
AnimatorSet a = new FolderAnimationManager(this, false /* isOpening */).getAnimator();
a.addListener(new AnimatorListenerAdapter() {
@Override
@@ -837,6 +905,19 @@
clearDragInfo();
mState = STATE_SMALL;
mContent.setCurrentPage(0);
+
+ mOpenAnimationColorChangeAnimator = null;
+ mColorChangeRunnable = null;
+ if (mColorChangeAnimator != null) {
+ mColorChangeAnimator.cancel();
+ mColorChangeAnimator = null;
+ }
+ if (mColorExtractor != null) {
+ mColorExtractor.removeLocations();
+ mColorExtractor.setListener(null);
+ }
+ GradientDrawable bg = (GradientDrawable) getBackground();
+ bg.setColor(Themes.getAttrColor(getContext(), R.attr.folderFillColor));
}
@Override
@@ -1033,7 +1114,7 @@
if (getItemCount() <= mContent.itemsPerPage()) {
// Show the animation, next time something is added to the folder.
mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, false,
- mLauncher.getModelWriter());
+ mLauncherDelegate.getModelWriter());
}
}
@@ -1051,7 +1132,7 @@
}
if (!items.isEmpty()) {
- mLauncher.getModelWriter().moveItemsInDatabase(items, mInfo.id, 0);
+ mLauncherDelegate.getModelWriter().moveItemsInDatabase(items, mInfo.id, 0);
}
if (FeatureFlags.FOLDER_NAME_SUGGEST.get() && !isBind
&& total > 1 /* no need to update if there's one icon */) {
@@ -1104,6 +1185,12 @@
lp.height = height;
lp.x = left;
lp.y = top;
+
+ if (mColorExtractor != null) {
+ mColorExtractor.removeLocations();
+ mColorExtractor.setListener(mColorListener);
+ mLauncherDelegate.addRectForColorExtraction(lp, mColorExtractor);
+ }
}
protected int getContentAreaHeight() {
@@ -1143,7 +1230,7 @@
if (mContent.getChildCount() > 0) {
int cellIconGap = (mContent.getPageAt(0).getCellWidth()
- - mLauncher.getDeviceProfile().iconSizePx) / 2;
+ - mActivityContext.getDeviceProfile().iconSizePx) / 2;
mFooter.setPadding(mContent.getPaddingLeft() + cellIconGap,
mFooter.getPaddingTop(),
mContent.getPaddingRight() + cellIconGap,
@@ -1173,56 +1260,7 @@
}
@Thunk void replaceFolderWithFinalItem() {
- // Add the last remaining child to the workspace in place of the folder
- Runnable onCompleteRunnable = new Runnable() {
- @Override
- public void run() {
- int itemCount = getItemCount();
- if (itemCount <= 1) {
- View newIcon = null;
- WorkspaceItemInfo finalItem = null;
-
- if (itemCount == 1) {
- // Move the item from the folder to the workspace, in the position of the
- // folder
- CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container,
- mInfo.screenId);
- finalItem = mInfo.contents.remove(0);
- newIcon = mLauncher.createShortcut(cellLayout, finalItem);
- mLauncher.getModelWriter().addOrMoveItemInDatabase(finalItem,
- mInfo.container, mInfo.screenId, mInfo.cellX, mInfo.cellY);
- }
-
- // Remove the folder
- mLauncher.removeItem(mFolderIcon, mInfo, true /* deleteFromDb */);
- if (mFolderIcon instanceof DropTarget) {
- mDragController.removeDropTarget((DropTarget) mFolderIcon);
- }
-
- if (newIcon != null) {
- // We add the child after removing the folder to prevent both from existing
- // at the same time in the CellLayout. We need to add the new item with
- // addInScreenFromBind() to ensure that hotseat items are placed correctly.
- mLauncher.getWorkspace().addInScreenFromBind(newIcon, mInfo);
-
- // Focus the newly created child
- newIcon.requestFocus();
- }
- if (finalItem != null) {
- StatsLogger logger = mStatsLogManager.logger().withItemInfo(finalItem);
- mDragController.getLogInstanceId().map(logger::withInstanceId)
- .orElse(logger)
- .log(LAUNCHER_FOLDER_CONVERTED_TO_ICON);
- }
- }
- }
- };
- View finalChild = mContent.getLastItem();
- if (finalChild != null) {
- mFolderIcon.performDestroyAnimation(onCompleteRunnable);
- } else {
- onCompleteRunnable.run();
- }
+ mLauncherDelegate.replaceFolderWithFinalItem(this);
mDestroyed = true;
}
@@ -1281,6 +1319,10 @@
mScrollPauseAlarm.cancelAlarm();
}
mContent.completePendingPageChanges();
+ Launcher launcher = mLauncherDelegate.getLauncher();
+ if (launcher == null) {
+ return;
+ }
PendingAddShortcutInfo pasi = d.dragInfo instanceof PendingAddShortcutInfo
? (PendingAddShortcutInfo) d.dragInfo : null;
@@ -1290,7 +1332,7 @@
pasi.container = mInfo.id;
pasi.rank = mEmptyCellRank;
- mLauncher.addPendingItem(pasi, pasi.container, pasi.screenId, null, pasi.spanX,
+ launcher.addPendingItem(pasi, pasi.container, pasi.screenId, null, pasi.spanX,
pasi.spanY);
d.deferDragViewCleanupPostAnimation = false;
mRearrangeOnClose = true;
@@ -1312,7 +1354,7 @@
// Actually move the item in the database if it was an external drag. Call this
// before creating the view, so that WorkspaceItemInfo is updated appropriately.
- mLauncher.getModelWriter().addOrMoveItemInDatabase(
+ mLauncherDelegate.getModelWriter().addOrMoveItemInDatabase(
si, mInfo.id, 0, si.cellX, si.cellY);
mIsExternalDrag = false;
} else {
@@ -1327,7 +1369,7 @@
float scaleY = getScaleY();
setScaleX(1.0f);
setScaleY(1.0f);
- mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView, null);
+ launcher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView, null);
setScaleX(scaleX);
setScaleY(scaleY);
} else {
@@ -1355,10 +1397,11 @@
if (mContent.getPageCount() > 1) {
// The animation has already been shown while opening the folder.
- mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher.getModelWriter());
+ mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true,
+ mLauncherDelegate.getModelWriter());
}
- mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
+ launcher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY);
if (d.stateAnnouncer != null) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
@@ -1387,7 +1430,7 @@
FolderGridOrganizer verifier = new FolderGridOrganizer(
mActivityContext.getDeviceProfile().inv).setFolderInfo(mInfo);
verifier.updateRankAndPos(item, rank);
- mLauncher.getModelWriter().addOrMoveItemInDatabase(item, mInfo.id, 0, item.cellX,
+ mLauncherDelegate.getModelWriter().addOrMoveItemInDatabase(item, mInfo.id, 0, item.cellX,
item.cellY);
updateItemLocationsInDatabaseBatch(false);
@@ -1620,17 +1663,9 @@
return true;
}
return false;
- } else if (!dl.isEventOverView(this, ev)) {
- if (mLauncher.getAccessibilityDelegate().isInAccessibleDrag()) {
- // Do not close the container if in drag and drop.
- if (!dl.isEventOverView(mLauncher.getDropTargetBar(), ev)) {
- return true;
- }
- } else {
- // TODO: add ww log if need to gather tap outside to close folder
- close(true);
- return true;
- }
+ } else if (!dl.isEventOverView(this, ev)
+ && mLauncherDelegate.interceptOutsideTouch(ev, dl, this)) {
+ return true;
}
}
return false;
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index ee6ea99..af8be8d 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -35,8 +35,6 @@
import android.view.View;
import android.view.animation.AnimationUtils;
-import androidx.core.graphics.ColorUtils;
-
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.R;
@@ -80,6 +78,8 @@
private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
private final FolderGridOrganizer mPreviewVerifier;
+ private ObjectAnimator mBgColorAnimator;
+
public FolderAnimationManager(Folder folder, boolean isOpening) {
mFolder = folder;
mContent = folder.mContent;
@@ -105,6 +105,12 @@
R.interpolator.large_folder_preview_item_close_interpolator);
}
+ /**
+ * Returns the animator that changes the background color.
+ */
+ public ObjectAnimator getBgColorAnimator() {
+ return mBgColorAnimator;
+ }
/**
* Prepares the Folder for animating between open / closed states.
@@ -162,10 +168,15 @@
final float yDistance = initialY - lp.y;
// Set up the Folder background.
- final int finalColor = ColorUtils.setAlphaComponent(
- Themes.getAttrColor(mContext, R.attr.folderFillColor), 255);
- final int initialColor = setColorAlphaBound(
- finalColor, mPreviewBackground.getBackgroundAlpha());
+ int previewBackgroundColor = Themes.getAttrColor(mContext, R.attr.folderFillColor);
+ final int finalColor;
+ if (mIsOpening) {
+ finalColor = Themes.getAttrColor(mContext, R.attr.popupColorPrimary);
+ } else {
+ finalColor = mFolderBackground.getColor().getDefaultColor();
+ }
+ final int initialColor = setColorAlphaBound(previewBackgroundColor,
+ mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
@@ -193,11 +204,12 @@
play(a, anim);
}
+ mBgColorAnimator = getAnimator(mFolderBackground, "color", initialColor, finalColor);
+ play(a, mBgColorAnimator);
play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
play(a, getAnimator(mFolder.mContent, SCALE_PROPERTY, initialScale, finalScale));
play(a, getAnimator(mFolder.mFooter, SCALE_PROPERTY, initialScale, finalScale));
- play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
play(a, mFolderIcon.mFolderName.createTextAlphaAnimator(!mIsOpening));
play(a, getShape().createRevealAnimator(
mFolder, startRect, endRect, finalRadius, !mIsOpening));
@@ -409,7 +421,7 @@
: ObjectAnimator.ofFloat(view, property, v2, v1);
}
- private Animator getAnimator(GradientDrawable drawable, String property, int v1, int v2) {
+ private ObjectAnimator getAnimator(GradientDrawable drawable, String property, int v1, int v2) {
return mIsOpening
? ObjectAnimator.ofArgb(drawable, property, v1, v2)
: ObjectAnimator.ofArgb(drawable, property, v2, v1);
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 6b02021..279c445 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -169,14 +169,11 @@
public static <T extends Context & ActivityContext> FolderIcon inflateFolderAndIcon(int resId,
T activityContext, ViewGroup group, FolderInfo folderInfo) {
Folder folder = Folder.fromXml(activityContext);
- folder.setDragController(folder.mLauncher.getDragController());
FolderIcon icon = inflateIcon(resId, activityContext, group, folderInfo);
folder.setFolderIcon(icon);
folder.bind(folderInfo);
icon.setFolder(folder);
-
- icon.setOnFocusChangeListener(folder.mLauncher.getFocusHandler());
icon.mBackground.paddingY = icon.isInHotseat()
? 0 : activityContext.getDeviceProfile().cellYPaddingPx;
return icon;
@@ -467,7 +464,7 @@
CharSequence newTitle = nameInfos.getLabels()[0];
FromState fromState = mInfo.getFromLabelState();
- mInfo.setTitle(newTitle, mFolder.mLauncher.getModelWriter());
+ mInfo.setTitle(newTitle, mFolder.mLauncherDelegate.getModelWriter());
onTitleChanged(mInfo.title);
mFolder.mFolderName.setText(mInfo.title);
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index a4e8be6..7fc3740 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -31,7 +31,6 @@
import android.view.ViewDebug;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseActivity;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
@@ -49,6 +48,7 @@
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.ViewCache;
+import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.Iterator;
@@ -102,7 +102,7 @@
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
- mViewCache = BaseActivity.fromContext(context).getViewCache();
+ mViewCache = ActivityContext.lookupContext(context).getViewCache();
}
public void setFolder(Folder folder) {
diff --git a/src/com/android/launcher3/folder/LauncherDelegate.java b/src/com/android/launcher3/folder/LauncherDelegate.java
new file mode 100644
index 0000000..f7d8e8c
--- /dev/null
+++ b/src/com/android/launcher3/folder/LauncherDelegate.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.folder;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.StatsLogManager.StatsLogger;
+import com.android.launcher3.model.ModelWriter;
+import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.views.BaseDragLayer.LayoutParams;
+import com.android.launcher3.widget.LocalColorExtractor;
+
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * Wrapper around Launcher methods to allow folders in non-launcher context
+ */
+public class LauncherDelegate {
+
+ private final Launcher mLauncher;
+ private final Rect mTempRect = new Rect();
+ private final RectF mTempRectF = new RectF();
+
+ private LauncherDelegate(Launcher launcher) {
+ mLauncher = launcher;
+ }
+
+ void init(Folder folder, FolderIcon icon) {
+ folder.setDragController(mLauncher.getDragController());
+ icon.setOnFocusChangeListener(mLauncher.getFocusHandler());
+ }
+
+ boolean isDraggingEnabled() {
+ return mLauncher.isDraggingEnabled();
+ }
+
+ void beginDragShared(View child, DragSource source, DragOptions options) {
+ mLauncher.getWorkspace().beginDragShared(child, source, options);
+ }
+
+ ModelWriter getModelWriter() {
+ return mLauncher.getModelWriter();
+ }
+
+ void forEachVisibleWorkspacePage(Consumer<View> callback) {
+ mLauncher.getWorkspace().forEachVisiblePage(callback);
+ }
+
+ @Nullable
+ Launcher getLauncher() {
+ return mLauncher;
+ }
+
+ void addRectForColorExtraction(BaseDragLayer.LayoutParams lp, LocalColorExtractor target) {
+ mTempRect.set(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
+ target.getExtractedRectForViewRect(mLauncher,
+ mLauncher.getWorkspace().getCurrentPage(), mTempRect, mTempRectF);
+ if (!mTempRectF.isEmpty()) {
+ target.addLocation(Arrays.asList(mTempRectF));
+ }
+ }
+
+ void replaceFolderWithFinalItem(Folder folder) {
+ // Add the last remaining child to the workspace in place of the folder
+ Runnable onCompleteRunnable = new Runnable() {
+ @Override
+ public void run() {
+ int itemCount = folder.getItemCount();
+ FolderInfo info = folder.mInfo;
+ if (itemCount <= 1) {
+ View newIcon = null;
+ WorkspaceItemInfo finalItem = null;
+
+ if (itemCount == 1) {
+ // Move the item from the folder to the workspace, in the position of the
+ // folder
+ CellLayout cellLayout = mLauncher.getCellLayout(info.container,
+ info.screenId);
+ finalItem = info.contents.remove(0);
+ newIcon = mLauncher.createShortcut(cellLayout, finalItem);
+ mLauncher.getModelWriter().addOrMoveItemInDatabase(finalItem,
+ info.container, info.screenId, info.cellX, info.cellY);
+ }
+
+ // Remove the folder
+ mLauncher.removeItem(folder.mFolderIcon, info, true /* deleteFromDb */);
+ if (folder.mFolderIcon instanceof DropTarget) {
+ folder.mDragController.removeDropTarget((DropTarget) folder.mFolderIcon);
+ }
+
+ if (newIcon != null) {
+ // We add the child after removing the folder to prevent both from existing
+ // at the same time in the CellLayout. We need to add the new item with
+ // addInScreenFromBind() to ensure that hotseat items are placed correctly.
+ mLauncher.getWorkspace().addInScreenFromBind(newIcon, info);
+
+ // Focus the newly created child
+ newIcon.requestFocus();
+ }
+ if (finalItem != null) {
+ StatsLogger logger = mLauncher.getStatsLogManager().logger()
+ .withItemInfo(finalItem);
+ ((Optional<InstanceId>) folder.mDragController.getLogInstanceId())
+ .map(logger::withInstanceId)
+ .orElse(logger)
+ .log(LAUNCHER_FOLDER_CONVERTED_TO_ICON);
+ }
+ }
+ }
+ };
+ View finalChild = folder.mContent.getLastItem();
+ if (finalChild != null) {
+ folder.mFolderIcon.performDestroyAnimation(onCompleteRunnable);
+ } else {
+ onCompleteRunnable.run();
+ }
+ }
+
+
+ boolean interceptOutsideTouch(MotionEvent ev, BaseDragLayer dl, Folder folder) {
+ if (mLauncher.getAccessibilityDelegate().isInAccessibleDrag()) {
+ // Do not close the container if in drag and drop.
+ if (!dl.isEventOverView(mLauncher.getDropTargetBar(), ev)) {
+ return true;
+ }
+ } else {
+ // TODO: add ww log if need to gather tap outside to close folder
+ folder.close(true);
+ return true;
+ }
+ return false;
+ }
+
+ private static class FallbackDelegate extends LauncherDelegate {
+
+ private final ActivityContext mContext;
+ private ModelWriter mWriter;
+
+ FallbackDelegate(ActivityContext context) {
+ super(null);
+ mContext = context;
+ }
+
+ @Override
+ void init(Folder folder, FolderIcon icon) {
+ folder.setDragController(mContext.getDragController());
+ }
+
+ @Override
+ boolean isDraggingEnabled() {
+ return false;
+ }
+
+ @Override
+ void beginDragShared(View child, DragSource source, DragOptions options) { }
+
+ @Override
+ ModelWriter getModelWriter() {
+ if (mWriter == null) {
+ mWriter = LauncherAppState.getInstance((Context) mContext).getModel()
+ .getWriter(false, false);
+ }
+ return mWriter;
+ }
+
+ @Override
+ void forEachVisibleWorkspacePage(Consumer<View> callback) { }
+
+ @Override
+ Launcher getLauncher() {
+ return null;
+ }
+
+ @Override
+ void replaceFolderWithFinalItem(Folder folder) { }
+
+ @Override
+ boolean interceptOutsideTouch(MotionEvent ev, BaseDragLayer dl, Folder folder) {
+ folder.close(true);
+ return true;
+ }
+
+ @Override
+ void addRectForColorExtraction(LayoutParams lp, LocalColorExtractor target) { }
+ }
+
+ static LauncherDelegate from(ActivityContext context) {
+ return context instanceof Launcher
+ ? new LauncherDelegate((Launcher) context)
+ : new FallbackDelegate(context);
+ }
+}
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 8244f01..6adef01 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -400,7 +400,7 @@
drawable.setLevel(item.getProgressLevel());
p.drawable = drawable;
} else {
- p.drawable = item.newIcon(mContext);
+ p.drawable = item.newIcon(mContext, true);
}
p.drawable.setBounds(0, 0, mIconSize, mIconSize);
p.item = item;
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index 911f8c3..cb42e7a 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -90,10 +90,7 @@
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption option = new GridOption(getContext(), Xml.asAttributeSet(parser));
- if (option.visible) {
- result.add(option);
- }
+ result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
}
}
} catch (IOException | XmlPullParserException e) {
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 31764c5..f5b6890 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -20,7 +20,6 @@
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
@@ -118,7 +117,7 @@
* 4) Measure and draw the view on a canvas
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherPreviewRenderer extends ContextThemeWrapper
+public class LauncherPreviewRenderer extends ContextWrapper
implements ActivityContext, WorkspaceLayoutManager, LayoutInflater.Factory2 {
private static final String TAG = "LauncherPreviewRenderer";
@@ -220,11 +219,11 @@
private final CellLayout mWorkspace;
public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
- super(context, R.style.AppTheme);
+ super(context);
mUiHandler = new Handler(Looper.getMainLooper());
mContext = context;
mIdp = idp;
- mDp = idp.portraitProfile.copy(context);
+ mDp = idp.getDeviceProfile(context).copy(context);
mMigrated = migrated;
// TODO: get correct insets once display cutout API is available.
@@ -271,14 +270,6 @@
return mRootView;
}
- public boolean shouldShowRealLauncherPreview() {
- return ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get();
- }
-
- public boolean shouldShowQsb() {
- return FeatureFlags.QSB_ON_FIRST_SCREEN;
- }
-
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
if ("TextClock".equals(name)) {
@@ -402,107 +393,88 @@
}
private void populate() {
- if (shouldShowRealLauncherPreview()) {
- WorkspaceFetcher fetcher;
- PreviewContext previewContext = null;
- if (mMigrated) {
- previewContext = new PreviewContext(mContext, mIdp);
- LauncherAppState appForPreview = new LauncherAppState(
- previewContext, null /* iconCacheFileName */);
- fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
- MODEL_EXECUTOR.execute(fetcher);
- } else {
- fetcher = new WorkspaceItemsInfoFetcher();
- LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
- (LauncherModel.ModelUpdateTask) fetcher);
- }
- WorkspaceResult workspaceResult = fetcher.get();
- if (previewContext != null) {
- previewContext.onDestroy();
- }
-
- if (workspaceResult == null) {
- return;
- }
-
- // Separate the items that are on the current screen, and the other remaining items.
- ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
- ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
- ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
- ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
- filterCurrentWorkspaceItems(0 /* currentScreenId */,
- workspaceResult.mWorkspaceItems, currentWorkspaceItems,
- otherWorkspaceItems);
- filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
- currentAppWidgets, otherAppWidgets);
- sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
- for (ItemInfo itemInfo : currentWorkspaceItems) {
- switch (itemInfo.itemType) {
- case Favorites.ITEM_TYPE_APPLICATION:
- case Favorites.ITEM_TYPE_SHORTCUT:
- case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
- break;
- case Favorites.ITEM_TYPE_FOLDER:
- inflateAndAddFolder((FolderInfo) itemInfo);
- break;
- default:
- break;
- }
- }
- for (ItemInfo itemInfo : currentAppWidgets) {
- switch (itemInfo.itemType) {
- case Favorites.ITEM_TYPE_APPWIDGET:
- case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
- if (mMigrated) {
- inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
- workspaceResult.mWidgetProvidersMap);
- } else {
- inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
- workspaceResult.mWidgetsModel);
- }
- break;
- default:
- break;
- }
- }
- IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
- mDp.numShownHotseatIcons);
- List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
- ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
- int count = Math.min(ranks.size(), predictions.size());
- for (int i = 0; i < count; i++) {
- int rank = ranks.get(i);
- WorkspaceItemInfo itemInfo =
- new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
- itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
- itemInfo.rank = rank;
- itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
- itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
- itemInfo.screenId = rank;
- inflateAndAddPredictedIcon(itemInfo);
- }
+ WorkspaceFetcher fetcher;
+ PreviewContext previewContext = null;
+ if (mMigrated) {
+ previewContext = new PreviewContext(mContext, mIdp);
+ LauncherAppState appForPreview = new LauncherAppState(
+ previewContext, null /* iconCacheFileName */);
+ fetcher = new WorkspaceItemsInfoFromPreviewFetcher(appForPreview);
+ MODEL_EXECUTOR.execute(fetcher);
} else {
- // Add hotseat icons
- for (int i = 0; i < mDp.numShownHotseatIcons; i++) {
- WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
- info.container = Favorites.CONTAINER_HOTSEAT;
- info.screenId = i;
- inflateAndAddIcon(info);
+ fetcher = new WorkspaceItemsInfoFetcher();
+ LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
+ (LauncherModel.ModelUpdateTask) fetcher);
+ }
+ WorkspaceResult workspaceResult = fetcher.get();
+ if (previewContext != null) {
+ previewContext.onDestroy();
+ }
+
+ if (workspaceResult == null) {
+ return;
+ }
+
+ // Separate the items that are on the current screen, and the other remaining items.
+ ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
+ ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
+ ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
+ ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
+ filterCurrentWorkspaceItems(0 /* currentScreenId */,
+ workspaceResult.mWorkspaceItems, currentWorkspaceItems,
+ otherWorkspaceItems);
+ filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
+ currentAppWidgets, otherAppWidgets);
+ sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
+ for (ItemInfo itemInfo : currentWorkspaceItems) {
+ switch (itemInfo.itemType) {
+ case Favorites.ITEM_TYPE_APPLICATION:
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ inflateAndAddIcon((WorkspaceItemInfo) itemInfo);
+ break;
+ case Favorites.ITEM_TYPE_FOLDER:
+ inflateAndAddFolder((FolderInfo) itemInfo);
+ break;
+ default:
+ break;
}
- // Add workspace icons
- for (int i = 0; i < mIdp.numColumns; i++) {
- WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
- info.container = Favorites.CONTAINER_DESKTOP;
- info.screenId = 0;
- info.cellX = i;
- info.cellY = mIdp.numRows - 1;
- inflateAndAddIcon(info);
+ }
+ for (ItemInfo itemInfo : currentAppWidgets) {
+ switch (itemInfo.itemType) {
+ case Favorites.ITEM_TYPE_APPWIDGET:
+ case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
+ if (mMigrated) {
+ inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+ workspaceResult.mWidgetProvidersMap);
+ } else {
+ inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+ workspaceResult.mWidgetsModel);
+ }
+ break;
+ default:
+ break;
}
}
+ IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
+ mDp.numShownHotseatIcons);
+ List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
+ ? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
+ int count = Math.min(ranks.size(), predictions.size());
+ for (int i = 0; i < count; i++) {
+ int rank = ranks.get(i);
+ WorkspaceItemInfo itemInfo =
+ new WorkspaceItemInfo((WorkspaceItemInfo) predictions.get(i));
+ itemInfo.container = CONTAINER_HOTSEAT_PREDICTION;
+ itemInfo.rank = rank;
+ itemInfo.cellX = mHotseat.getCellXFromOrder(rank);
+ itemInfo.cellY = mHotseat.getCellYFromOrder(rank);
+ itemInfo.screenId = rank;
+ inflateAndAddPredictedIcon(itemInfo);
+ }
// Add first page QSB
- if (shouldShowQsb()) {
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
View qsb = mHomeElementInflater.inflate(
R.layout.search_container_workspace, mWorkspace, false);
CellLayout.LayoutParams lp =
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index fdc3a94..6193570 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import android.app.WallpaperColors;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
@@ -28,18 +29,23 @@
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.SurfaceControlViewHost;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.R;
import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.model.GridSizeMigrationTaskV2;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.LocalColorExtractor;
import java.util.concurrent.TimeUnit;
/** Render preview using surface view. */
+@SuppressWarnings("NewApi")
public class PreviewSurfaceRenderer implements IBinder.DeathRecipient {
private static final int FADE_IN_ANIMATION_DURATION = 200;
@@ -50,6 +56,7 @@
private static final String KEY_DISPLAY_ID = "display_id";
private static final String KEY_SURFACE_PACKAGE = "surface_package";
private static final String KEY_CALLBACK = "callback";
+ private static final String KEY_COLORS = "wallpaper_colors";
private final Context mContext;
private final InvariantDeviceProfile mIdp;
@@ -57,6 +64,7 @@
private final int mWidth;
private final int mHeight;
private final Display mDisplay;
+ private final WallpaperColors mWallpaperColors;
private SurfaceControlViewHost mSurfaceControlViewHost;
@@ -68,6 +76,8 @@
if (gridName == null) {
gridName = InvariantDeviceProfile.getCurrentGridName(context);
}
+ mWallpaperColors = bundle.getParcelable(KEY_COLORS);
+
mIdp = new InvariantDeviceProfile(context, gridName);
mHostToken = bundle.getBinder(KEY_HOST_TOKEN);
@@ -100,6 +110,19 @@
MODEL_EXECUTOR.post(() -> {
final boolean success = doGridMigrationIfNecessary();
+ final Context inflationContext;
+ if (mWallpaperColors != null) {
+ // Workaround to create a themed context
+ Context context = mContext.createDisplayContext(mDisplay);
+ LocalColorExtractor.newInstance(mContext)
+ .applyColorsOverride(context, mWallpaperColors);
+
+ inflationContext = new ContextThemeWrapper(context,
+ Themes.getActivityThemeRes(context, mWallpaperColors.getColorHints()));
+ } else {
+ inflationContext = new ContextThemeWrapper(mContext, R.style.AppTheme);
+ }
+
MAIN_EXECUTOR.post(() -> {
// If mSurfaceControlViewHost is null due to any reason (e.g. binder died,
// happening when user leaves the preview screen before preview rendering finishes),
@@ -109,7 +132,8 @@
return;
}
- View view = new LauncherPreviewRenderer(mContext, mIdp, success).getRenderedView();
+ View view = new LauncherPreviewRenderer(inflationContext, mIdp, success)
+ .getRenderedView();
// This aspect scales the view to fit in the surface and centers it
final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(),
mHeight / (float) view.getMeasuredHeight());
diff --git a/src/com/android/launcher3/graphics/SysUiScrim.java b/src/com/android/launcher3/graphics/SysUiScrim.java
index c09dac8..f0766c5 100644
--- a/src/com/android/launcher3/graphics/SysUiScrim.java
+++ b/src/com/android/launcher3/graphics/SysUiScrim.java
@@ -45,7 +45,10 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.Themes;
+import com.android.systemui.plugins.ResourceProvider;
/**
* View scrim which draws behind hotseat and workspace
@@ -101,8 +104,10 @@
private static final int ALPHA_MASK_BITMAP_DP = 200;
private static final int ALPHA_MASK_WIDTH_DP = 2;
- private boolean mDrawTopScrim, mDrawBottomScrim;
+ private boolean mDrawTopScrim, mDrawBottomScrim, mDrawWallpaperScrim;
+ private final RectF mWallpaperScrimRect = new RectF();
+ private final Paint mWallpaperScrimPaint = new Paint();
private final RectF mFinalMaskRect = new RectF();
private final Paint mBottomMaskPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
private final Bitmap mBottomMask;
@@ -117,6 +122,7 @@
private boolean mAnimateScrimOnNextDraw = false;
private float mSysUiAnimMultiplier = 1;
+ private int mWallpaperScrimMaxAlpha;
public SysUiScrim(View view) {
mRoot = view;
@@ -127,6 +133,14 @@
mBottomMask = mTopScrim == null ? null : createDitheredAlphaMask();
mHideSysUiScrim = mTopScrim == null;
+ mDrawWallpaperScrim = FeatureFlags.ENABLE_WALLPAPER_SCRIM.get()
+ && !Themes.getAttrBoolean(view.getContext(), R.attr.isMainColorDark)
+ && !Themes.getAttrBoolean(view.getContext(), R.attr.isWorkspaceDarkText);
+ ResourceProvider rp = DynamicResource.provider(view.getContext());
+ int wallpaperScrimColor = rp.getColor(R.color.wallpaper_scrim_color);
+ mWallpaperScrimMaxAlpha = Color.alpha(wallpaperScrimColor);
+ mWallpaperScrimPaint.setColor(wallpaperScrimColor);
+
view.addOnAttachStateChangeListener(this);
}
@@ -151,6 +165,9 @@
mAnimateScrimOnNextDraw = false;
}
+ if (mDrawWallpaperScrim) {
+ canvas.drawRect(mWallpaperScrimRect, mWallpaperScrimPaint);
+ }
if (mDrawTopScrim) {
mTopScrim.draw(canvas);
}
@@ -214,6 +231,7 @@
mTopScrim.setBounds(0, 0, w, h);
mFinalMaskRect.set(0, h - mMaskHeight, w, h);
}
+ mWallpaperScrimRect.set(0, 0, w, h);
}
private void setSysUiProgress(float progress) {
@@ -236,6 +254,7 @@
if (mTopScrim != null) {
mTopScrim.setAlpha(Math.round(255 * factor));
}
+ mWallpaperScrimPaint.setAlpha(Math.round(mWallpaperScrimMaxAlpha * factor));
}
private Bitmap createDitheredAlphaMask() {
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index a2c0f5c..297325a 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -52,7 +52,6 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
@@ -82,10 +81,11 @@
private int mPendingIconRequestCount = 0;
public IconCache(Context context, InvariantDeviceProfile idp) {
- this(context, idp, LauncherFiles.APP_ICONS_DB);
+ this(context, idp, LauncherFiles.APP_ICONS_DB, new IconProvider(context));
}
- public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName) {
+ public IconCache(Context context, InvariantDeviceProfile idp, String dbFileName,
+ IconProvider iconProvider) {
super(context, dbFileName, MODEL_EXECUTOR.getLooper(),
idp.fillResIconDpi, idp.iconBitmapSize, true /* inMemoryCache */);
mComponentWithLabelCachingLogic = new ComponentCachingLogic(context, false);
@@ -94,7 +94,7 @@
mLauncherApps = mContext.getSystemService(LauncherApps.class);
mUserManager = UserCache.INSTANCE.get(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
- mIconProvider = new IconProvider(context);
+ mIconProvider = iconProvider;
}
@Override
@@ -108,7 +108,7 @@
}
@Override
- protected BaseIconFactory getIconFactory() {
+ public BaseIconFactory getIconFactory() {
return LauncherIcons.obtain(mContext);
}
@@ -333,15 +333,6 @@
+ ",flags_asi:" + FeatureFlags.APP_SEARCH_IMPROVEMENTS.get();
}
- @Override
- protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
- if (mIconProvider.isClockIcon(cacheKey)) {
- // For clock icon, we always load the dynamic icon
- return false;
- }
- return super.getEntryFromDB(cacheKey, entry, lowRes);
- }
-
/**
* Interface for receiving itemInfo with high-res icon.
*/
diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
index 93de35a..e820ac4 100644
--- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
+++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
@@ -20,6 +20,7 @@
import android.content.pm.LauncherActivityInfo;
import android.os.UserHandle;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -56,8 +57,8 @@
@Override
public BitmapInfo loadIcon(Context context, LauncherActivityInfo object) {
try (LauncherIcons li = LauncherIcons.obtain(context)) {
- return li.createBadgedIconBitmap(new IconProvider(context)
- .getIcon(object, li.mFillResIconDpi),
+ return li.createBadgedIconBitmap(LauncherAppState.getInstance(context)
+ .getIconProvider().getIcon(object, li.mFillResIconDpi),
object.getUser(), object.getApplicationInfo().targetSdkVersion);
}
}
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 29287d9..3be2c3a 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -20,7 +20,6 @@
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller.SessionInfo;
import android.os.UserHandle;
-import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
@@ -28,6 +27,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
@@ -130,7 +130,7 @@
packageName);
if (!packageInstaller.verifySessionInfo(sessionInfo)) {
- Log.d(LOG, "Item info failed session info verification: "
+ FileLog.d(LOG, "Item info failed session info verification: "
+ workspaceInfo);
}
@@ -180,11 +180,11 @@
addedItemsFinal.add(itemInfo);
// log bitmap and label
- Log.d(LOG, "Adding item info to workspace: " + itemInfo);
+ FileLog.d(LOG, "Adding item info to workspace: " + itemInfo);
if (itemInfo instanceof ItemInfoWithIcon) {
ItemInfoWithIcon infoWithIcon = (ItemInfoWithIcon) itemInfo;
- Log.d(LOG, "Item info icon base 64 string: "
+ FileLog.d(LOG, "Item info icon base 64 string: "
+ infoWithIcon.bitmap.icon == null
? "null" : IOUtils.toBase64String(infoWithIcon.bitmap.icon));
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 22cb46b..217f523 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -43,6 +43,7 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -191,11 +192,11 @@
MODEL_EXECUTOR.post(() -> {
Pair<ItemInfo, Object> itemInfo = info.getItemInfo(mContext);
if (itemInfo == null) {
- Log.d(LOG,
+ FileLog.d(LOG,
"Adding PendingInstallShortcutInfo with no attached info to queue.",
stackTrace);
} else {
- Log.d(LOG,
+ FileLog.d(LOG,
"Adding PendingInstallShortcutInfo to queue. Attached info: "
+ itemInfo.first,
stackTrace);
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 897b02e..7e3bcee 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -52,6 +52,7 @@
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
@@ -394,6 +395,11 @@
* otherwise marks it for deletion.
*/
public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) {
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ // Ensure that it is a valid intent. An exception here will
+ // cause the item loading to get skipped
+ ShortcutKey.fromItemInfo(info);
+ }
if (checkItemPlacement(info)) {
dataModel.addItem(mContext, info, false);
} else {
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 76b2ab0..6813b97 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -223,7 +223,15 @@
* Returns a FastBitmapDrawable with the icon.
*/
public FastBitmapDrawable newIcon(Context context) {
- FastBitmapDrawable drawable = bitmap.newIcon(context);
+ return newIcon(context, false);
+ }
+
+ /**
+ * Returns a FastBitmapDrawable with the icon and context theme applied
+ */
+ public FastBitmapDrawable newIcon(Context context, boolean applyTheme) {
+ FastBitmapDrawable drawable = applyTheme
+ ? bitmap.newThemedIcon(context) : bitmap.newIcon(context);
drawable.setIsDisabled(isDisabled());
return drawable;
}
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 88db430..5255490 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -30,7 +30,6 @@
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@@ -40,6 +39,7 @@
import com.android.launcher3.SessionCommitReceiver;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.IntArray;
@@ -218,7 +218,7 @@
if (FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
&& SessionCommitReceiver.isEnabled(mAppContext)
&& verifySessionInfo(sessionInfo)) {
- Log.d(LOG, "Adding package name to install queue: "
+ FileLog.d(LOG, "Adding package name to install queue: "
+ sessionInfo.getAppPackageName());
ItemInstallQueue.INSTANCE.get(mAppContext)
@@ -241,7 +241,7 @@
if (sessionInfo != null) {
Bitmap appIcon = sessionInfo.getAppIcon();
- Log.d(LOG, String.format(
+ FileLog.d(LOG, String.format(
"Verifying session info. Valid: %b, Session verified: %b, Install reason valid:"
+ " %b, App icon: %s, App label: %s, Promise icon added: %b, "
+ "App installed: %b.",
@@ -254,7 +254,7 @@
new PackageManagerHelper(mAppContext).isAppInstalled(
sessionInfo.getAppPackageName(), getUserHandle(sessionInfo))));
} else {
- Log.d(LOG, "Verifying session info failed: session info null.");
+ FileLog.d(LOG, "Verifying session info failed: session info null.");
}
return validSessionInfo;
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 48c5d0a..73ac8f2 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -16,16 +16,16 @@
package com.android.launcher3.popup;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE;
+import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
-import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
@@ -43,6 +43,7 @@
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
+import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
@@ -52,13 +53,10 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
-import com.android.launcher3.anim.RevealOutlineAnimation;
-import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.statemanager.StatefulActivity;
@@ -78,11 +76,21 @@
public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
extends AbstractFloatingView {
+ // Duration values (ms) for popup open and close animations.
+ private static final int OPEN_DURATION = 276;
+ private static final int OPEN_FADE_START_DELAY = 0;
+ private static final int OPEN_FADE_DURATION = 38;
+ private static final int OPEN_CHILD_FADE_START_DELAY = 38;
+ private static final int OPEN_CHILD_FADE_DURATION = 76;
+
+ private static final int CLOSE_DURATION = 200;
+ private static final int CLOSE_FADE_START_DELAY = 140;
+ private static final int CLOSE_FADE_DURATION = 50;
+ private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
+ private static final int CLOSE_CHILD_FADE_DURATION = 140;
+
// +1 for system shortcut view
private static final int MAX_NUM_CHILDREN = MAX_SHORTCUTS + 1;
- // Index used to get background color when using local wallpaper color extraction,
- private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
- private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_800;
private final Rect mTempRect = new Rect();
@@ -104,10 +112,8 @@
protected boolean mIsAboveIcon;
private int mGravity;
- protected Animator mOpenCloseAnimator;
+ protected AnimatorSet mOpenCloseAnimator;
protected boolean mDeferContainerRemoval;
- private final Rect mStartRect = new Rect();
- private final Rect mEndRect = new Rect();
private final GradientDrawable mRoundedTop;
private final GradientDrawable mRoundedBottom;
@@ -120,7 +126,6 @@
private final int[] mColors;
private final HashMap<String, View> mViewForRect = new HashMap<>();
- private final int mColorExtractionIndex;
@Nullable private LocalColorExtractor mColorExtractor;
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -129,9 +134,6 @@
mOutlineRadius = Themes.getDialogCornerRadius(context);
mLauncher = BaseDraggingActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
- mColorExtractionIndex = Utilities.isDarkTheme(context)
- ? DARK_COLOR_EXTRACTION_INDEX
- : LIGHT_COLOR_EXTRACTION_INDEX;
setClipToOutline(true);
setOutlineProvider(new ViewOutlineProvider() {
@Override
@@ -177,7 +179,7 @@
(int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor);
}
- if (Utilities.ATLEAST_S) {
+ if (supportsColorExtraction()) {
setupColorExtraction();
}
}
@@ -558,48 +560,13 @@
return getChildCount() > 0 ? getChildAt(0) : this;
}
- private int getArrowDuration() {
- return shouldAddArrow()
- ? getResources().getInteger(R.integer.config_popupArrowOpenCloseDuration)
- : 0;
- }
-
private void animateOpen() {
setVisibility(View.VISIBLE);
- final AnimatorSet openAnim = new AnimatorSet();
- final Resources res = getResources();
- final long revealDuration = (long) res.getInteger(R.integer.config_popupOpenCloseDuration);
- final long arrowDuration = getArrowDuration();
- final TimeInterpolator revealInterpolator = ACCEL_DEACCEL;
-
- // Rectangular reveal.
- mEndRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
- final ValueAnimator revealAnim = createOpenCloseOutlineProvider()
- .createRevealAnimator(this, false);
- revealAnim.setDuration(revealDuration);
- revealAnim.setInterpolator(revealInterpolator);
- // Clip the popup to the initial outline while the notification dot and arrow animate.
- revealAnim.start();
- revealAnim.pause();
-
- ValueAnimator fadeIn = ValueAnimator.ofFloat(0, 1);
- fadeIn.setDuration(revealDuration + arrowDuration);
- fadeIn.setInterpolator(revealInterpolator);
- fadeIn.addUpdateListener(anim -> {
- float alpha = (float) anim.getAnimatedValue();
- mArrow.setAlpha(alpha);
- setAlpha(revealAnim.isStarted() ? alpha : 0);
- });
- openAnim.play(fadeIn);
-
- // Animate the arrow.
- mArrow.setScaleX(0);
- mArrow.setScaleY(0);
- Animator arrowScale = ObjectAnimator.ofFloat(mArrow, LauncherAnimUtils.SCALE_PROPERTY, 1)
- .setDuration(arrowDuration);
-
- openAnim.addListener(new AnimatorListenerAdapter() {
+ mOpenCloseAnimator = getOpenCloseAnimator(true, OPEN_DURATION, OPEN_FADE_START_DELAY,
+ OPEN_FADE_DURATION, OPEN_CHILD_FADE_START_DELAY, OPEN_CHILD_FADE_DURATION,
+ DECELERATED_EASE);
+ mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
setAlpha(1f);
@@ -607,56 +574,68 @@
mOpenCloseAnimator = null;
}
});
-
- mOpenCloseAnimator = openAnim;
- openAnim.playSequentially(arrowScale, revealAnim);
- openAnim.start();
+ mOpenCloseAnimator.start();
}
+ private AnimatorSet getOpenCloseAnimator(boolean isOpening, int totalDuration,
+ int fadeStartDelay, int fadeDuration, int childFadeStartDelay,
+ int childFadeDuration, Interpolator interpolator) {
+ final AnimatorSet openAnim = new AnimatorSet();
+ float[] alphaValues = isOpening ? new float[] {0, 1} : new float[] {1, 0};
+ float[] scaleValues = isOpening ? new float[] {0.5f, 1} : new float[] {1, 0.5f};
+
+ ValueAnimator fade = ValueAnimator.ofFloat(alphaValues);
+ fade.setStartDelay(fadeStartDelay);
+ fade.setDuration(fadeDuration);
+ fade.setInterpolator(LINEAR);
+ fade.addUpdateListener(anim -> {
+ float alpha = (float) anim.getAnimatedValue();
+ mArrow.setAlpha(alpha);
+ setAlpha(alpha);
+ });
+ openAnim.play(fade);
+
+ setPivotX(mIsLeftAligned ? 0 : getMeasuredWidth());
+ setPivotY(mIsAboveIcon ? getMeasuredHeight() : 0);
+ Animator scale = ObjectAnimator.ofFloat(this, View.SCALE_Y, scaleValues);
+ scale.setDuration(totalDuration);
+ scale.setInterpolator(interpolator);
+ openAnim.play(scale);
+
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ View view = getChildAt(i);
+ if (view.getVisibility() == VISIBLE && view instanceof ViewGroup) {
+ for (int j = ((ViewGroup) view).getChildCount() - 1; j >= 0; --j) {
+ View childView = ((ViewGroup) view).getChildAt(j);
+
+ childView.setAlpha(alphaValues[0]);
+ ValueAnimator childFade = ObjectAnimator.ofFloat(childView, ALPHA, alphaValues);
+ childFade.setStartDelay(childFadeStartDelay);
+ childFade.setDuration(childFadeDuration);
+ childFade.setInterpolator(LINEAR);
+
+ openAnim.play(childFade);
+ }
+ }
+ }
+ return openAnim;
+ }
+
+
protected void animateClose() {
if (!mIsOpen) {
return;
}
- if (getOutlineProvider() instanceof RevealOutlineAnimation) {
- ((RevealOutlineAnimation) getOutlineProvider()).getOutline(mEndRect);
- } else {
- mEndRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
- }
if (mOpenCloseAnimator != null) {
mOpenCloseAnimator.cancel();
}
mIsOpen = false;
-
- final AnimatorSet closeAnim = new AnimatorSet();
- final Resources res = getResources();
- final TimeInterpolator revealInterpolator = ACCEL_DEACCEL;
- final long revealDuration = res.getInteger(R.integer.config_popupOpenCloseDuration);
- final long arrowDuration = getArrowDuration();
-
- // Hide the arrow
- Animator scaleArrow = ObjectAnimator.ofFloat(mArrow, LauncherAnimUtils.SCALE_PROPERTY, 0)
- .setDuration(arrowDuration);
-
- // Rectangular reveal (reversed).
- final ValueAnimator revealAnim = createOpenCloseOutlineProvider()
- .createRevealAnimator(this, true);
- revealAnim.setDuration(revealDuration);
- revealAnim.setInterpolator(revealInterpolator);
- closeAnim.playSequentially(revealAnim, scaleArrow);
-
- ValueAnimator fadeOut = ValueAnimator.ofFloat(getAlpha(), 0);
- fadeOut.setDuration(revealDuration + arrowDuration);
- fadeOut.setInterpolator(revealInterpolator);
- fadeOut.addUpdateListener(anim -> {
- float alpha = (float) anim.getAnimatedValue();
- mArrow.setAlpha(alpha);
- setAlpha(scaleArrow.isStarted() ? 0 : alpha);
- });
- closeAnim.play(fadeOut);
-
- onCreateCloseAnimation(closeAnim);
- closeAnim.addListener(new AnimatorListenerAdapter() {
+ mOpenCloseAnimator = getOpenCloseAnimator(false, CLOSE_DURATION, CLOSE_FADE_START_DELAY,
+ CLOSE_FADE_DURATION, CLOSE_CHILD_FADE_START_DELAY, CLOSE_CHILD_FADE_DURATION,
+ ACCELERATED_EASE);
+ onCreateCloseAnimation(mOpenCloseAnimator);
+ mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mOpenCloseAnimator = null;
@@ -667,8 +646,7 @@
}
}
});
- mOpenCloseAnimator = closeAnim;
- closeAnim.start();
+ mOpenCloseAnimator.start();
}
/**
@@ -676,16 +654,6 @@
*/
protected void onCreateCloseAnimation(AnimatorSet anim) { }
- private RoundedRectRevealOutlineProvider createOpenCloseOutlineProvider() {
- int arrowLeft = getArrowLeft();
- int arrowCenterY = mIsAboveIcon ? getMeasuredHeight() : 0;
-
- mStartRect.set(arrowLeft, arrowCenterY, arrowLeft + mArrowWidth, arrowCenterY);
-
- return new RoundedRectRevealOutlineProvider(
- mArrowPointRadius, mOutlineRadius, mStartRect, mEndRect);
- }
-
/**
* Closes the popup without animation.
*/
@@ -703,10 +671,18 @@
mViewForRect.clear();
if (mColorExtractor != null) {
mColorExtractor.removeLocations();
+ mColorExtractor.setListener(null);
}
}
/**
+ * Returns whether color extraction is supported.
+ */
+ public boolean supportsColorExtraction() {
+ return Utilities.ATLEAST_S;
+ }
+
+ /**
* Callback to be called when the popup is closed
*/
public void setOnCloseCallback(@NonNull Runnable callback) {
@@ -747,7 +723,7 @@
View view = getChildAt(i);
if (view.getVisibility() == VISIBLE) {
RectF rf = new RectF();
- getColorExtractionRect(Launcher.getLauncher(getContext()),
+ mColorExtractor.getExtractedRectForView(Launcher.getLauncher(getContext()),
workspace.getCurrentPage(), view, rf);
if (rf.isEmpty()) {
numVisibleChild++;
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index a191df4..22c3f58 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -20,7 +20,7 @@
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID;
import static android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_PROVIDER;
-import static com.android.launcher3.Utilities.ATLEAST_S;
+import static com.android.launcher3.AppWidgetResizeFrame.getWidgetSizeOptions;
import android.app.Activity;
import android.app.Fragment;
@@ -32,11 +32,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.graphics.Rect;
import android.os.Bundle;
import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.SizeF;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -45,7 +43,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
@@ -53,8 +50,6 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.FragmentWithPreview;
-import java.util.ArrayList;
-
/**
* A frame layout which contains a QSB. This internally uses fragment to bind the view, which
* allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}.
@@ -163,7 +158,7 @@
protected String mKeyWidgetId = "qsb_widget_id";
private QsbWidgetHost mQsbWidgetHost;
- private AppWidgetProviderInfo mWidgetInfo;
+ protected AppWidgetProviderInfo mWidgetInfo;
private QsbWidgetHostView mQsb;
// We need to store the orientation here, due to a bug (b/64916689) that results in widgets
@@ -297,19 +292,7 @@
protected Bundle createBindOptions() {
InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext());
-
- Bundle opts = new Bundle();
- ArrayList<SizeF> sizes = AppWidgetResizeFrame
- .getWidgetSizes(getContext(), idp.numColumns, 1);
- Rect size = AppWidgetResizeFrame.getMinMaxSizes(sizes, null /* outRect */);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, size.right);
- opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, size.bottom);
- if (ATLEAST_S) {
- opts.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizes);
- }
- return opts;
+ return getWidgetSizeOptions(getContext(), mWidgetInfo.provider, idp.numColumns, 1);
}
protected View getDefaultView(ViewGroup container, boolean showSetupIcon) {
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index f5e74b7..5999091 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -87,8 +87,8 @@
if (mDragLayer != null) {
return;
}
- InvariantDeviceProfile currentDisplayIdp =
- new InvariantDeviceProfile(this, getWindow().getDecorView().getDisplay());
+ InvariantDeviceProfile currentDisplayIdp = new InvariantDeviceProfile(
+ this, getWindow().getDecorView().getDisplay());
// Disable transpose layout and use multi-window mode so that the icons are scaled properly
mDeviceProfile = currentDisplayIdp.getDeviceProfile(this)
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index 40630d3..f78f6dd 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -29,7 +29,6 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.model.data.ItemInfo;
@@ -109,8 +108,6 @@
setMeasuredDimension(width, height);
DeviceProfile grid = mActivity.getDeviceProfile();
- InvariantDeviceProfile idp = grid.inv;
-
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
@@ -118,10 +115,10 @@
int padding = 2 * (grid.desiredWorkspaceLeftRightMarginPx
+ grid.cellLayoutPaddingLeftRightPx);
- int maxWidth = grid.allAppsCellWidthPx * idp.numAllAppsColumns + padding;
+ int maxWidth = grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + padding;
int appsWidth = Math.min(width, maxWidth);
- int maxHeight = grid.allAppsCellHeightPx * idp.numAllAppsColumns + padding;
+ int maxHeight = grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + padding;
int appsHeight = Math.min(height, maxHeight);
mAppsView.measure(
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 216510b..883ff75 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -19,7 +19,6 @@
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
-import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
import android.content.SharedPreferences;
import android.os.Bundle;
@@ -38,6 +37,8 @@
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -169,12 +170,14 @@
return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;
case ALLOW_ROTATION_PREFERENCE_KEY:
- if (getResources().getBoolean(R.bool.allow_rotation)) {
+ DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get(
+ getContext()).getDeviceProfile(getContext());
+ if (deviceProfile.allowRotation) {
// Launcher supports rotation by default. No need to show this setting.
return false;
}
// Initialize the UI once
- preference.setDefaultValue(getAllowRotationDefaultValue());
+ preference.setDefaultValue(false);
return true;
case FLAGS_PREFERENCE_KEY:
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 14ef2dc..03b6853 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -129,14 +129,14 @@
}
/**
- * @see #goToState(STATE_TYPE, boolean, Runnable)
+ * @see #goToState(STATE_TYPE, boolean, AnimatorListener)
*/
public void goToState(STATE_TYPE state) {
goToState(state, shouldAnimateStateChange());
}
/**
- * @see #goToState(STATE_TYPE, boolean, Runnable)
+ * @see #goToState(STATE_TYPE, boolean, AnimatorListener)
*/
public void goToState(STATE_TYPE state, boolean animated) {
goToState(state, animated, 0, null);
@@ -149,15 +149,15 @@
* true otherwise
* @paras onCompleteRunnable any action to perform at the end of the transition, of null.
*/
- public void goToState(STATE_TYPE state, boolean animated, Runnable onCompleteRunnable) {
- goToState(state, animated, 0, onCompleteRunnable);
+ public void goToState(STATE_TYPE state, boolean animated, AnimatorListener listener) {
+ goToState(state, animated, 0, listener);
}
/**
* Changes the Launcher state to the provided state after the given delay.
*/
- public void goToState(STATE_TYPE state, long delay, Runnable onCompleteRunnable) {
- goToState(state, true, delay, onCompleteRunnable);
+ public void goToState(STATE_TYPE state, long delay, AnimatorListener listener) {
+ goToState(state, true, delay, listener);
}
/**
@@ -187,21 +187,20 @@
}
}
- private void goToState(STATE_TYPE state, boolean animated, long delay,
- final Runnable onCompleteRunnable) {
+ private void goToState(
+ STATE_TYPE state, boolean animated, long delay, AnimatorListener listener) {
animated &= areAnimatorsEnabled();
if (mActivity.isInState(state)) {
if (mConfig.currentAnimation == null) {
// Run any queued runnable
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
+ if (listener != null) {
+ listener.onAnimationEnd(null);
}
return;
} else if (!mConfig.userControlled && animated && mConfig.targetState == state) {
// We are running the same animation as requested
- if (onCompleteRunnable != null) {
- mConfig.currentAnimation.addListener(
- AnimationSuccessListener.forRunnable(onCompleteRunnable));
+ if (listener != null) {
+ mConfig.currentAnimation.addListener(listener);
}
return;
}
@@ -221,8 +220,8 @@
onStateTransitionEnd(state);
// Run any queued runnable
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
+ if (listener != null) {
+ listener.onAnimationEnd(null);
}
return;
}
@@ -233,16 +232,16 @@
int startChangeId = mConfig.changeId;
mUiHandler.postDelayed(() -> {
if (mConfig.changeId == startChangeId) {
- goToStateAnimated(state, fromState, onCompleteRunnable);
+ goToStateAnimated(state, fromState, listener);
}
}, delay);
} else {
- goToStateAnimated(state, fromState, onCompleteRunnable);
+ goToStateAnimated(state, fromState, listener);
}
}
private void goToStateAnimated(STATE_TYPE state, STATE_TYPE fromState,
- Runnable onCompleteRunnable) {
+ AnimatorListener listener) {
// Since state mBaseState can be reached from multiple states, just assume that the
// transition plays in reverse and use the same duration as previous state.
mConfig.duration = state == mBaseState
@@ -250,8 +249,8 @@
: state.getTransitionDuration(mActivity);
prepareForAtomicAnimation(fromState, state, mConfig);
AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim();
- if (onCompleteRunnable != null) {
- animation.addListener(AnimationSuccessListener.forRunnable(onCompleteRunnable));
+ if (listener != null) {
+ animation.addListener(listener);
}
mUiHandler.post(new StartAnimRunnable(animation));
}
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 2da06e9..5832711 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -18,43 +18,34 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.res.Resources;
-import com.android.launcher3.R;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.UiThreadHelper;
/**
* Utility class to manage launcher rotation
*/
-public class RotationHelper implements OnSharedPreferenceChangeListener {
+public class RotationHelper implements OnSharedPreferenceChangeListener,
+ DeviceProfile.OnDeviceProfileChangeListener {
private static final String TAG = "RotationHelper";
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
- public static boolean getAllowRotationDefaultValue() {
- // If the device's pixel density was scaled (usually via settings for A11y), use the
- // original dimensions to determine if rotation is allowed of not.
- Resources res = Resources.getSystem();
- int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
- * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
- return originalSmallestWidth >= 600;
- }
-
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
- private Activity mActivity;
- private final SharedPreferences mSharedPrefs;
+ private BaseActivity mActivity;
+ private SharedPreferences mSharedPrefs = null;
private boolean mIgnoreAutoRotateSettings;
+ private boolean mForceAllowRotationForTesting;
private boolean mHomeRotationEnabled;
/**
@@ -79,18 +70,25 @@
// Initialize mLastActivityFlags to a value not used by SCREEN_ORIENTATION flags
private int mLastActivityFlags = -999;
- public RotationHelper(Activity activity) {
+ public RotationHelper(BaseActivity activity) {
mActivity = activity;
+ }
+ private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings) {
// On large devices we do not handle auto-rotate differently.
- mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation);
+ mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
if (!mIgnoreAutoRotateSettings) {
- mSharedPrefs = Utilities.getPrefs(mActivity);
- mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ if (mSharedPrefs == null) {
+ mSharedPrefs = Utilities.getPrefs(mActivity);
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ }
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- getAllowRotationDefaultValue());
+ mActivity.getDeviceProfile().allowRotation);
} else {
- mSharedPrefs = null;
+ if (mSharedPrefs != null) {
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ mSharedPrefs = null;
+ }
}
}
@@ -99,12 +97,21 @@
if (mDestroyed) return;
boolean wasRotationEnabled = mHomeRotationEnabled;
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- getAllowRotationDefaultValue());
+ mActivity.getDeviceProfile().allowRotation);
if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange();
}
}
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ boolean ignoreAutoRotateSettings = dp.allowRotation;
+ if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
+ setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
+ notifyChange();
+ }
+ }
+
public void setStateHandlerRequest(int request) {
if (mStateHandlerRequest != request) {
mStateHandlerRequest = request;
@@ -128,14 +135,15 @@
// Used by tests only.
public void forceAllowRotationForTesting(boolean allowRotation) {
- mIgnoreAutoRotateSettings =
- allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation);
+ mForceAllowRotationForTesting = allowRotation;
notifyChange();
}
public void initialize() {
if (!mInitialized) {
mInitialized = true;
+ setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().allowRotation);
+ mActivity.addOnDeviceProfileChangeListener(this);
notifyChange();
}
}
@@ -143,6 +151,7 @@
public void destroy() {
if (!mDestroyed) {
mDestroyed = true;
+ mActivity.removeOnDeviceProfileChangeListener(this);
mActivity = null;
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
@@ -165,7 +174,7 @@
} else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED;
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
- || mHomeRotationEnabled) {
+ || mHomeRotationEnabled || mForceAllowRotationForTesting) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
} else {
// If auto rotation is off, allow rotation on the activity, in case the user is using
@@ -191,9 +200,10 @@
@Override
public String toString() {
- return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d,"
- + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mHomeRotationEnabled=%b]",
+ return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d, "
+ + "mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, "
+ + "mHomeRotationEnabled=%b, mForceAllowRotationForTesting=%b]",
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
- mIgnoreAutoRotateSettings, mHomeRotationEnabled);
+ mIgnoreAutoRotateSettings, mHomeRotationEnabled, mForceAllowRotationForTesting);
}
}
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 2f26b4f..bd6f7d3 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -58,8 +58,7 @@
ANIM_OVERVIEW_TRANSLATE_Y,
ANIM_OVERVIEW_FADE,
ANIM_ALL_APPS_FADE,
- ANIM_WORKSPACE_SCRIM_FADE,
- ANIM_ALL_APPS_HEADER_FADE,
+ ANIM_SCRIM_FADE,
ANIM_OVERVIEW_MODAL,
ANIM_DEPTH,
ANIM_OVERVIEW_ACTIONS_FADE,
@@ -77,13 +76,12 @@
public static final int ANIM_OVERVIEW_TRANSLATE_Y = 8;
public static final int ANIM_OVERVIEW_FADE = 9;
public static final int ANIM_ALL_APPS_FADE = 10;
- public static final int ANIM_WORKSPACE_SCRIM_FADE = 11;
- public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
- public static final int ANIM_OVERVIEW_MODAL = 13;
- public static final int ANIM_DEPTH = 14;
- public static final int ANIM_OVERVIEW_ACTIONS_FADE = 15;
+ public static final int ANIM_SCRIM_FADE = 11;
+ public static final int ANIM_OVERVIEW_MODAL = 12;
+ public static final int ANIM_DEPTH = 13;
+ public static final int ANIM_OVERVIEW_ACTIONS_FADE = 14;
- private static final int ANIM_TYPES_COUNT = 16;
+ private static final int ANIM_TYPES_COUNT = 15;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 3296ea5..4012e89 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -109,10 +109,6 @@
public static final String REQUEST_MOCK_SENSOR_ROTATION = "mock-sensor-rotation";
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
- public static final String LAUNCHER_NOT_TRANSPOSED = "b/185820525";
- public static final String NO_SWIPE_TO_HOME = "b/158017601";
public static final String WORK_PROFILE_REMOVED = "b/159671700";
- public static final String TIS_NO_EVENTS = "b/180915942";
- public static final String GET_RECENTS_FAILED = "b/177472267";
- public static final String TWO_BUTTON_NORMAL_NOT_OVERVIEW = "b/177316094";
+ public static final String FALLBACK_ACTIVITY_NO_SET = "b/181019015";
}
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 2fd5efc..44e55e1 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -160,6 +160,19 @@
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ // Don't use device profile here because we know we're in fake landscape, only split option
+ // available is top/left
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ // Top (visually left) side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollY();
}
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 6c2f17e..6811438 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -42,6 +42,10 @@
*/
public interface PagedOrientationHandler {
+ int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0;
+ int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1;
+ int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2;
+
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
@@ -71,6 +75,13 @@
int getSecondaryDimension(View view);
FloatProperty<View> getPrimaryViewTranslate();
FloatProperty<View> getSecondaryViewTranslate();
+
+ /**
+ * @param splitPosition The position where the view to be split will go
+ * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
+ * dismissal should happen
+ */
+ int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
int getPrimaryScroll(View view);
float getPrimaryScale(View view);
int getChildStart(View view);
@@ -94,7 +105,7 @@
int getPrimaryValue(int x, int y);
int getSecondaryValue(int x, int y);
- float getPrimaryValue(float x, float y);
+ float getPrimaryValue(float x, float y);
float getSecondaryValue(float x, float y);
boolean isLayoutNaturalToLauncher();
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index f6a6448..d3d77fd 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -156,6 +156,25 @@
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ if (dp.isLandscape) {
+ // Left side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ } else {
+ // Top side
+ return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
+ }
+ } else if (splitPosition.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // We don't have a bottom option, so should be right
+ return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollX();
}
@@ -277,7 +296,7 @@
} else {
// Phone Portrait, LargeScreen Landscape/Portrait
viewGroup.setOrientation(LinearLayout.HORIZONTAL);
- lp.width = LinearLayout.LayoutParams.WRAP_CONTENT;
+ lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
}
lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
diff --git a/src/com/android/launcher3/util/ColorExtractionUtils.java b/src/com/android/launcher3/util/ColorExtractionUtils.java
deleted file mode 100644
index b377ded..0000000
--- a/src/com/android/launcher3/util/ColorExtractionUtils.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util;
-
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.view.View;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.Utilities;
-
-/**
- * Utility class used to map launcher views to wallpaper rect.
- */
-public class ColorExtractionUtils {
-
- public static final String TAG = "ColorExtractionUtils";
-
- private static final Rect sTempRect = new Rect();
- private static final RectF sTempRectF = new RectF();
-
- /**
- * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
- *
- * @param launcher Launcher class class.
- * @param pageId The page the workspace item is on.
- * @param v The view.
- * @param colorExtractionRectOut The location rect, but converted to a format expected by the
- * wallpaper local color extractor.
- */
- public static void getColorExtractionRect(Launcher launcher, int pageId, View v,
- RectF colorExtractionRectOut) {
- Rect viewRect = sTempRect;
- viewRect.set(0, 0, v.getWidth(), v.getHeight());
- Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, viewRect, false,
- sTempRectF);
- Utilities.setRect(sTempRectF, viewRect);
- getColorExtractionRect(launcher, pageId, viewRect, colorExtractionRectOut);
- }
-
- /**
- * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
- * local color extractor.
- *
- * @param launcher Launcher class.
- * @param pageId The page the workspace item is on.
- * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
- * @param colorExtractionRectOut The location rect, but converted to a format expected by the
- * wallpaper local color extractor.
- */
- public static void getColorExtractionRect(Launcher launcher, int pageId, Rect rectInDragLayer,
- RectF colorExtractionRectOut) {
- // If the view hasn't been measured and laid out, we cannot do this.
- if (rectInDragLayer.isEmpty()) {
- colorExtractionRectOut.setEmpty();
- return;
- }
-
- Resources res = launcher.getResources();
- DeviceProfile dp = launcher.getDeviceProfile().inv.getDeviceProfile(launcher);
- float screenWidth = dp.widthPx;
- float screenHeight = dp.heightPx;
- int numScreens = launcher.getWorkspace().getNumPagesForWallpaperParallax();
- pageId = Utilities.isRtl(res) ? numScreens - pageId - 1 : pageId;
- float relativeScreenWidth = 1f / numScreens;
-
- int[] dragLayerBounds = new int[2];
- launcher.getDragLayer().getLocationOnScreen(dragLayerBounds);
- // Translate from drag layer coordinates to screen coordinates.
- int screenLeft = rectInDragLayer.left + dragLayerBounds[0];
- int screenTop = rectInDragLayer.top + dragLayerBounds[1];
- int screenRight = rectInDragLayer.right + dragLayerBounds[0];
- int screenBottom = rectInDragLayer.bottom + dragLayerBounds[1];
-
- // This is the position of the view relative to the wallpaper, as expected by the
- // local color extraction of the WallpaperManager.
- // The coordinate system is such that, on the horizontal axis, each screen has a
- // distinct range on the [0,1] segment. So if there are 3 screens, they will have the
- // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be
- // the position of the view relative to the screen. For the vertical axis, this is
- // simply the location of the view relative to the screen.
- // Translate from drag layer coordinates to screen coordinates
- colorExtractionRectOut.left = (screenLeft / screenWidth + pageId) * relativeScreenWidth;
- colorExtractionRectOut.right = (screenRight / screenWidth + pageId) * relativeScreenWidth;
- colorExtractionRectOut.top = screenTop / screenHeight;
- colorExtractionRectOut.bottom = screenBottom / screenHeight;
-
- if (colorExtractionRectOut.left < 0
- || colorExtractionRectOut.right > 1
- || colorExtractionRectOut.top < 0
- || colorExtractionRectOut.bottom > 1) {
- colorExtractionRectOut.setEmpty();
- }
- }
-}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 75c089e..e2c0a32 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -18,8 +18,10 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@@ -32,16 +34,22 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
+import android.util.ArraySet;
import android.util.Log;
import android.view.Display;
+import android.view.WindowMetrics;
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.ApiWrapper;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
/**
* Utility class to cache properties of default display to avoid a system RPC on every call.
@@ -54,13 +62,14 @@
public static final MainThreadInitializedObject<DisplayController> INSTANCE =
new MainThreadInitializedObject<>(DisplayController::new);
- public static final int CHANGE_SIZE = 1 << 0;
+ public static final int CHANGE_ACTIVE_SCREEN = 1 << 0;
public static final int CHANGE_ROTATION = 1 << 1;
public static final int CHANGE_FRAME_DELAY = 1 << 2;
public static final int CHANGE_DENSITY = 1 << 3;
+ public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 4;
- public static final int CHANGE_ALL = CHANGE_SIZE | CHANGE_ROTATION
- | CHANGE_FRAME_DELAY | CHANGE_DENSITY;
+ public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
+ | CHANGE_FRAME_DELAY | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
private final Context mContext;
private final DisplayManager mDM;
@@ -87,7 +96,17 @@
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
- mInfo = new Info(getContext(display), display);
+ // Create a single holder for all internal displays. External display holders created
+ // lazily.
+ Set<PortraitSize> extraInternalDisplays = new ArraySet<>();
+ for (Display d : mDM.getDisplays()) {
+ if (ApiWrapper.isInternalDisplay(display) && d.getDisplayId() != DEFAULT_DISPLAY) {
+ Point size = new Point();
+ d.getRealSize(size);
+ extraInternalDisplays.add(new PortraitSize(size.x, size.y));
+ }
+ }
+ mInfo = new Info(getDisplayInfoContext(display), display, extraInternalDisplays);
mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
}
@@ -139,7 +158,7 @@
*/
private void onConfigChanged(Intent intent) {
Configuration config = mContext.getResources().getConfiguration();
- if (config.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
+ if (mInfo.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
Log.d(TAG, "Configuration changed, notifying listeners");
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (display != null) {
@@ -157,8 +176,7 @@
|| config.fontScale != mInfo.fontScale
|| display.getRotation() != mInfo.rotation
|| !mInfo.mScreenSizeDp.equals(
- Math.min(config.screenHeightDp, config.screenWidthDp),
- Math.max(config.screenHeightDp, config.screenWidthDp))) {
+ new PortraitSize(config.screenHeightDp, config.screenWidthDp))) {
handleInfoChange(display);
}
}
@@ -178,18 +196,21 @@
return mInfo;
}
- private Context getContext(Display display) {
+ private Context getDisplayInfoContext(Display display) {
return Utilities.ATLEAST_S ? mWindowContext : mContext.createDisplayContext(display);
}
@AnyThread
private void handleInfoChange(Display display) {
Info oldInfo = mInfo;
- Context context = getContext(display);
- Info newInfo = new Info(context, display);
+ Set<PortraitSize> extraDisplaysSizes = oldInfo.mAllSizes.size() > 1
+ ? oldInfo.mAllSizes : Collections.emptySet();
+
+ Context displayContext = getDisplayInfoContext(display);
+ Info newInfo = new Info(displayContext, display, extraDisplaysSizes);
int change = 0;
- if (newInfo.hasDifferentSize(oldInfo)) {
- change |= CHANGE_SIZE;
+ if (!newInfo.mScreenSizeDp.equals(oldInfo.mScreenSizeDp)) {
+ change |= CHANGE_ACTIVE_SCREEN;
}
if (newInfo.rotation != oldInfo.rotation) {
change |= CHANGE_ROTATION;
@@ -200,11 +221,14 @@
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
change |= CHANGE_DENSITY;
}
+ if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)) {
+ change |= CHANGE_SUPPORTED_BOUNDS;
+ }
if (change != 0) {
mInfo = newInfo;
final int flags = change;
- MAIN_EXECUTOR.execute(() -> notifyChange(context, flags));
+ MAIN_EXECUTOR.execute(() -> notifyChange(displayContext, flags));
}
}
@@ -224,13 +248,18 @@
public final float fontScale;
public final int densityDpi;
- private final Point mScreenSizeDp;
+ private final PortraitSize mScreenSizeDp;
+ private final Set<PortraitSize> mAllSizes;
- public final Point realSize;
- public final Point smallestSize;
- public final Point largestSize;
+ public final Point currentSize;
+
+ public final Set<WindowBounds> supportedBounds = new ArraySet<>();
public Info(Context context, Display display) {
+ this(context, display, Collections.emptySet());
+ }
+
+ private Info(Context context, Display display, Set<PortraitSize> extraDisplaysSizes) {
id = display.getDisplayId();
rotation = display.getRotation();
@@ -238,35 +267,67 @@
Configuration config = context.getResources().getConfiguration();
fontScale = config.fontScale;
densityDpi = config.densityDpi;
- mScreenSizeDp = new Point(
- Math.min(config.screenHeightDp, config.screenWidthDp),
- Math.max(config.screenHeightDp, config.screenWidthDp));
+ mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
singleFrameMs = getSingleFrameMs(display);
+ currentSize = new Point();
- realSize = new Point();
- smallestSize = new Point();
- largestSize = new Point();
+ display.getRealSize(currentSize);
- display.getRealSize(realSize);
- display.getCurrentSizeRange(smallestSize, largestSize);
+ if (extraDisplaysSizes.isEmpty() || !Utilities.ATLEAST_S) {
+ Point smallestSize = new Point();
+ Point largestSize = new Point();
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ int portraitWidth = Math.min(currentSize.x, currentSize.y);
+ int portraitHeight = Math.max(currentSize.x, currentSize.y);
+
+ supportedBounds.add(new WindowBounds(portraitWidth, portraitHeight,
+ smallestSize.x, largestSize.y));
+ supportedBounds.add(new WindowBounds(portraitHeight, portraitWidth,
+ largestSize.x, smallestSize.y));
+ mAllSizes = Collections.singleton(new PortraitSize(currentSize.x, currentSize.y));
+ } else {
+ mAllSizes = new ArraySet<>(extraDisplaysSizes);
+ mAllSizes.add(new PortraitSize(currentSize.x, currentSize.y));
+ Set<WindowMetrics> metrics = WindowManagerCompat.getDisplayProfiles(
+ context, mAllSizes, densityDpi,
+ ApiWrapper.TASKBAR_DRAWN_IN_PROCESS);
+ metrics.forEach(wm -> supportedBounds.add(WindowBounds.fromWindowMetrics(wm)));
+ }
}
- private boolean hasDifferentSize(Info info) {
- if (!realSize.equals(info.realSize)
- && !realSize.equals(info.realSize.y, info.realSize.x)) {
- Log.d(TAG, String.format("Display size changed from %s to %s",
- info.realSize, realSize));
- return true;
- }
+ /**
+ * Returns true if the bounds represent a tablet
+ */
+ public boolean isTablet(WindowBounds bounds) {
+ return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
+ densityDpi) >= MIN_TABLET_WIDTH;
+ }
+ }
- if (!smallestSize.equals(info.smallestSize) || !largestSize.equals(info.largestSize)) {
- Log.d(TAG, String.format("Available size changed from [%s, %s] to [%s, %s]",
- smallestSize, largestSize, info.smallestSize, info.largestSize));
- return true;
- }
+ /**
+ * Utility class to hold a size information in an orientation independent way
+ */
+ public static class PortraitSize {
+ public final int width, height;
- return false;
+ public PortraitSize(int w, int h) {
+ width = Math.min(w, h);
+ height = Math.max(w, h);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PortraitSize that = (PortraitSize) o;
+ return width == that.width && height == that.height;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(width, height);
}
}
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 898ac25..06cac08 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -19,6 +19,7 @@
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_TEXT;
import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME;
+import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.res.TypedArray;
@@ -40,9 +41,14 @@
public class Themes {
public static int getActivityThemeRes(Context context) {
- int colorHints = Utilities.ATLEAST_P ? context.getSystemService(WallpaperManager.class)
- .getWallpaperColors(WallpaperManager.FLAG_SYSTEM).getColorHints()
- : 0;
+ final int colorHints;
+ if (Utilities.ATLEAST_P) {
+ WallpaperColors colors = context.getSystemService(WallpaperManager.class)
+ .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+ colorHints = colors == null ? 0 : colors.getColorHints();
+ } else {
+ colorHints = 0;
+ }
return getActivityThemeRes(context, colorHints);
}
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index be14e01..523f3d6 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -23,11 +23,12 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.view.View;
import android.view.WindowInsets;
import android.view.inputmethod.InputMethodManager;
-import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
+import com.android.launcher3.views.ActivityContext;
/**
* Utility class for offloading some class from UI thread
@@ -43,15 +44,21 @@
private static final int MSG_RUN_COMMAND = 3;
@SuppressLint("NewApi")
- public static void hideKeyboardAsync(Launcher launcher, IBinder token) {
+ public static void hideKeyboardAsync(ActivityContext activityContext, IBinder token) {
+ View root = activityContext.getDragLayer();
if (Utilities.ATLEAST_R) {
- WindowInsets rootInsets = launcher.getRootView().getRootWindowInsets();
+ WindowInsets rootInsets = root.getRootWindowInsets();
boolean isImeShown = rootInsets != null && rootInsets.isVisible(
WindowInsets.Type.ime());
- if (!isImeShown) return;
+ if (isImeShown) {
+ // this call is already asynchronous
+ root.getWindowInsetsController().hide(WindowInsets.Type.ime());
+ }
+ return;
}
- Message.obtain(HANDLER.get(launcher), MSG_HIDE_KEYBOARD, token).sendToTarget();
+ Message.obtain(HANDLER.get(root.getContext()),
+ MSG_HIDE_KEYBOARD, token).sendToTarget();
}
public static void setOrientationAsync(Activity activity, int orientation) {
diff --git a/src/com/android/launcher3/util/WindowBounds.java b/src/com/android/launcher3/util/WindowBounds.java
index 3c2fb62..c92770e 100644
--- a/src/com/android/launcher3/util/WindowBounds.java
+++ b/src/com/android/launcher3/util/WindowBounds.java
@@ -15,11 +15,16 @@
*/
package com.android.launcher3.util;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
+import android.view.WindowInsets.Type;
+import android.view.WindowMetrics;
import androidx.annotation.Nullable;
+import java.util.Objects;
+
/**
* Utility class to hold information about window position and layout
*/
@@ -36,6 +41,18 @@
bounds.height() - insets.top - insets.bottom);
}
+ public WindowBounds(int width, int height, int availableWidth, int availableHeight) {
+ this.bounds = new Rect(0, 0, width, height);
+ this.availableSize = new Point(availableWidth, availableHeight);
+ // We don't care about insets in this case
+ this.insets = new Rect(0, 0, width - availableWidth, height - availableHeight);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(bounds, insets);
+ }
+
@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof WindowBounds)) {
@@ -44,4 +61,30 @@
WindowBounds other = (WindowBounds) obj;
return other.bounds.equals(bounds) && other.insets.equals(insets);
}
+
+ @Override
+ public String toString() {
+ return "WindowBounds{"
+ + "bounds=" + bounds
+ + ", insets=" + insets
+ + ", availableSize=" + availableSize
+ + '}';
+ }
+
+ /**
+ * Returns true if the device is in landscape orientation
+ */
+ public final boolean isLandscape() {
+ return availableSize.x > availableSize.y;
+ }
+
+ /**
+ * Returns the bounds corresponding to the provided WindowMetrics
+ */
+ @SuppressWarnings("NewApi")
+ public static WindowBounds fromWindowMetrics(WindowMetrics wm) {
+ Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
+ return new WindowBounds(wm.getBounds(),
+ new Rect(insets.left, insets.top, insets.right, insets.bottom));
+ }
}
diff --git a/src/com/android/launcher3/util/WindowManagerCompat.java b/src/com/android/launcher3/util/WindowManagerCompat.java
new file mode 100644
index 0000000..38a63de
--- /dev/null
+++ b/src/com/android/launcher3/util/WindowManagerCompat.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
+import static com.android.launcher3.Utilities.dpiFromPx;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.util.DisplayController.PortraitSize;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Utility class to simulate window manager APIs until proper APIs are available
+ */
+@TargetApi(Build.VERSION_CODES.S)
+public class WindowManagerCompat {
+
+ public static final int MIN_TABLET_WIDTH = 600;
+
+ /**
+ * Returns a set of supported render sizes for a set of internal displays.
+ * This is a temporary workaround which assumes only nav-bar insets change across displays
+ * @param consumeTaskBar if true, it assumes that task bar is part of the app window
+ * and ignores any insets because of task bar.
+ */
+ public static Set<WindowMetrics> getDisplayProfiles(
+ Context windowContext, Collection<PortraitSize> allDisplaySizes,
+ int densityDpi, boolean consumeTaskBar) {
+ WindowInsets metrics = windowContext.getSystemService(WindowManager.class)
+ .getMaximumWindowMetrics().getWindowInsets();
+ boolean hasNavbar = ResourceUtils.getIntegerByName(
+ "config_navBarInteractionMode",
+ windowContext.getResources(),
+ INVALID_RESOURCE_HANDLE) != 0;
+
+ WindowInsets.Builder insetsBuilder = new WindowInsets.Builder(metrics);
+
+ Set<WindowMetrics> result = new HashSet<>();
+ for (PortraitSize size : allDisplaySizes) {
+ int swDP = (int) dpiFromPx(size.width, densityDpi);
+ boolean isTablet = swDP >= MIN_TABLET_WIDTH;
+
+ final Insets portraitNav, landscapeNav;
+ if (isTablet && !consumeTaskBar) {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, windowContext.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_size));
+ } else if (hasNavbar) {
+ portraitNav = Insets.of(0, 0, 0,
+ getSystemResource(windowContext, "navigation_bar_height", swDP));
+ landscapeNav = isTablet
+ ? Insets.of(0, 0, 0, getSystemResource(windowContext,
+ "navigation_bar_height_landscape", swDP))
+ : Insets.of(0, 0, getSystemResource(windowContext,
+ "navigation_bar_width", swDP), 0);
+ } else {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, 0);
+ }
+
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.width, size.height),
+ insetsBuilder.setInsets(Type.navigationBars(), portraitNav).build()));
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.height, size.width),
+ insetsBuilder.setInsets(Type.navigationBars(), landscapeNav).build()));
+ }
+ return result;
+ }
+
+ private static int getSystemResource(Context context, String key, int swDp) {
+ int resourceId = context.getResources().getIdentifier(key, "dimen", "android");
+ if (resourceId > 0) {
+ Configuration conf = new Configuration();
+ conf.smallestScreenWidthDp = swDp;
+ return context.createConfigurationContext(conf)
+ .getResources().getDimensionPixelSize(resourceId);
+ }
+ return 0;
+ }
+}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 71aa4ac..646b669 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -23,7 +23,9 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.dot.DotInfo;
+import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ViewCache;
/**
* An interface to be used along with a context for various activities in Launcher. This allows a
@@ -86,6 +88,17 @@
DeviceProfile getDeviceProfile();
+ default ViewCache getViewCache() {
+ return new ViewCache();
+ }
+
+ /**
+ * Controller for supporting item drag-and-drop
+ */
+ default <T extends DragController> T getDragController() {
+ return null;
+ }
+
/**
* Returns the ActivityContext associated with the given Context.
*/
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 1ddd1ba..81581fa 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -234,7 +234,7 @@
}
Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, outViewBounds,
- ignoreTransform, outRect);
+ ignoreTransform, null /** recycle */, outRect);
}
/**
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index ae34257..9d0913a 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -106,6 +106,7 @@
// prevent jumping, this offset is applied as the user scrolls.
protected int mTouchOffsetY;
protected int mThumbOffsetY;
+ protected int mRvOffsetY;
// Fast scroller popup
private TextView mPopupView;
@@ -186,14 +187,18 @@
public void setThumbOffsetY(int y) {
if (mThumbOffsetY == y) {
+ int rvCurrentOffsetY = mRv.getCurrentScrollY();
+ if (mRvOffsetY != rvCurrentOffsetY) {
+ mRvOffsetY = mRv.getCurrentScrollY();
+ notifyScrollChanged();
+ }
return;
}
updatePopupY(y);
mThumbOffsetY = y;
invalidate();
- if (mOnFastScrollChangeListener != null) {
- mOnFastScrollChangeListener.onThumbOffsetYChanged(mThumbOffsetY);
- }
+ mRvOffsetY = mRv.getCurrentScrollY();
+ notifyScrollChanged();
}
public int getThumbOffsetY() {
@@ -422,13 +427,17 @@
mOnFastScrollChangeListener = onFastScrollChangeListener;
}
+ private void notifyScrollChanged() {
+ if (mOnFastScrollChangeListener != null) {
+ mOnFastScrollChangeListener.onScrollChanged();
+ }
+ }
+
/**
* A callback that is invoked when there is a scroll change in {@link RecyclerViewFastScroller}.
*/
public interface OnFastScrollChangeListener {
- /**
- * Called when the thumb offset vertical position, in pixels, has changed to {@code y}.
- */
- void onThumbOffsetYChanged(int y);
+ /** Called when the recycler view scroll has changed. */
+ void onScrollChanged();
}
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 5387a3e..0ba94ab 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
import android.content.Context;
+import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
@@ -37,13 +38,16 @@
private SystemUiController mSystemUiController;
+ private ScrimDrawingController mDrawingController;
+
public ScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(false);
}
@Override
- public void setInsets(Rect insets) { }
+ public void setInsets(Rect insets) {
+ }
@Override
public boolean hasOverlappingRendering() {
@@ -63,6 +67,14 @@
}
@Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (mDrawingController != null) {
+ mDrawingController.drawOnScrim(canvas);
+ }
+ }
+
+ @Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
updateSysUiColors();
@@ -96,4 +108,24 @@
return ColorUtils.calculateLuminance(
((ColorDrawable) getBackground()).getColor()) < 0.5f;
}
+
+ /**
+ * Sets drawing controller. Invalidates ScrimView if drawerController has changed.
+ */
+ public void setDrawingController(ScrimDrawingController drawingController) {
+ if (mDrawingController != drawingController) {
+ mDrawingController = drawingController;
+ invalidate();
+ }
+ }
+
+ /**
+ * A Utility interface allowing for other surfaces to draw on ScrimView
+ */
+ public interface ScrimDrawingController {
+ /**
+ * Called inside ScrimView#OnDraw
+ */
+ void drawOnScrim(Canvas canvas);
+ }
}
diff --git a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
index 3a24c3d..149ac57 100644
--- a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
@@ -44,7 +44,7 @@
mPaint = new TextPaint();
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
- mLauncher.getDeviceProfile().getFullScreenProfile().iconTextSizePx,
+ mLauncher.getDeviceProfile().iconTextSizePx,
getResources().getDisplayMetrics()));
setBackgroundResource(R.drawable.bg_deferred_app_widget);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 697c453..5deecd4 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer;
import static com.android.launcher3.Utilities.setRect;
-import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
@@ -102,6 +101,7 @@
private final Rect mCurrentWidgetSize = new Rect();
private final Rect mWidgetSizeAtDrag = new Rect();
+ private final float[] mTmpFloatArray = new float[4];
private final RectF mTempRectF = new RectF();
private final Rect mEnforcedRectangle = new Rect();
private final float mEnforcedCornerRadius;
@@ -323,7 +323,7 @@
if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
getBoundsForViewInDragLayer(mLauncher.getDragLayer(), this, mCurrentWidgetSize, true,
- mTempRectF);
+ mTmpFloatArray, mTempRectF);
setRect(mTempRectF, mCurrentWidgetSize);
updateColorExtraction(mCurrentWidgetSize,
mWorkspace.getPageIndexForScreenId(info.screenId));
@@ -357,7 +357,7 @@
* @param pageId The workspace page the widget is on.
*/
private void updateColorExtraction(Rect rectInDragLayer, int pageId) {
- getColorExtractionRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
+ mColorExtractor.getExtractedRectForViewRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
if (mTempRectF.isEmpty()) {
return;
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index ad61495..de511cd 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -13,6 +13,7 @@
import android.os.Parcel;
import android.os.UserHandle;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
@@ -66,20 +67,25 @@
}
public void initSpans(Context context, InvariantDeviceProfile idp) {
- Point landCellSize = idp.landscapeProfile.getCellSize();
- Point portCellSize = idp.portraitProfile.getCellSize();
-
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations.
- float smallestCellWidth = Math.min(landCellSize.x, portCellSize.x);
- float smallestCellHeight = Math.min(landCellSize.y, portCellSize.y);
+ float smallestCellWidth = Float.MAX_VALUE;
+ float smallestCellHeight = Float.MAX_VALUE;
+
+ Point cellSize = new Point();
+ boolean isWidgetPadded = false;
+ for (DeviceProfile dp : idp.supportedProfiles) {
+ dp.getCellSize(cellSize);
+ smallestCellWidth = Math.min(smallestCellWidth, cellSize.x);
+ smallestCellHeight = Math.min(smallestCellHeight, cellSize.y);
+ isWidgetPadded = isWidgetPadded || !dp.shouldInsetWidgets();
+ }
// We want to account for the extra amount of padding that we are adding to the widget
// to ensure that it gets the full amount of space that it has requested.
// If grids supports insetting widgets, we do not account for widget padding.
Rect widgetPadding = new Rect();
- if (!idp.landscapeProfile.shouldInsetWidgets()
- || !idp.portraitProfile.shouldInsetWidgets()) {
+ if (isWidgetPadded) {
AppWidgetHostView.getDefaultPaddingForWidget(context, provider, widgetPadding);
}
diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java
index 2121bc2..a66024a 100644
--- a/src/com/android/launcher3/widget/LocalColorExtractor.java
+++ b/src/com/android/launcher3/widget/LocalColorExtractor.java
@@ -16,14 +16,19 @@
package com.android.launcher3.widget;
+import android.app.WallpaperColors;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.util.SparseIntArray;
+import android.view.View;
import androidx.annotation.Nullable;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.ResourceBasedOverride;
import java.util.List;
@@ -31,6 +36,10 @@
/** Extracts the colors we need from the wallpaper at given locations. */
public class LocalColorExtractor implements ResourceBasedOverride {
+ // Index used to get background color when using local wallpaper color extraction,
+ private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
+ private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_800;
+
/** Listener for color changes on a screen location. */
public interface Listener {
/**
@@ -44,7 +53,7 @@
}
/**
- * Returns a new instance of the LocalColorExtractor.
+ * Creates a new instance of LocalColorExtractor
*/
public static LocalColorExtractor newInstance(Context context) {
return Overrides.getObject(LocalColorExtractor.class, context.getApplicationContext(),
@@ -65,4 +74,47 @@
public void removeLocations() {
// no-op
}
+
+ /**
+ * Updates the base context to contain the colors override
+ */
+ public void applyColorsOverride(Context base, WallpaperColors colors) { }
+
+ /**
+ * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
+ *
+ * @param launcher Launcher class class.
+ * @param pageId The page the workspace item is on.
+ * @param v The view.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForView(Launcher launcher, int pageId, View v,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
+
+ /**
+ * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
+ * local color extractor.
+ *
+ * @param launcher Launcher class.
+ * @param pageId The page the workspace item is on.
+ * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForViewRect(Launcher launcher, int pageId, Rect rectInDragLayer,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
+
+ /**
+ * Returns an index used to query the color of interest from the list of extracted colors.
+ */
+ public static int getColorIndex(Context context) {
+ return Utilities.isDarkTheme(context)
+ ? DARK_COLOR_EXTRACTION_INDEX
+ : LIGHT_COLOR_EXTRACTION_INDEX;
+ }
}
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index ee0b84e..3377abb 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -15,9 +15,11 @@
*/
package com.android.launcher3.widget;
+import static com.android.launcher3.AppWidgetResizeFrame.getWidgetSizeOptions;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
import android.appwidget.AppWidgetHostView;
+import android.content.Context;
import android.os.Bundle;
import com.android.launcher3.LauncherSettings;
@@ -57,4 +59,8 @@
public WidgetAddFlowHandler getHandler() {
return new WidgetAddFlowHandler(info);
}
+
+ public Bundle getDefaultSizeOptions(Context context) {
+ return getWidgetSizeOptions(context, componentName, spanX, spanY);
+ }
}
diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
index 12e0d43..46141e0 100644
--- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java
+++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
@@ -1,16 +1,12 @@
package com.android.launcher3.widget;
import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
import android.content.Context;
-import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
-import android.util.SizeF;
import android.view.View;
-import com.android.launcher3.AppWidgetResizeFrame;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
import com.android.launcher3.dragndrop.DragController;
@@ -18,9 +14,6 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.util.Thunk;
-import java.util.ArrayList;
-import java.util.stream.Collectors;
-
public class WidgetHostViewLoader implements DragController.DragListener {
private static final String TAG = "WidgetHostViewLoader";
private static final boolean LOGD = false;
@@ -90,7 +83,7 @@
if (pInfo.isCustomWidget()) {
return false;
}
- final Bundle options = getDefaultOptionsForWidget(mLauncher, mInfo);
+ final Bundle options = mInfo.getDefaultSizeOptions(mLauncher);
// If there is a configuration activity, do not follow thru bound and inflate.
if (mInfo.getHandler().needsConfigure()) {
@@ -154,29 +147,4 @@
return true;
}
- public static Bundle getDefaultOptionsForWidget(Context context, PendingAddWidgetInfo info) {
- ArrayList<SizeF> sizes = AppWidgetResizeFrame
- .getWidgetSizes(context, info.spanX, info.spanY);
-
- Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(context,
- info.componentName, null);
- float density = context.getResources().getDisplayMetrics().density;
- float xPaddingDips = (padding.left + padding.right) / density;
- float yPaddingDips = (padding.top + padding.bottom) / density;
-
- ArrayList<SizeF> paddedSizes = sizes.stream().map(
- size -> new SizeF(Math.max(0.f, size.getWidth() - xPaddingDips),
- Math.max(0.f, size.getHeight() - yPaddingDips))).collect(
- Collectors.toCollection(ArrayList::new));
-
- Rect rect = AppWidgetResizeFrame.getMinMaxSizes(paddedSizes, null /* outRect */);
-
- Bundle options = new Bundle();
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, rect.left);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, rect.top);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, rect.right);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, rect.bottom);
- options.putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, paddedSizes);
- return options;
- }
}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index f18b63e..995ac47 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -118,6 +118,7 @@
ViewGroup.LayoutParams layoutParams = widgetsTableScrollView.getLayoutParams();
layoutParams.height = mMaxTableHeight;
widgetsTableScrollView.setLayoutParams(layoutParams);
+ findViewById(R.id.collapse_handle).setVisibility(VISIBLE);
}
}
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 7f84077..317fd03 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.widget.picker;
+import android.graphics.Point;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.RelativeLayout;
@@ -33,9 +35,11 @@
RecyclerViewFastScroller.OnFastScrollChangeListener {
private final boolean mHasWorkProfile;
private final SearchAndRecommendationViewHolder mViewHolder;
+ private final View mSearchAndRecommendationViewParent;
private final WidgetsRecyclerView mPrimaryRecyclerView;
private final WidgetsRecyclerView mSearchRecyclerView;
private final int mTabsHeight;
+ private final Point mTempOffset = new Point();
// The following are only non null if mHasWorkProfile is true.
@Nullable private final WidgetsRecyclerView mWorkRecyclerView;
@@ -44,6 +48,8 @@
private WidgetsRecyclerView mCurrentRecyclerView;
+ private OnContentChangeListener mOnContentChangeListener = () -> applyVerticalTransition();
+
/**
* The vertical distance, in pixels, until the search is pinned at the top of the screen when
* the user scrolls down the recycler view.
@@ -62,6 +68,8 @@
*/
private int mCollapsibleHeightForTabs = 0;
+ private boolean mShouldForwardToRecyclerView = false;
+
SearchAndRecommendationsScrollController(
boolean hasWorkProfile,
int tabsHeight,
@@ -73,20 +81,24 @@
@Nullable PersonalWorkPagedView primaryWorkViewPager) {
mHasWorkProfile = hasWorkProfile;
mViewHolder = viewHolder;
+ mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
+ mSearchAndRecommendationViewParent = (View) mViewHolder.mContainer.getParent();
mPrimaryRecyclerView = primaryRecyclerView;
- mCurrentRecyclerView = mPrimaryRecyclerView;
mWorkRecyclerView = workRecyclerView;
mSearchRecyclerView = searchRecyclerView;
mPrimaryWorkTabsView = personalWorkTabsView;
mPrimaryWorkViewPager = primaryWorkViewPager;
- mCurrentRecyclerView = mPrimaryRecyclerView;
mTabsHeight = tabsHeight;
+ setCurrentRecyclerView(mPrimaryRecyclerView);
}
/** Sets the current active {@link WidgetsRecyclerView}. */
public void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView) {
+ if (mCurrentRecyclerView != null) {
+ mCurrentRecyclerView.setOnContentChangeListener(null);
+ }
mCurrentRecyclerView = currentRecyclerView;
- mCurrentRecyclerView = currentRecyclerView;
+ mCurrentRecyclerView.setOnContentChangeListener(mOnContentChangeListener);
mViewHolder.mHeaderTitle.setTranslationY(0);
mViewHolder.mRecommendedWidgetsTable.setTranslationY(0);
mViewHolder.mSearchBar.setTranslationY(0);
@@ -208,12 +220,16 @@
return hasMarginOrPaddingUpdated;
}
+ @Override
+ public void onScrollChanged() {
+ applyVerticalTransition();
+ }
+
/**
* Changes the displacement of collapsible views (e.g. title & widget recommendations) and fixed
- * views (e.g. recycler views, tabs) upon scrolling.
+ * views (e.g. recycler views, tabs) upon scrolling / content changes in the recycler view.
*/
- @Override
- public void onThumbOffsetYChanged(int unused) {
+ private void applyVerticalTransition() {
// Always use the recycler view offset because fast scroller offset has a different scale.
int recyclerViewYOffset = mCurrentRecyclerView.getCurrentScrollY();
if (recyclerViewYOffset < 0) return;
@@ -245,6 +261,43 @@
}
}
+ /**
+ * Returns {@code true} if a touch event should be intercepted by this controller.
+ */
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ mShouldForwardToRecyclerView = mCurrentRecyclerView.onInterceptTouchEvent(event);
+ return mShouldForwardToRecyclerView;
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
+ }
+
+ /**
+ * Returns {@code true} if this controller has intercepted and consumed a touch event.
+ */
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mShouldForwardToRecyclerView) {
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ return mCurrentRecyclerView.onTouchEvent(event);
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
+ }
+ return false;
+ }
+
+ private void calculateMotionEventOffset(Point p) {
+ p.x = mViewHolder.mContainer.getLeft() - mCurrentRecyclerView.getLeft()
+ - mSearchAndRecommendationViewParent.getLeft();
+ p.y = mViewHolder.mContainer.getTop() - mCurrentRecyclerView.getTop()
+ - mSearchAndRecommendationViewParent.getTop();
+ }
+
/** private the height, in pixel, + the vertical margins of a given view. */
private static int measureHeightWithVerticalMargins(View view) {
if (view.getVisibility() != View.VISIBLE) {
@@ -254,4 +307,13 @@
return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
+ marginLayoutParams.topMargin;
}
+
+ /**
+ * A listener to be notified when there is a content change in the recycler view that may affect
+ * the relative position of the search and recommendation container.
+ */
+ public interface OnContentChangeListener {
+ /** Notifies a content change in the recycler view. */
+ void onContentChanged();
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java
new file mode 100644
index 0000000..0d7d2b5
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget.picker;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.LinearLayout;
+
+/**
+ * A {@link LinearLayout} container for holding search and widgets recommendation.
+ *
+ * <p>This class intercepts touch events and dispatch them to the right view.
+ */
+public class SearchAndRecommendationsView extends LinearLayout {
+ private SearchAndRecommendationsScrollController mController;
+
+ public SearchAndRecommendationsView(Context context) {
+ this(context, /* attrs= */ null);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs) {
+ this(context, attrs, /* defStyleAttr= */ 0);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, /* defStyleRes= */ 0);
+ }
+
+ public SearchAndRecommendationsView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public void setSearchAndRecommendationScrollController(
+ SearchAndRecommendationsScrollController controller) {
+ mController = controller;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return mController.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return mController.onTouchEvent(event) || super.onTouchEvent(event);
+ }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index b4d4856..4d8c1ca 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -146,7 +146,7 @@
mAdapters.put(AdapterHolder.SEARCH, new AdapterHolder(AdapterHolder.SEARCH));
mTabsHeight = mHasWorkProfile
? getContext().getResources()
- .getDimensionPixelSize(R.dimen.all_apps_header_tab_height)
+ .getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
: 0;
mWidgetCellHorizontalPadding = 2 * getResources().getDimensionPixelOffset(
R.dimen.widget_cell_horizontal_padding);
@@ -709,13 +709,14 @@
}
final class SearchAndRecommendationViewHolder {
- final ViewGroup mContainer;
+ final SearchAndRecommendationsView mContainer;
final View mCollapseHandle;
final WidgetsSearchBar mSearchBar;
final TextView mHeaderTitle;
final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
- SearchAndRecommendationViewHolder(ViewGroup searchAndRecommendationContainer) {
+ SearchAndRecommendationViewHolder(
+ SearchAndRecommendationsView searchAndRecommendationContainer) {
mContainer = searchAndRecommendationContainer;
mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 1524ab3..c3eda13 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -47,7 +47,6 @@
private int mMaxSpansPerRow = 4;
private final LayoutInflater mLayoutInflater;
- private final int mIndent;
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
private final WidgetPreviewLoader mWidgetPreviewLoader;
@@ -62,7 +61,6 @@
WidgetPreviewLoader widgetPreviewLoader,
WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater;
- mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent);
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
mWidgetPreviewLoader = widgetPreviewLoader;
@@ -90,11 +88,6 @@
ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false);
-
- // if the end padding is 0, then container view (horizontal scroll view) doesn't respect
- // the end of the linear layout width + the start padding and doesn't allow scrolling.
- container.findViewById(R.id.widgets_table).setPaddingRelative(mIndent, 0, 1, 0);
-
return new WidgetsRowViewHolder(container);
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index eb821d4..e981906 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -23,6 +23,8 @@
import android.view.View;
import android.widget.TableLayout;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
@@ -35,6 +37,7 @@
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
+import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;
/**
* The widgets recycler view.
@@ -50,6 +53,7 @@
private boolean mTouchDownOnScroller;
private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
private int mLastVisibleWidgetContentTableHeight = 0;
+ @Nullable private OnContentChangeListener mOnContentChangeListener;
public WidgetsRecyclerView(Context context) {
this(context, null);
@@ -86,6 +90,22 @@
mAdapter = (WidgetsListAdapter) adapter;
}
+ @Override
+ public void onChildAttachedToWindow(@NonNull View child) {
+ super.onChildAttachedToWindow(child);
+ if (mOnContentChangeListener != null) {
+ mOnContentChangeListener.onContentChanged();
+ }
+ }
+
+ @Override
+ public void onChildDetachedFromWindow(@NonNull View child) {
+ super.onChildDetachedFromWindow(child);
+ if (mOnContentChangeListener != null) {
+ mOnContentChangeListener.onContentChanged();
+ }
+ }
+
/**
* Maps the touch (from 0..1) to the adapter position that should be visible.
*/
@@ -207,6 +227,25 @@
mHeaderViewDimensionsProvider = headerViewDimensionsProvider;
}
+ @Override
+ public void scrollToTop() {
+ if (mScrollbar != null) {
+ mScrollbar.reattachThumbToScroll();
+ }
+
+ if (getLayoutManager() instanceof LinearLayoutManager) {
+ if (getCurrentScrollY() == 0) {
+ // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
+ return;
+ }
+ }
+ scrollToPosition(0);
+ }
+
+ public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
+ mOnContentChangeListener = listener;
+ }
+
/**
* Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
* {@code untilIndex}.
@@ -244,19 +283,4 @@
*/
int getHeaderViewHeight();
}
-
- @Override
- public void scrollToTop() {
- if (mScrollbar != null) {
- mScrollbar.reattachThumbToScroll();
- }
-
- if (getLayoutManager() instanceof LinearLayoutManager) {
- if (getCurrentScrollY() == 0) {
- // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
- return;
- }
- }
- scrollToPosition(0);
- }
}
diff --git a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
index 3a3028f..b5db8f4 100644
--- a/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/workprofile/PersonalWorkSlidingTabStrip.java
@@ -39,6 +39,8 @@
private final Paint mDividerPaint;
private int mSelectedIndicatorHeight;
+ private final int mSelectedIndicatorRadius;
+
private int mIndicatorLeft = -1;
private int mIndicatorRight = -1;
private float mScrollOffset;
@@ -54,7 +56,10 @@
setWillNotDraw(false);
mSelectedIndicatorHeight =
- getResources().getDimensionPixelSize(R.dimen.all_apps_tabs_indicator_height);
+ getResources().getDimensionPixelSize(R.dimen.all_apps_header_pill_height);
+
+ mSelectedIndicatorRadius = getResources().getDimensionPixelSize(
+ R.dimen.all_apps_header_pill_corner_radius);
mSelectedIndicatorPaint = new Paint();
mSelectedIndicatorPaint.setColor(
@@ -118,9 +123,9 @@
super.onDraw(canvas);
float y = getHeight() - mDividerPaint.getStrokeWidth();
- canvas.drawLine(getPaddingLeft(), y, getWidth() - getPaddingRight(), y, mDividerPaint);
- canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
- mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
+ canvas.drawRoundRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
+ mIndicatorRight, getHeight(), mSelectedIndicatorRadius, mSelectedIndicatorRadius,
+ mSelectedIndicatorPaint);
}
@Override
@@ -144,7 +149,8 @@
}
@Override
- public void setMarkersCount(int numMarkers) { }
+ public void setMarkersCount(int numMarkers) {
+ }
@Override
public boolean hasOverlappingRendering() {
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
index 6fd147a..4407fe1 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -18,12 +18,22 @@
import android.app.Person;
import android.content.pm.ShortcutInfo;
+import android.view.Display;
import com.android.launcher3.Utilities;
public class ApiWrapper {
+ public static final boolean TASKBAR_DRAWN_IN_PROCESS = false;
+
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
+
+ /**
+ * Returns true if the display is an internal displays
+ */
+ public static boolean isInternalDisplay(Display display) {
+ return display.getDisplayId() == Display.DEFAULT_DISPLAY;
+ }
}
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 7f6c8f8..918ec4a 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -109,7 +109,7 @@
<activity
android:name="com.android.launcher3.testcomponent.TestLauncherActivity"
android:clearTaskOnLaunch="true"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:enabled="false"
android:label="Test launcher"
android:launchMode="singleTask"
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 2a0f7bb..8936f39 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -249,6 +249,7 @@
@Before
public void setUp() throws Exception {
+ mLauncher.onTestStart();
Assert.assertTrue("Keyguard is visible, which is likely caused by a crash in SysUI",
TestHelpers.wait(
Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
@@ -288,13 +289,17 @@
@After
public void verifyLauncherState() {
- // Limits UI tests affecting tests running after them.
- mLauncher.waitForLauncherInitialized();
- if (mLauncherPid != 0) {
- assertEquals("Launcher crashed, pid mismatch:",
- mLauncherPid, mLauncher.getPid().intValue());
+ try {
+ // Limits UI tests affecting tests running after them.
+ mLauncher.waitForLauncherInitialized();
+ if (mLauncherPid != 0) {
+ assertEquals("Launcher crashed, pid mismatch:",
+ mLauncherPid, mLauncher.getPid().intValue());
+ }
+ checkDetectedLeaks(mLauncher);
+ } finally {
+ mLauncher.onTestFinish();
}
- checkDetectedLeaks(mLauncher);
}
protected void clearLauncherData() {
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index 6c68daa..8f2d528 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -55,23 +55,19 @@
}
private void evaluateInPortrait() throws Throwable {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "evaluateInPortrait");
mTest.mDevice.setOrientationNatural();
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_0);
AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher);
base.evaluate();
mTest.getDevice().pressHome();
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "evaluateInPortrait finished");
}
private void evaluateInLandscape() throws Throwable {
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "evaluateInLandscape");
mTest.mDevice.setOrientationLeft();
mTest.mLauncher.setExpectedRotation(Surface.ROTATION_90);
AbstractLauncherUiTest.checkDetectedLeaks(mTest.mLauncher);
base.evaluate();
mTest.getDevice().pressHome();
- Log.d(TestProtocol.LAUNCHER_NOT_TRANSPOSED, "evaluateInLandscape finished");
}
};
}
diff --git a/tests/src_common/com/android/launcher3/common/WidgetUtils.java b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
index ffad93f..5e17e0a 100644
--- a/tests/src_common/com/android/launcher3/common/WidgetUtils.java
+++ b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
@@ -16,7 +16,6 @@
package com.android.launcher3.common;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
-import static com.android.launcher3.widget.WidgetHostViewLoader.getDefaultOptionsForWidget;
import android.appwidget.AppWidgetHost;
import android.content.ContentResolver;
@@ -62,7 +61,7 @@
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
- Bundle options = getDefaultOptionsForWidget(targetContext, pendingInfo);
+ Bundle options = pendingInfo.getDefaultSizeOptions(targetContext);
AppWidgetHost host = new LauncherAppWidgetHost(targetContext);
int widgetId = host.allocateAppWidgetId();
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index ebad154..c77583c 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -95,7 +95,6 @@
private static final String TAG = "Tapl";
private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
private static final int GESTURE_STEP_MS = 16;
- private static long START_TIME = System.currentTimeMillis();
private static final Pattern EVENT_TOUCH_DOWN = getTouchEventPattern("ACTION_DOWN");
private static final Pattern EVENT_TOUCH_UP = getTouchEventPattern("ACTION_UP");
@@ -107,6 +106,7 @@
static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");
private final String mLauncherPackage;
private final boolean mIsLauncher3;
+ private long mTestStartTime = -1;
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
@@ -422,6 +422,14 @@
mOnSettledStateAction = onSettledStateAction;
}
+ public void onTestStart() {
+ mTestStartTime = System.currentTimeMillis();
+ }
+
+ public void onTestFinish() {
+ mTestStartTime = -1;
+ }
+
private String formatSystemHealthMessage(String message) {
final String testPackage = getContext().getPackageName();
@@ -430,14 +438,16 @@
mInstrumentation.getUiAutomation().grantRuntimePermission(
testPackage, "android.permission.PACKAGE_USAGE_STATS");
- final String systemHealth = mSystemHealthSupplier != null
- ? mSystemHealthSupplier.apply(START_TIME)
- : TestHelpers.getSystemHealthMessage(getContext(), START_TIME);
+ if (mTestStartTime > 0) {
+ final String systemHealth = mSystemHealthSupplier != null
+ ? mSystemHealthSupplier.apply(mTestStartTime)
+ : TestHelpers.getSystemHealthMessage(getContext(), mTestStartTime);
- if (systemHealth != null) {
- return message
- + ",\nperhaps linked to system health problems:\n<<<<<<<<<<<<<<<<<<\n"
- + systemHealth + "\n>>>>>>>>>>>>>>>>>>";
+ if (systemHealth != null) {
+ return message
+ + ",\nperhaps linked to system health problems:\n<<<<<<<<<<<<<<<<<<\n"
+ + systemHealth + "\n>>>>>>>>>>>>>>>>>>";
+ }
}
return message;
@@ -695,6 +705,7 @@
waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
// Swiping up can temporarily bring Nexus Launcher if the current
// Launcher is a Launcher3 one. Wait for the current launcher to reappear.
+ SystemClock.sleep(5000); // b/187080582
waitForLauncherObject(getAnyObjectSelector());
}
}
@@ -1348,6 +1359,8 @@
}
public int getTotalPssKb() {
+ // GC the system & sysui first before gc'ing launcher
+ logShellCommand("cmd statusbar run-gc");
return getTestInfo(TestProtocol.REQUEST_TOTAL_PSS_KB).
getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}