Improve the release of predict_back animaton leash
Seems the predict_back nimation leash cant be released in time after
gesture animation already finsihed, and it will keep for long time it
may cause SurfaceFlinger memory loading high and layer count too much.
Flag: EXEMPT bugfix
Bug: 370247136
Test: repeatly open settings and gesture predict back to home launcher
(cherry picked from https://partner-android-review.googlesource.com/q/commit:7c1a0cf0be835656dbc9897535b5ee55ba1ea33f)
Merged-In: I51845842decf47a79da755418c61a227eae6474a
Change-Id: I51845842decf47a79da755418c61a227eae6474a
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);
}