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

Commit e2777eaf authored by Aurélien Pomini's avatar Aurélien Pomini
Browse files

Fix wallpaper dim race condition

The updateListener from updateWallpaperDimming is always run on the UI
thread. The other methods of the engine (here detach()) may run on
another thread if onProvideEngineLooper is overriden, which is the case
for ImageWallpaper.

This can cause a crash if the detach() is called while the wallpaper dim
animation is running. To avoid this, we add a small lock for both the
surface release operations and the wallpaper dim update.

Flag: EXEMPT bugfix
Bug: 386999490
Test: presubmit
Change-Id: I01d014996b0a2df65e17867d1629a211f37f5322
parent f1610eff
Loading
Loading
Loading
Loading
+35 −28
Original line number Diff line number Diff line
@@ -325,6 +325,7 @@ public abstract class WallpaperService extends Service {
        IWindowSession mSession;

        final Object mLock = new Object();
        private final Object mSurfaceReleaseLock = new Object();
        boolean mOffsetMessageEnqueued;

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -1075,10 +1076,12 @@ public abstract class WallpaperService extends Service {
                animator.setDuration(DIMMING_ANIMATION_DURATION_MS);
                animator.addUpdateListener((ValueAnimator va) -> {
                    final float dimValue = (float) va.getAnimatedValue();
                    if (mBbqSurfaceControl != null) {
                    synchronized (mSurfaceReleaseLock) {
                        if (mBbqSurfaceControl != null && mBbqSurfaceControl.isValid()) {
                            surfaceControlTransaction
                                    .setAlpha(mBbqSurfaceControl, 1 - dimValue).apply();
                        }
                    }
                });
                animator.addListener(new AnimatorListenerAdapter() {
                    @Override
@@ -2356,10 +2359,13 @@ public abstract class WallpaperService extends Service {
            if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
            onDestroy();

            synchronized (mSurfaceReleaseLock) {
                if (mCreated) {
                    try {
                    if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
                        if (DEBUG) {
                            Log.v(TAG, "Removing window and destroying surface "
                                    + mSurfaceHolder.getSurface() + " of: " + this);
                        }

                        if (mInputEventReceiver != null) {
                            mInputEventReceiver.dispose();
@@ -2387,6 +2393,7 @@ public abstract class WallpaperService extends Service {
                    mRelayoutResult = null;
                }
            }
        }

        private final DisplayListener mDisplayListener =
                new DisplayListener() {