diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml
index 469ad942d9..e77c88926d 100644
--- a/lint-baseline-launcher3.xml
+++ b/lint-baseline-launcher3.xml
@@ -573,4 +573,15 @@
column="42"/>
+
+
+
+
diff --git a/quickstep/protos_overrides/launcher_atom_extension.proto b/quickstep/protos_overrides/launcher_atom_extension.proto
index 6253b41aac..d2dc0cb745 100644
--- a/quickstep/protos_overrides/launcher_atom_extension.proto
+++ b/quickstep/protos_overrides/launcher_atom_extension.proto
@@ -26,6 +26,7 @@ message ExtendedContainers {
oneof Container{
DeviceSearchResultContainer device_search_result_container = 1;
+ CorrectedDeviceSearchResultContainer corrected_device_search_result_container = 2;
}
}
@@ -33,3 +34,9 @@ message ExtendedContainers {
message DeviceSearchResultContainer{
optional int32 query_length = 1;
}
+
+// Represents on-device search result container with results from spell-corrected query.
+message CorrectedDeviceSearchResultContainer{
+ optional int32 query_length = 1;
+}
+
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_back_left.xml
similarity index 82%
rename from quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml
rename to quickstep/res/drawable/gesture_tutorial_motion_back_left.xml
index f5ad56916b..a6860fac64 100644
--- a/quickstep/res/drawable/gesture_tutorial_motion_back_left_dark_mode.xml
+++ b/quickstep/res/drawable/gesture_tutorial_motion_back_left.xml
@@ -1,306 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -313,11 +21,11 @@
@@ -330,11 +38,11 @@
@@ -347,11 +55,11 @@
@@ -364,11 +72,11 @@
@@ -381,11 +89,11 @@
@@ -398,11 +106,11 @@
@@ -415,11 +123,11 @@
@@ -432,11 +140,11 @@
@@ -449,11 +157,11 @@
@@ -466,11 +174,11 @@
@@ -483,11 +191,11 @@
@@ -500,11 +208,11 @@
@@ -517,11 +225,11 @@
@@ -530,203 +238,486 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -973,7 +814,7 @@
@@ -1090,104 +931,104 @@
android:viewportWidth="412">
-
-
+
+
-
-
-
-
-
+ android:translateX="-17.875"
+ android:translateY="322.017">
+ android:translateX="123.282"
+ android:translateY="129.757">
+ android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_back_right.xml
similarity index 82%
rename from quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml
rename to quickstep/res/drawable/gesture_tutorial_motion_back_right.xml
index b898dc17a6..b368d9d045 100644
--- a/quickstep/res/drawable/gesture_tutorial_motion_back_right_dark_mode.xml
+++ b/quickstep/res/drawable/gesture_tutorial_motion_back_right.xml
@@ -1,306 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -313,11 +21,11 @@
@@ -330,11 +38,11 @@
@@ -347,11 +55,11 @@
@@ -364,11 +72,11 @@
@@ -381,11 +89,11 @@
@@ -398,11 +106,11 @@
@@ -415,11 +123,11 @@
@@ -432,11 +140,11 @@
@@ -449,11 +157,11 @@
@@ -466,11 +174,11 @@
@@ -483,11 +191,11 @@
@@ -500,11 +208,11 @@
@@ -517,11 +225,11 @@
@@ -530,203 +238,486 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -973,7 +814,7 @@
@@ -1090,104 +931,104 @@
android:viewportWidth="412">
-
-
+
+
-
-
-
-
-
+ android:translateX="-17.875"
+ android:translateY="322.017">
+ android:translateX="565.282"
+ android:translateY="129.757">
+ android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 4eb2d53b46..ef96c963bd 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -423,7 +423,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
ActivityOptionsWrapper activityOptions =
mAppTransitionManager.hasControlRemoteAppTransitionPermission()
- ? mAppTransitionManager.getActivityLaunchOptions(this, v)
+ ? mAppTransitionManager.getActivityLaunchOptions(v)
: super.getActivityLaunchOptions(v, item);
if (mLastTouchUpTime > 0) {
ActivityOptionsCompat.setLauncherSourceInfo(
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 1090099d2f..661053af18 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -36,26 +36,48 @@ import androidx.annotation.UiThread;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import java.lang.ref.WeakReference;
+
+/**
+ * This class is needed to wrap any animation runner that is a part of the
+ * RemoteAnimationDefinition:
+ * - Launcher creates a new instance of the LauncherAppTransitionManagerImpl whenever it is
+ * created, which in turn registers a new definition
+ * - When the definition is registered, window manager retains a strong binder reference to the
+ * runner passed in
+ * - If the Launcher activity is recreated, the new definition registered will replace the old
+ * reference in the system's activity record, but until the system server is GC'd, the binder
+ * reference will still exist, which references the runner in the Launcher process, which
+ * references the (old) Launcher activity through this class
+ *
+ * Instead we make the runner provided to the definition static only holding a weak reference to
+ * the runner implementation. When this animation manager is destroyed, we remove the Launcher
+ * reference to the runner, leaving only the weak ref from the runner.
+ */
@TargetApi(Build.VERSION_CODES.P)
-public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
+public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
+
+ private static final RemoteAnimationFactory DEFAULT_FACTORY =
+ (transit, appTargets, wallpaperTargets, nonAppTargets, result) ->
+ result.setAnimation(null, null);
private final Handler mHandler;
private final boolean mStartAtFrontOfQueue;
+ private final WeakReference mFactory;
+
private AnimationResult mAnimationResult;
/**
* @param startAtFrontOfQueue If true, the animation start will be posted at the front of the
* queue to minimize latency.
*/
- public LauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue) {
+ public LauncherAnimationRunner(Handler handler, RemoteAnimationFactory factory,
+ boolean startAtFrontOfQueue) {
mHandler = handler;
+ mFactory = new WeakReference<>(factory);
mStartAtFrontOfQueue = startAtFrontOfQueue;
}
- public Handler getHandler() {
- return mHandler;
- }
-
// Called only in S+ platform
@BinderThread
public void onAnimationStart(
@@ -67,7 +89,7 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
Runnable r = () -> {
finishExistingAnimation();
mAnimationResult = new AnimationResult(() -> mAnimationResult = null, runnable);
- onCreateAnimation(transit, appTargets, wallpaperTargets, nonAppTargets,
+ getFactory().onCreateAnimation(transit, appTargets, wallpaperTargets, nonAppTargets,
mAnimationResult);
};
if (mStartAtFrontOfQueue) {
@@ -92,17 +114,11 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
onAnimationStart(appTargets, new RemoteAnimationTargetCompat[0], runnable);
}
- /**
- * Called on the UI thread when the animation targets are received. The implementation must
- * call {@link AnimationResult#setAnimation} with the target animation to be run.
- */
- @UiThread
- public abstract void onCreateAnimation(
- int transit,
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets,
- AnimationResult result);
+
+ private RemoteAnimationFactory getFactory() {
+ RemoteAnimationFactory factory = mFactory.get();
+ return factory != null ? factory : DEFAULT_FACTORY;
+ }
@UiThread
private void finishExistingAnimation() {
@@ -118,7 +134,10 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
@BinderThread
@Override
public void onAnimationCancelled() {
- postAsyncCallback(mHandler, this::finishExistingAnimation);
+ postAsyncCallback(mHandler, () -> {
+ finishExistingAnimation();
+ getFactory().onAnimationCancelled();
+ });
}
public static final class AnimationResult {
@@ -153,7 +172,6 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
@UiThread
public void setAnimation(AnimatorSet animation, Context context) {
setAnimation(animation, context, null, true);
-
}
/**
@@ -198,4 +216,28 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo
}
}
}
+
+ /**
+ * Used with LauncherAnimationRunner as an interface for the runner to call back to the
+ * implementation.
+ */
+ @FunctionalInterface
+ public interface RemoteAnimationFactory {
+
+ /**
+ * Called on the UI thread when the animation targets are received. The implementation must
+ * call {@link AnimationResult#setAnimation} with the target animation to be run.
+ */
+ void onCreateAnimation(int transit,
+ RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets,
+ LauncherAnimationRunner.AnimationResult result);
+
+ /**
+ * Called when the animation is cancelled. This can happen with or without
+ * the create being called.
+ */
+ default void onAnimationCancelled() { }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 2d1e304325..a07f27f6fe 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -79,6 +79,7 @@ import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.icons.FastBitmapDrawable;
@@ -197,11 +198,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
private RemoteAnimationProvider mRemoteAnimationProvider;
// Strong refs to runners which are cleared when the launcher activity is destroyed
- private WrappedAnimationRunnerImpl mWallpaperOpenRunner;
- private WrappedAnimationRunnerImpl mAppLaunchRunner;
- private WrappedAnimationRunnerImpl mKeyguardGoingAwayRunner;
+ private RemoteAnimationFactory mWallpaperOpenRunner;
+ private RemoteAnimationFactory mAppLaunchRunner;
+ private RemoteAnimationFactory mKeyguardGoingAwayRunner;
- private WrappedAnimationRunnerImpl mWallpaperOpenTransitionRunner;
+ private RemoteAnimationFactory mWallpaperOpenTransitionRunner;
private RemoteTransitionCompat mLauncherOpenTransition;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@@ -257,11 +258,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
* @return ActivityOptions with remote animations that controls how the window of the opening
* targets are displayed.
*/
- public ActivityOptionsWrapper getActivityLaunchOptions(Launcher launcher, View v) {
+ public ActivityOptionsWrapper getActivityLaunchOptions(View v) {
boolean fromRecents = isLaunchingFromRecents(v, null /* targets */);
RunnableList onEndCallback = new RunnableList();
- mAppLaunchRunner = new AppLaunchAnimationRunner(mHandler, v, onEndCallback);
- RemoteAnimationRunnerCompat runner = new WrappedLauncherAnimationRunner<>(
+ mAppLaunchRunner = new AppLaunchAnimationRunner(v, onEndCallback);
+ RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(
mHandler, mAppLaunchRunner, true /* startAtFrontOfQueue */);
// Note that this duration is a guess as we do not know if the animation will be a
@@ -1006,7 +1007,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
WindowManagerWrapper.ACTIVITY_TYPE_STANDARD,
new RemoteAnimationAdapterCompat(
- new WrappedLauncherAnimationRunner<>(mHandler, mWallpaperOpenRunner,
+ new LauncherAnimationRunner(mHandler, mWallpaperOpenRunner,
false /* startAtFrontOfQueue */),
CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
@@ -1015,7 +1016,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
definition.addRemoteAnimation(
WindowManagerWrapper.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
new RemoteAnimationAdapterCompat(
- new WrappedLauncherAnimationRunner<>(
+ new LauncherAnimationRunner(
mHandler, mKeyguardGoingAwayRunner,
true /* startAtFrontOfQueue */),
CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
@@ -1035,7 +1036,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
if (hasControlRemoteAppTransitionPermission()) {
mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
mLauncherOpenTransition = RemoteAnimationAdapterCompat.buildRemoteTransition(
- new WrappedLauncherAnimationRunner<>(mHandler, mWallpaperOpenTransitionRunner,
+ new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
false /* startAtFrontOfQueue */));
mLauncherOpenTransition.addHomeOpenCheck();
SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition);
@@ -1093,7 +1094,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
* @return Runner that plays when user goes to Launcher
* ie. pressing home, swiping up from nav bar.
*/
- WrappedAnimationRunnerImpl createWallpaperOpenRunner(boolean fromUnlock) {
+ RemoteAnimationFactory createWallpaperOpenRunner(boolean fromUnlock) {
return new WallpaperOpenLauncherAnimationRunner(mHandler, fromUnlock);
}
@@ -1243,7 +1244,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
/**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
- protected class WallpaperOpenLauncherAnimationRunner implements WrappedAnimationRunnerImpl {
+ protected class WallpaperOpenLauncherAnimationRunner implements RemoteAnimationFactory {
private final Handler mHandler;
private final boolean mFromUnlock;
@@ -1331,17 +1332,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
/**
* Remote animation runner for animation to launch an app.
*/
- private class AppLaunchAnimationRunner implements WrappedAnimationRunnerImpl {
+ private class AppLaunchAnimationRunner implements RemoteAnimationFactory {
- private static final String TRANSITION_LAUNCH_FROM_RECENTS = "transition:LaunchFromRecents";
- private static final String TRANSITION_LAUNCH_FROM_ICON = "transition:LaunchFromIcon";
-
- private final Handler mHandler;
private final View mV;
private final RunnableList mOnEndCallback;
- AppLaunchAnimationRunner(Handler handler, View v, RunnableList onEndCallback) {
- mHandler = handler;
+ AppLaunchAnimationRunner(View v, RunnableList onEndCallback) {
mV = v;
mOnEndCallback = onEndCallback;
}
@@ -1385,6 +1381,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy,
skipFirstFrame);
}
+
+ @Override
+ public void onAnimationCancelled() {
+ mOnEndCallback.executeAllAndDestroy();
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java b/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java
deleted file mode 100644
index 16727ecfda..0000000000
--- a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-
-/**
- * Used with WrappedLauncherAnimationRunner as an interface for the runner to call back to the
- * implementation.
- */
-public interface WrappedAnimationRunnerImpl {
-
- void onCreateAnimation(int transit,
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets,
- LauncherAnimationRunner.AnimationResult result);
-}
diff --git a/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java
deleted file mode 100644
index fcf9857649..0000000000
--- a/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.os.Handler;
-
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-
-import java.lang.ref.WeakReference;
-
-/**
- * This class is needed to wrap any animation runner that is a part of the
- * RemoteAnimationDefinition:
- * - Launcher creates a new instance of the LauncherAppTransitionManagerImpl whenever it is
- * created, which in turn registers a new definition
- * - When the definition is registered, window manager retains a strong binder reference to the
- * runner passed in
- * - If the Launcher activity is recreated, the new definition registered will replace the old
- * reference in the system's activity record, but until the system server is GC'd, the binder
- * reference will still exist, which references the runner in the Launcher process, which
- * references the (old) Launcher activity through this class
- *
- * Instead we make the runner provided to the definition static only holding a weak reference to
- * the runner implementation. When this animation manager is destroyed, we remove the Launcher
- * reference to the runner, leaving only the weak ref from the runner.
- */
-public class WrappedLauncherAnimationRunner
- extends LauncherAnimationRunner {
- private WeakReference mImpl;
-
- public WrappedLauncherAnimationRunner(
- Handler handler, R animationRunnerImpl, boolean startAtFrontOfQueue) {
- super(handler, startAtFrontOfQueue);
- mImpl = new WeakReference<>(animationRunnerImpl);
- }
-
- @Override
- public void onCreateAnimation(int transit,
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets,
- AnimationResult result) {
- R animationRunnerImpl = mImpl.get();
- if (animationRunnerImpl != null) {
- animationRunnerImpl.onCreateAnimation(transit, appTargets, wallpaperTargets,
- nonAppTargets, result);
- } else {
- result.setAnimation(null, null);
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index e6333d196b..4503e308e6 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.os.IBinder;
import android.util.FloatProperty;
+import android.view.CrossWindowBlurListeners;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
@@ -41,6 +42,8 @@ import com.android.launcher3.states.StateAnimationConfig;
import com.android.systemui.shared.system.BlurUtils;
import com.android.systemui.shared.system.WallpaperManagerCompat;
+import java.util.function.Consumer;
+
/**
* Controls blur and wallpaper zoom, for the Launcher surface only.
*/
@@ -96,11 +99,17 @@ public class DepthController implements StateHandler,
}
};
+ private final Consumer mCrossWindowBlurListener = (enabled) -> {
+ mCrossWindowBlursEnabled = enabled;
+ dispatchTransactionSurface();
+ };
+
private final Launcher mLauncher;
/**
* Blur radius when completely zoomed out, in pixels.
*/
private int mMaxBlurRadius;
+ private boolean mCrossWindowBlursEnabled;
private WallpaperManagerCompat mWallpaperManager;
private SurfaceControl mSurface;
/**
@@ -123,6 +132,7 @@ public class DepthController implements StateHandler,
mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
mWallpaperManager = new WallpaperManagerCompat(mLauncher);
}
+
if (mLauncher.getRootView() != null && mOnAttachListener == null) {
mOnAttachListener = new View.OnAttachStateChangeListener() {
@Override
@@ -132,13 +142,20 @@ public class DepthController implements StateHandler,
if (windowToken != null) {
mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
}
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
}
@Override
public void onViewDetachedFromWindow(View view) {
+ CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
}
};
mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
+ if (mLauncher.getRootView().isAttachedToWindow()) {
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
+ }
}
}
@@ -220,7 +237,8 @@ public class DepthController implements StateHandler,
boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW);
boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview;
- int blur = opaque || isOverview ? 0 : (int) (mDepth * mMaxBlurRadius);
+ int blur = opaque || isOverview || !mCrossWindowBlursEnabled
+ ? 0 : (int) (mDepth * mMaxBlurRadius);
new SurfaceControl.Transaction()
.setBackgroundBlurRadius(mSurface, blur)
.setOpaque(mSurface, opaque)
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index d15113184d..c2c721adf8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -26,6 +26,7 @@ import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.RemoteViews;
+import android.window.SplashScreen;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogManager;
@@ -56,7 +57,7 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
}
Pair options = remoteResponse.getLaunchOptions(view);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
- .getActivityLaunchOptions(mLauncher, hostView);
+ .getActivityLaunchOptions(hostView);
if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) {
// In the event this pending intent eventually launches an activity, i.e. a trampoline,
// use the Quickstep transition animation.
@@ -70,6 +71,7 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
}
}
activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
Object itemInfo = hostView.getTag();
if (itemInfo instanceof ItemInfo) {
mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 3d66823c98..fa5ab1cb7b 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -49,9 +49,8 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAnimationRunner;
import com.android.launcher3.LauncherAnimationRunner.AnimationResult;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
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;
@@ -109,7 +108,7 @@ public final class RecentsActivity extends StatefulActivity {
private StateManager mStateManager;
// Strong refs to runners which are cleared when the activity is destroyed
- private WrappedAnimationRunnerImpl mActivityLaunchAnimationRunner;
+ private RemoteAnimationFactory mActivityLaunchAnimationRunner;
/**
* Init drag layer and overview panel views.
@@ -206,19 +205,25 @@ public final class RecentsActivity extends StatefulActivity {
final TaskView taskView = (TaskView) v;
RunnableList onEndCallback = new RunnableList();
- mActivityLaunchAnimationRunner = (int transit,
- RemoteAnimationTargetCompat[] appTargets,
+ mActivityLaunchAnimationRunner = new RemoteAnimationFactory() {
+ @Override
+ public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets,
- AnimationResult result) -> {
- AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
- wallpaperTargets, nonAppTargets);
- anim.addListener(resetStateListener());
- result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy,
- true /* skipFirstFrame */);
+ RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) {
+ AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
+ wallpaperTargets, nonAppTargets);
+ anim.addListener(resetStateListener());
+ result.setAnimation(anim, RecentsActivity.this, onEndCallback::executeAllAndDestroy,
+ true /* skipFirstFrame */);
+ }
+
+ @Override
+ public void onAnimationCancelled() {
+ onEndCallback.executeAllAndDestroy();
+ }
};
- final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner<>(
+ final LauncherAnimationRunner wrapper = new LauncherAnimationRunner(
mUiHandler, mActivityLaunchAnimationRunner, true /* startAtFrontOfQueue */);
RemoteAnimationAdapterCompat adapterCompat = new RemoteAnimationAdapterCompat(
wrapper, RECENTS_LAUNCH_DURATION,
@@ -263,6 +268,7 @@ public final class RecentsActivity extends StatefulActivity {
// onActivityStart callback.
mFallbackRecentsView.setContentAlpha(1);
super.onStart();
+ mFallbackRecentsView.updateLocusId();
}
@Override
@@ -271,6 +277,7 @@ public final class RecentsActivity extends StatefulActivity {
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
+ mFallbackRecentsView.updateLocusId();
}
@Override
@@ -362,34 +369,37 @@ public final class RecentsActivity extends StatefulActivity {
}
private void startHomeInternal() {
- WrappedLauncherAnimationRunner runner = new WrappedLauncherAnimationRunner(
- getMainThreadHandler(), this::onCreateAnimationToHome, true);
+ LauncherAnimationRunner runner = new LauncherAnimationRunner(
+ getMainThreadHandler(), mAnimationToHomeFactory, 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();
+ private final RemoteAnimationFactory mAnimationToHomeFactory =
+ new RemoteAnimationFactory() {
+ @Override
+ public void onCreateAnimation(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();
+ 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, RecentsActivity.this,
+ () -> getStateManager().goToState(RecentsState.HOME, false),
+ true /* skipFirstFrame */);
}
- AnimatorSet anim = new AnimatorSet();
- anim.play(controller.getAnimationPlayer());
- anim.setDuration(HOME_APPEAR_DURATION);
- result.setAnimation(anim, this,
- () -> getStateManager().goToState(RecentsState.HOME, false),
- true /* skipFirstFrame */);
- }
+ };
@Override
protected void collectStateHandlers(List out) {
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 32f4c58d7f..9b6afd6a97 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -29,12 +29,8 @@ public class BackGestureTutorialFragment extends TutorialFragment {
@Override
Integer getFeedbackVideoResId(boolean forDarkMode) {
return mTutorialType == TutorialType.RIGHT_EDGE_BACK_NAVIGATION
- ? (forDarkMode
- ? R.drawable.gesture_tutorial_motion_back_right_dark_mode
- : R.drawable.gesture_tutorial_motion_back_right_light_mode)
- : (forDarkMode
- ? R.drawable.gesture_tutorial_motion_back_left_dark_mode
- : R.drawable.gesture_tutorial_motion_back_left_light_mode);
+ ? R.drawable.gesture_tutorial_motion_back_right
+ : R.drawable.gesture_tutorial_motion_back_left;
}
@Nullable
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 719cb0a032..b1c9ed0361 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -151,6 +151,7 @@ public class StatsLogCompatManager extends StatsLogManager {
private Optional mToState = Optional.empty();
private Optional mEditText = Optional.empty();
private SliceItem mSliceItem;
+ private LauncherAtom.Slice mSlice;
StatsCompatLogger(Context context) {
mContext = context;
@@ -193,7 +194,7 @@ public class StatsLogCompatManager extends StatsLogManager {
@Override
public StatsLogger withContainerInfo(ContainerInfo containerInfo) {
checkState(mItemInfo == DEFAULT_ITEM_INFO,
- "ItemInfo and ContainerInfo are mutual exclusive; cannot log both.");
+ "ItemInfo and ContainerInfo are mutual exclusive; cannot log both.");
this.mContainerInfo = Optional.of(containerInfo);
return this;
}
@@ -218,9 +219,21 @@ public class StatsLogCompatManager extends StatsLogManager {
@Override
public StatsLogger withSliceItem(@NonNull SliceItem sliceItem) {
+ checkState(mItemInfo == DEFAULT_ITEM_INFO && mSlice == null,
+ "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one"
+ + " of them.");
this.mSliceItem = checkNotNull(sliceItem, "expected valid sliceItem but received null");
- checkState(mItemInfo == DEFAULT_ITEM_INFO,
- "ItemInfo and SliceItem are mutual exclusive; cannot log both.");
+ return this;
+ }
+
+ @Override
+ public StatsLogger withSlice(LauncherAtom.Slice slice) {
+ checkState(mItemInfo == DEFAULT_ITEM_INFO && mSliceItem == null,
+ "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one"
+ + " of them.");
+ checkNotNull(slice, "expected valid slice but received null");
+ checkNotNull(slice.getUri(), "expected valid slice uri but received null");
+ this.mSlice = slice;
return this;
}
@@ -231,13 +244,16 @@ public class StatsLogCompatManager extends StatsLogManager {
}
LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
- if (mSliceItem != null) {
+ if (mSlice == null && mSliceItem != null) {
+ mSlice = LauncherAtom.Slice.newBuilder().setUri(
+ mSliceItem.getSlice().getUri().toString()).build();
+ }
+
+ if (mSlice != null) {
Executors.MODEL_EXECUTOR.execute(
() -> {
LauncherAtom.ItemInfo.Builder itemInfoBuilder =
- LauncherAtom.ItemInfo.newBuilder().setSlice(
- LauncherAtom.Slice.newBuilder().setUri(
- mSliceItem.getSlice().getUri().toString()));
+ LauncherAtom.ItemInfo.newBuilder().setSlice(mSlice);
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
write(event, applyOverwrites(itemInfoBuilder.build()));
});
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index 5c6da1611f..98dbd47ba4 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -21,15 +21,14 @@ import android.content.Context;
import android.os.Handler;
import com.android.launcher3.LauncherAnimationRunner;
-import com.android.launcher3.WrappedAnimationRunnerImpl;
-import com.android.launcher3.WrappedLauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
public abstract class RemoteAnimationProvider {
- WrappedAnimationRunnerImpl mAnimationRunner;
+ RemoteAnimationFactory mAnimationRunner;
public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets);
@@ -37,7 +36,7 @@ public abstract class RemoteAnimationProvider {
ActivityOptions toActivityOptions(Handler handler, long duration, Context context) {
mAnimationRunner = (transit, appTargets, wallpaperTargets, nonApps, result) ->
result.setAnimation(createWindowAnimation(appTargets, wallpaperTargets), context);
- final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner(
+ final LauncherAnimationRunner wrapper = new LauncherAnimationRunner(
handler, mAnimationRunner, false /* startAtFrontOfQueue */);
return ActivityOptionsCompat.makeRemoteAnimation(
new RemoteAnimationAdapterCompat(wrapper, duration, 0));
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 3d33e57a36..a147b6808c 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -41,9 +41,8 @@ import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
import com.android.launcher3.R;
-import com.android.launcher3.WrappedAnimationRunnerImpl;
-import com.android.launcher3.WrappedLauncherAnimationRunner;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
@@ -101,14 +100,14 @@ public class SplitSelectStateController {
return;
}
// Assume initial mInitialTaskId is for top/left part of screen
- WrappedAnimationRunnerImpl initialSplitRunnerWrapped = new SplitLaunchAnimationRunner(
+ RemoteAnimationFactory initialSplitRunnerWrapped = new SplitLaunchAnimationRunner(
mInitialTaskView, 0);
- WrappedAnimationRunnerImpl secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner(
+ RemoteAnimationFactory secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner(
taskView, 1);
- RemoteAnimationRunnerCompat initialSplitRunner = new WrappedLauncherAnimationRunner(
+ RemoteAnimationRunnerCompat initialSplitRunner = new LauncherAnimationRunner(
new Handler(Looper.getMainLooper()), initialSplitRunnerWrapped,
true /* startAtFrontOfQueue */);
- RemoteAnimationRunnerCompat secondarySplitRunner = new WrappedLauncherAnimationRunner(
+ RemoteAnimationRunnerCompat secondarySplitRunner = new LauncherAnimationRunner(
new Handler(Looper.getMainLooper()), secondarySplitRunnerWrapped,
true /* startAtFrontOfQueue */);
ActivityOptions initialOptions = ActivityOptionsCompat.makeRemoteAnimation(
@@ -192,7 +191,7 @@ public class SplitSelectStateController {
* LEGACY
* Remote animation runner for animation to launch an app.
*/
- private class SplitLaunchAnimationRunner implements WrappedAnimationRunnerImpl {
+ private class SplitLaunchAnimationRunner implements RemoteAnimationFactory {
private final TaskView mV;
private final int mTargetState;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 4332c76648..9c207891ac 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -62,6 +62,7 @@ import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
+import android.content.LocusId;
import android.content.res.Configuration;
import android.graphics.BlendMode;
import android.graphics.Canvas;
@@ -74,6 +75,7 @@ import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.os.Bundle;
import android.os.UserHandle;
import android.text.Layout;
import android.text.StaticLayout;
@@ -883,7 +885,7 @@ public abstract class RecentsView {
- UI_HELPER_EXECUTOR.getHandler().postDelayed(() ->
- ActivityManagerWrapper.getInstance().removeTask(
- dismissedTaskId), REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
- });
+ if (LIVE_TILE.get() && dismissedTaskView.isRunningTask()) {
+ finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
+ () -> removeTaskInternal(dismissedTaskId));
+ } else {
+ removeTaskInternal(dismissedTaskId);
+ }
mActivity.getStatsLogManager().logger()
.withItemInfo(dismissedTaskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
@@ -2472,6 +2475,12 @@ public abstract class RecentsView ActivityManagerWrapper.getInstance().removeTask(dismissedTaskId),
+ REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
+ }
+
/**
* @return {@code true} if one of the task thumbnails would intersect/overlap with the
* {@link #mSplitPlaceholderView}
@@ -3923,4 +3932,19 @@ public abstract class RecentsView mActivity.setLocusContext(id, Bundle.EMPTY));
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 8b6410508f..57cc79c8e4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -545,7 +545,13 @@ public class TaskView extends FrameLayout implements Reusable {
mIsClickableAsLiveTile = false;
RecentsView recentsView = getRecentsView();
- RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet();
+ final RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet();
+ if (targets == null) {
+ // If the recents animation is cancelled somehow between the parent if block and
+ // here, try to launch the task as a non live tile task.
+ launcherNonLiveTileTask();
+ return;
+ }
AnimatorSet anim = new AnimatorSet();
TaskViewUtils.composeRecentsLaunchAnimator(
@@ -567,17 +573,21 @@ public class TaskView extends FrameLayout implements Reusable {
});
anim.start();
} else {
- if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
- // User tapped to select second split screen app
- getRecentsView().confirmSplitSelect(this);
- } else {
- launchTaskAnimated();
- }
+ launcherNonLiveTileTask();
}
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
.log(LAUNCHER_TASK_LAUNCH_TAP);
}
+ private void launcherNonLiveTileTask() {
+ if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
+ // User tapped to select second split screen app
+ getRecentsView().confirmSplitSelect(this);
+ } else {
+ launchTaskAnimated();
+ }
+ }
+
/**
* Starts the task associated with this view and animates the startup.
* @return CompletionStage to indicate the animation completion or null if the launch failed.
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 9630d274df..a683d01f6c 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -107,7 +107,7 @@ public class FallbackRecentsTest {
mOrderSensitiveRules = RuleChain
.outerRule(new NavigationModeSwitchRule(mLauncher))
- .around(new FailureWatcher(mDevice));
+ .around(new FailureWatcher(mDevice, mLauncher));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
getHomeIntentInPackage(context),
diff --git a/res/color-night-v31/folder_background_dark.xml b/res/color-night-v31/folder_background_dark.xml
new file mode 100644
index 0000000000..a5bd6367d5
--- /dev/null
+++ b/res/color-night-v31/folder_background_dark.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-night-v31/popup_color_first.xml b/res/color-night-v31/popup_color_first.xml
new file mode 100644
index 0000000000..ba7412859c
--- /dev/null
+++ b/res/color-night-v31/popup_color_first.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-night-v31/popup_color_second.xml b/res/color-night-v31/popup_color_second.xml
new file mode 100644
index 0000000000..efc620532a
--- /dev/null
+++ b/res/color-night-v31/popup_color_second.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-night-v31/popup_color_third.xml b/res/color-night-v31/popup_color_third.xml
new file mode 100644
index 0000000000..591c7ede34
--- /dev/null
+++ b/res/color-night-v31/popup_color_third.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-v31/folder_background_light.xml b/res/color-v31/folder_background_light.xml
new file mode 100644
index 0000000000..e3c7e7dab1
--- /dev/null
+++ b/res/color-v31/folder_background_light.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-v31/popup_color_first.xml b/res/color-v31/popup_color_first.xml
new file mode 100644
index 0000000000..28d9155f5e
--- /dev/null
+++ b/res/color-v31/popup_color_first.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-v31/popup_color_second.xml b/res/color-v31/popup_color_second.xml
new file mode 100644
index 0000000000..dec562c046
--- /dev/null
+++ b/res/color-v31/popup_color_second.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color-v31/popup_color_third.xml b/res/color-v31/popup_color_third.xml
new file mode 100644
index 0000000000..582232c536
--- /dev/null
+++ b/res/color-v31/popup_color_third.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/res/color/popup_color_first.xml b/res/color/popup_color_first.xml
new file mode 100644
index 0000000000..d9999a20c8
--- /dev/null
+++ b/res/color/popup_color_first.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/res/color/popup_color_second.xml b/res/color/popup_color_second.xml
new file mode 100644
index 0000000000..d9999a20c8
--- /dev/null
+++ b/res/color/popup_color_second.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/res/color/popup_color_third.xml b/res/color/popup_color_third.xml
new file mode 100644
index 0000000000..d7e9e794e2
--- /dev/null
+++ b/res/color/popup_color_third.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/work_apps_toggle_background.xml b/res/drawable/work_apps_toggle_background.xml
index b7115f86b5..a47c8fef7c 100644
--- a/res/drawable/work_apps_toggle_background.xml
+++ b/res/drawable/work_apps_toggle_background.xml
@@ -18,14 +18,18 @@
-
+
-
-
+
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index dca3e79c62..1b4f3b984e 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -33,6 +33,8 @@
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
+ android:fontFamily="sans-serif-medium"
+ android:textSize="20sp"
tools:text="No widgets available" />
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 97feb23745..919f1b27cf 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -42,7 +42,7 @@