Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14bfb89c authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Fix race of releasing leashes with shell recents transition

The code flow:
RecentsAnimationController#finishController
 mOnFinishedListener.accept(this);
  RecentsAnimationCallbacks#onAnimationFinished
   *Post to "main" thread
    RecentsAnimationListener#onRecentsAnimationFinished
     TaskAnimationManager#cleanUpRecentsAnimation
      Invoke SurfaceControl#release
 *Post to "UiThreadHelper" thread
  RemoteTransitionCompat.RecentsControllerWrap#finish
   Invoke SurfaceControl.Transaction#remove
   on the same SurfaceControl.

Then it may be either NullPointerException from
SurfaceControl#checkNotReleased. Or rarely native crash by
changing the surface control from 2 threads at the same time.

Bug: 238192072
Bug: 238047903
Bug: 237631001
Bug: 237497909
Bug: 235616350
Test: Loop launch app and swipe to home.

Change-Id: I7e4ce2c273b8396ed464eb48426fd4435d6c5338
parent d69caeee
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -427,18 +427,14 @@ public class RemoteTransitionCompat implements Parcelable {
                    mPipTransaction = null;
                }
            }
            // Release surface references now. This is apparently to free GPU
            // memory while doing quick operations (eg. during CTS).
            for (int i = 0; i < mLeashMap.size(); ++i) {
                if (mLeashMap.keyAt(i) == mLeashMap.valueAt(i)) continue;
                t.remove(mLeashMap.valueAt(i));
            }
            try {
                mFinishCB.onTransitionFinished(wct.isEmpty() ? null : wct, t);
            } catch (RemoteException e) {
                Log.e("RemoteTransitionCompat", "Failed to call animation finish callback", e);
                t.apply();
            }
            // Only release the non-local created surface references. The animator is responsible
            // for releasing the leashes created by local.
            for (int i = 0; i < mInfo.getChanges().size(); ++i) {
                mInfo.getChanges().get(i).getLeash().release();
            }