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 e1ff4f4525..aaf7619dc6 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 @@ import com.android.systemui.shared.system.TransactionCompat; * * @param activity that contains the overview */ -final class AppToOverviewAnimationProvider implements +final class AppToOverviewAnimationProvider 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 fc50660c9c..c6b719a114 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.appprediction.PredictionUiStateManager; 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 @@ public class OverviewCommandHelper { // 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 809543ac98..a7d00c5c72 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; 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 abstract class BaseQuickstepLauncher extends Launcher 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 31c1acf771..2cb23f1599 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.RemoteAnimationRunnerCompat; 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 @@ public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCo 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 96340b22e6..fbd7a8a4b6 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 android.os.Handler; 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 @@ public class LauncherInitListener extends ActivityInitListener { // 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 6d4583032c..b9bd6b1d54 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -87,8 +87,6 @@ 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. Not used for 3p launchers. @@ -804,52 +802,6 @@ 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. */ diff --git a/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java b/quickstep/src/com/android/launcher3/WrappedAnimationRunnerImpl.java new file mode 100644 index 0000000000..da2aee4386 --- /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 0000000000..1753b62ca3 --- /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 + 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); + } + } +} diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java index 6520c4f091..21b97ecc7f 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.content.Context; 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 @@ public interface RemoteAnimationProvider { 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 @@ public interface RemoteAnimationProvider { } } - 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 @@ public interface RemoteAnimationProvider { /** * @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;