Fixing LauncherAnimationRunning referring a destroyed activity
Bug: 139137636
Change-Id: Id070a98103a7116179e7ee66fabeeb33fb19b1ff
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index e1ff4f4..aaf7619 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -48,7 +48,7 @@
*
* @param <T> activity that contains the overview
*/
-final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> implements
+final class AppToOverviewAnimationProvider<T extends BaseDraggingActivity> extends
RemoteAnimationProvider {
private static final long RECENTS_LAUNCH_DURATION = 250;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
index fc50660..c6b719a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewCommandHelper.java
@@ -33,6 +33,7 @@
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -187,7 +188,15 @@
// Otherwise, start overview.
mListener = mActivityInterface.createActivityInitListener(this::onActivityReady);
mListener.registerAndStartActivity(mOverviewComponentObserver.getOverviewIntent(),
- this::createWindowAnimation, mContext, MAIN_EXECUTOR.getHandler(),
+ new RemoteAnimationProvider() {
+ @Override
+ public AnimatorSet createWindowAnimation(
+ RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets) {
+ return RecentsActivityCommand.this.createWindowAnimation(appTargets,
+ wallpaperTargets);
+ }
+ }, mContext, MAIN_EXECUTOR.getHandler(),
mAnimationProvider.getRecentsLaunchDuration());
}
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 809543a..a7d00c5 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -52,10 +52,12 @@
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.util.ShelfPeekAnim;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.stream.Stream;
@@ -262,17 +264,21 @@
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
QuickstepAppTransitionManagerImpl appTransitionManager =
(QuickstepAppTransitionManagerImpl) getAppTransitionManager();
- appTransitionManager.setRemoteAnimationProvider((appTargets, wallpaperTargets) -> {
+ appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
+ @Override
+ public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets) {
- // On the first call clear the reference.
- signal.cancel();
+ // On the first call clear the reference.
+ signal.cancel();
- ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
- fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
- wallpaperTargets));
- AnimatorSet anim = new AnimatorSet();
- anim.play(fadeAnimation);
- return anim;
+ ValueAnimator fadeAnimation = ValueAnimator.ofFloat(1, 0);
+ fadeAnimation.addUpdateListener(new RemoteFadeOutAnimationListener(appTargets,
+ wallpaperTargets));
+ AnimatorSet anim = new AnimatorSet();
+ anim.play(fadeAnimation);
+ return anim;
+ }
}, signal);
}
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 31c1acf..2cb23f1 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -34,7 +34,8 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@TargetApi(Build.VERSION_CODES.P)
-public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
+public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat,
+ WrappedAnimationRunnerImpl {
private final Handler mHandler;
private final boolean mStartAtFrontOfQueue;
@@ -49,6 +50,10 @@
mStartAtFrontOfQueue = startAtFrontOfQueue;
}
+ public Handler getHandler() {
+ return mHandler;
+ }
+
// Called only in R+ platform
@BinderThread
public void onAnimationStart(RemoteAnimationTargetCompat[] appTargets,
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index 96340b2..fbd7a8a 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3;
+import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
@@ -25,6 +26,7 @@
import com.android.launcher3.util.ActivityTracker;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.BiPredicate;
@@ -51,17 +53,21 @@
// Set a one-time animation provider. After the first call, this will get cleared.
// TODO: Probably also check the intended target id.
CancellationSignal cancellationSignal = new CancellationSignal();
- appTransitionManager.setRemoteAnimationProvider((appTargets, wallpaperTargets) -> {
+ appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() {
+ @Override
+ public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets) {
- // On the first call clear the reference.
- cancellationSignal.cancel();
- RemoteAnimationProvider provider = mRemoteAnimationProvider;
- mRemoteAnimationProvider = null;
+ // On the first call clear the reference.
+ cancellationSignal.cancel();
+ RemoteAnimationProvider provider = mRemoteAnimationProvider;
+ mRemoteAnimationProvider = null;
- if (provider != null && launcher.getStateManager().getState().overviewUi) {
- return provider.createWindowAnimation(appTargets, wallpaperTargets);
+ if (provider != null && launcher.getStateManager().getState().overviewUi) {
+ return provider.createWindowAnimation(appTargets, wallpaperTargets);
+ }
+ return null;
}
- return null;
}, cancellationSignal);
}
launcher.deferOverlayCallbacksUntilNextResumeOrStop();
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index f691359..8d4e727 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -86,8 +86,6 @@
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.lang.ref.WeakReference;
-
/**
* {@link LauncherAppTransitionManager} with Quickstep-specific app transitions for launching from
* home and/or all-apps. Not used for 3p launchers.
@@ -785,52 +783,6 @@
}
/**
- * Used with WrappedLauncherAnimationRunner as an interface for the runner to call back to the
- * implementation.
- */
- protected interface WrappedAnimationRunnerImpl {
- Handler getHandler();
- void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- LauncherAnimationRunner.AnimationResult result);
- }
-
- /**
- * 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.
- */
- protected static class WrappedLauncherAnimationRunner<R extends WrappedAnimationRunnerImpl>
- extends LauncherAnimationRunner {
- private WeakReference<R> mImpl;
-
- public WrappedLauncherAnimationRunner(R animationRunnerImpl, boolean startAtFrontOfQueue) {
- super(animationRunnerImpl.getHandler(), startAtFrontOfQueue);
- mImpl = new WeakReference<>(animationRunnerImpl);
- }
-
- @Override
- public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) {
- R animationRunnerImpl = mImpl.get();
- if (animationRunnerImpl != null) {
- animationRunnerImpl.onCreateAnimation(appTargets, wallpaperTargets, result);
- }
- }
- }
-
- /**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
protected class WallpaperOpenLauncherAnimationRunner implements WrappedAnimationRunnerImpl {
diff --git a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java b/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java
new file mode 100644
index 0000000..da2aee4
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Used with WrappedLauncherAnimationRunner as an interface for the runner to call back to the
+ * implementation.
+ */
+public interface WrappedAnimationRunnerImpl {
+ Handler getHandler();
+ void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ LauncherAnimationRunner.AnimationResult result);
+}
diff --git a/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java
new file mode 100644
index 0000000..1753b62
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/WrappedLauncherAnimationRunner.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+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<R extends WrappedAnimationRunnerImpl>
+ extends LauncherAnimationRunner {
+ private WeakReference<R> mImpl;
+
+ public WrappedLauncherAnimationRunner(R animationRunnerImpl, boolean startAtFrontOfQueue) {
+ super(animationRunnerImpl.getHandler(), startAtFrontOfQueue);
+ mImpl = new WeakReference<>(animationRunnerImpl);
+ }
+
+ @Override
+ public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets, AnimationResult result) {
+ R animationRunnerImpl = mImpl.get();
+ if (animationRunnerImpl != null) {
+ animationRunnerImpl.onCreateAnimation(appTargets, wallpaperTargets, result);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index 6520c4f..21b97ec 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -21,21 +21,22 @@
import android.os.Handler;
import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.WrappedLauncherAnimationRunner;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.TransactionCompat;
-@FunctionalInterface
-public interface RemoteAnimationProvider {
+public abstract class RemoteAnimationProvider {
+ LauncherAnimationRunner mAnimationRunner;
static final int Z_BOOST_BASE = 800570000;
- AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
+ public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets);
- default ActivityOptions toActivityOptions(Handler handler, long duration, Context context) {
- LauncherAnimationRunner runner = new LauncherAnimationRunner(handler,
+ ActivityOptions toActivityOptions(Handler handler, long duration, Context context) {
+ mAnimationRunner = new LauncherAnimationRunner(handler,
false /* startAtFrontOfQueue */) {
@Override
@@ -44,8 +45,11 @@
result.setAnimation(createWindowAnimation(appTargets, wallpaperTargets), context);
}
};
+ final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner(
+ mAnimationRunner, false /* startAtFrontOfQueue */);
+
return ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(runner, duration, 0));
+ new RemoteAnimationAdapterCompat(wrapper, duration, 0));
}
/**
@@ -63,7 +67,7 @@
}
}
- static int getLayer(RemoteAnimationTargetCompat target, int boostModeTarget) {
+ public static int getLayer(RemoteAnimationTargetCompat target, int boostModeTarget) {
return target.mode == boostModeTarget
? Z_BOOST_BASE + target.prefixOrderIndex
: target.prefixOrderIndex;
@@ -72,7 +76,7 @@
/**
* @return the target with the lowest opaque layer for a certain app animation, or null.
*/
- static RemoteAnimationTargetCompat findLowestOpaqueLayerTarget(
+ public static RemoteAnimationTargetCompat findLowestOpaqueLayerTarget(
RemoteAnimationTargetCompat[] appTargets, int mode) {
int lowestLayer = Integer.MAX_VALUE;
int lowestLayerIndex = -1;