Merge "Improve the release of predict_back animaton leash" into main
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 4988a94..851472f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -25,6 +25,7 @@
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
import android.window.IBackAnimationRunner;
import android.window.IOnBackInvokedCallback;
@@ -32,6 +33,8 @@
import com.android.internal.jank.Cuj.CujType;
import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import java.lang.ref.WeakReference;
+
/**
* Used to register the animation callback and runner, it will trigger result if gesture was finish
* before it received IBackAnimationRunner#onAnimationStart, so the controller could continue
@@ -80,22 +83,49 @@
return mCallback;
}
+ private Runnable mFinishedCallback;
+ private RemoteAnimationTarget[] mApps;
+ private IRemoteAnimationFinishedCallback mRemoteCallback;
+
+ private static class RemoteAnimationFinishedStub extends IRemoteAnimationFinishedCallback.Stub {
+ //the binder callback should not hold strong reference to it to avoid memory leak.
+ private WeakReference<BackAnimationRunner> mRunnerRef;
+
+ private RemoteAnimationFinishedStub(BackAnimationRunner runner) {
+ mRunnerRef = new WeakReference<>(runner);
+ }
+
+ @Override
+ public void onAnimationFinished() {
+ BackAnimationRunner runner = mRunnerRef.get();
+ if (runner == null) {
+ return;
+ }
+ if (runner.shouldMonitorCUJ(runner.mApps)) {
+ InteractionJankMonitorUtils.endTracing(runner.mCujType);
+ }
+
+ runner.mFinishedCallback.run();
+ for (int i = runner.mApps.length - 1; i >= 0; --i) {
+ SurfaceControl sc = runner.mApps[i].leash;
+ if (sc != null && sc.isValid()) {
+ sc.release();
+ }
+ }
+ runner.mApps = null;
+ runner.mFinishedCallback = null;
+ }
+ }
+
/**
* Called from {@link IBackAnimationRunner}, it will deliver these
* {@link RemoteAnimationTarget}s to the corresponding runner.
*/
void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
- final IRemoteAnimationFinishedCallback callback =
- new IRemoteAnimationFinishedCallback.Stub() {
- @Override
- public void onAnimationFinished() {
- if (shouldMonitorCUJ(apps)) {
- InteractionJankMonitorUtils.endTracing(mCujType);
- }
- finishedCallback.run();
- }
- };
+ mFinishedCallback = finishedCallback;
+ mApps = apps;
+ if (mRemoteCallback == null) mRemoteCallback = new RemoteAnimationFinishedStub(this);
mWaitingAnimation = false;
if (shouldMonitorCUJ(apps)) {
InteractionJankMonitorUtils.beginTracing(
@@ -103,7 +133,7 @@
}
try {
getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
- nonApps, callback);
+ nonApps, mRemoteCallback);
} catch (RemoteException e) {
Log.w(TAG, "Failed call onAnimationStart", e);
}