Fixing TaskView.launchTask.onEndCallback is not called

Sometimes onAnimaitonCancelled can be called without onCreate. Calling
onEnd in this case so that the sate is cleared

Removing additional subclassing for the runner

Bug: 190856140
Test: Manual
Change-Id: If105cb343cab446a4eac90a45184ce50c6e4c485
This commit is contained in:
Sunny Goyal
2021-06-18 17:42:18 -07:00
parent 871d435be2
commit 696c612964
9 changed files with 134 additions and 182 deletions

View File

@@ -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<RemoteAnimationFactory> 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() { }
}
}