From 24ab40cebe9bdd84593f0dfd7826e94c75679495 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 30 Oct 2019 22:35:09 -0700 Subject: [PATCH] Move remote animation definition runner to wrapped class - Add call to unregister for remote animations from the system when the launcher activity is destroyed to prevent a lingering reference from the system to the old activity. But separately, to not have to wait for the system to GC before clearing the binder ref, we also wrap all runner implementations so that they can be cleaned up after a GC in our process only. Bug: 139137636 Change-Id: Ib6276cac80b446440ec101fe00eae6ca41fdf32c --- .../QuickstepAppTransitionManagerImpl.java | 98 ++++++++++++++++--- src/com/android/launcher3/BaseActivity.java | 2 +- src/com/android/launcher3/Launcher.java | 2 + .../LauncherAppTransitionManager.java | 14 +++ 4 files changed, 102 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index d4db05a6c6..1e01709d60 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -69,9 +69,9 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.views.FloatingIconView; +import com.android.quickstep.RemoteAnimationTargets; import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.RemoteAnimationProvider; -import com.android.quickstep.RemoteAnimationTargets; import com.android.systemui.shared.system.ActivityCompat; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.QuickStepContract; @@ -83,6 +83,8 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; 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. @@ -149,6 +151,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans private DeviceProfile mDeviceProfile; private RemoteAnimationProvider mRemoteAnimationProvider; + private WrappedAnimationRunnerImpl mWallpaperOpenRunner; private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() { @Override @@ -176,7 +179,6 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y); mLauncher.addOnDeviceProfileChangeListener(this); - registerRemoteAnimations(); } @Override @@ -598,18 +600,36 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans /** * Registers remote animations used when closing apps to home screen. */ - private void registerRemoteAnimations() { - // Unregister this + @Override + public void registerRemoteAnimations() { if (hasControlRemoteAppTransitionPermission()) { + mWallpaperOpenRunner = createWallpaperOpenRunner(false /* fromUnlock */); + RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat(); definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN, WindowManagerWrapper.ACTIVITY_TYPE_STANDARD, - new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(false /* fromUnlock */), + new RemoteAnimationAdapterCompat( + new WrappedLauncherAnimationRunner<>(mWallpaperOpenRunner, + false /* startAtFrontOfQueue */), CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */)); new ActivityCompat(mLauncher).registerRemoteAnimations(definition); } } + /** + * Unregisters all remote animations. + */ + @Override + public void unregisterRemoteAnimations() { + if (hasControlRemoteAppTransitionPermission()) { + new ActivityCompat(mLauncher).unregisterRemoteAnimations(); + + // Also clear strong references to the runners registered with the remote animation + // definition so we don't have to wait for the system gc + mWallpaperOpenRunner = null; + } + } + private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) { return taskIsATargetWithMode(targets, mLauncher.getTaskId(), mode); } @@ -618,9 +638,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans * @return Runner that plays when user goes to Launcher * ie. pressing home, swiping up from nav bar. */ - RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) { - return new WallpaperOpenLauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */, - fromUnlock); + WrappedAnimationRunnerImpl createWallpaperOpenRunner(boolean fromUnlock) { + return new WallpaperOpenLauncherAnimationRunner(mHandler, fromUnlock); } /** @@ -701,7 +720,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans } /** - * Creates an animator that modifies Launcher as a result from {@link #getWallpaperOpenRunner}. + * Creates an animator that modifies Launcher as a result from + * {@link #createWallpaperOpenRunner}. */ private void createLauncherResumeAnimation(AnimatorSet anim) { if (mLauncher.isInState(LauncherState.ALL_APPS)) { @@ -760,18 +780,70 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans == PackageManager.PERMISSION_GRANTED; } + /** + * 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 + extends LauncherAnimationRunner { + private WeakReference 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. */ - class WallpaperOpenLauncherAnimationRunner extends LauncherAnimationRunner { + protected class WallpaperOpenLauncherAnimationRunner implements WrappedAnimationRunnerImpl { + + private final Handler mHandler; private final boolean mFromUnlock; - public WallpaperOpenLauncherAnimationRunner(Handler handler, boolean startAtFrontOfQueue, - boolean fromUnlock) { - super(handler, startAtFrontOfQueue); + public WallpaperOpenLauncherAnimationRunner(Handler handler, boolean fromUnlock) { + mHandler = handler; mFromUnlock = fromUnlock; } + @Override + public Handler getHandler() { + return mHandler; + } + @Override public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index ea63fa7ada..3ca4f5989d 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -286,7 +286,7 @@ public abstract class BaseActivity extends Activity /** * Used to set the override visibility state, used only to handle the transition home with the * recents animation. - * @see QuickstepAppTransitionManagerImpl#getWallpaperOpenRunner + * @see QuickstepAppTransitionManagerImpl#createWallpaperOpenRunner */ public void addForceInvisibleFlag(@InvisibilityFlags int flag) { mForceInvisible |= flag; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index f5fafbfcd6..8066d383d1 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -373,6 +373,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mPopupDataProvider = new PopupDataProvider(this); mAppTransitionManager = LauncherAppTransitionManager.newInstance(this); + mAppTransitionManager.registerRemoteAnimations(); boolean internalStateHandled = ACTIVITY_TRACKER.handleCreate(this); if (internalStateHandled) { @@ -1545,6 +1546,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, LauncherAppState.getIDP(this).removeOnChangeListener(this); mOverlayManager.onActivityDestroyed(this); + mAppTransitionManager.unregisterRemoteAnimations(); } public LauncherAccessibilityDelegate getAccessibilityDelegate() { diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java index c55c120a62..9148c2f0d5 100644 --- a/src/com/android/launcher3/LauncherAppTransitionManager.java +++ b/src/com/android/launcher3/LauncherAppTransitionManager.java @@ -67,4 +67,18 @@ public class LauncherAppTransitionManager implements ResourceBasedOverride { public Animator createStateElementAnimation(int index, float... values) { throw new RuntimeException("Unknown gesture animation " + index); } + + /** + * Registers remote animations for certain system transitions. + */ + public void registerRemoteAnimations() { + // Do nothing + } + + /** + * Unregisters all remote animations. + */ + public void unregisterRemoteAnimations() { + // Do nothing + } }