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

Commit 9a81477e authored by Winson Chung's avatar Winson Chung
Browse files

Fix issue with leaking death recipients

- When invalidating an existing external interface, we also need to
  unregister any listeners to ensure that binder death recipients are
  unlinked.  Otherwise, a crash in the process for the old listener
  can cause the current listener to be unregistered.

Bug: 242377577
Test: atest WMShellUnitTests
Change-Id: Ibb77ac19e4ebc616b8977db70d6269e3b930848e
parent 12f428cb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import java.util.function.Consumer;
 * Manages the lifecycle of a single instance of a remote listener, including the clean up if the
 * remote process dies.  All calls on this class should happen on the main shell thread.
 *
 * Any external interface using this listener should also unregister the listener when it is
 * invalidated, otherwise it may leak binder death recipients.
 *
 * @param <C> The controller (must be RemoteCallable)
 * @param <L> The remote listener interface type
 */
+12 −7
Original line number Diff line number Diff line
@@ -207,7 +207,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb

    private Consumer<Boolean> mOnIsInPipStateChangedListener;

    private interface PipAnimationListener {
    @VisibleForTesting
    interface PipAnimationListener {
        /**
         * Notifies the listener that the Pip animation is started.
         */
@@ -434,11 +435,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            Optional<OneHandedController> oneHandedController,
            ShellExecutor mainExecutor
    ) {
        // Ensure that we are the primary user's SystemUI.
        final int processUser = UserManager.get(context).getProcessUserId();
        if (processUser != UserHandle.USER_SYSTEM) {
            throw new IllegalStateException("Non-primary Pip component not currently supported.");
        }


        mContext = context;
        mShellCommandHandler = shellCommandHandler;
@@ -872,11 +869,17 @@ public class PipController implements PipTransitionController.PipTransitionCallb
                animationType == PipAnimationController.ANIM_TYPE_BOUNDS);
    }

    private void setPinnedStackAnimationListener(PipAnimationListener callback) {
    @VisibleForTesting
    void setPinnedStackAnimationListener(PipAnimationListener callback) {
        mPinnedStackAnimationRecentsCallback = callback;
        onPipResourceDimensionsChanged();
    }

    @VisibleForTesting
    boolean hasPinnedStackAnimationListener() {
        return mPinnedStackAnimationRecentsCallback != null;
    }

    private void onPipResourceDimensionsChanged() {
        if (mPinnedStackAnimationRecentsCallback != null) {
            mPinnedStackAnimationRecentsCallback.onPipResourceDimensionsChanged(
@@ -1166,6 +1169,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        @Override
        public void invalidate() {
            mController = null;
            // Unregister the listener to ensure any registered binder death recipients are unlinked
            mListener.unregister();
        }

        @Override
+11 −2
Original line number Diff line number Diff line
@@ -280,14 +280,21 @@ public class RecentTasksController implements TaskStackListenerCallback,
        }
    }

    private void registerRecentTasksListener(IRecentTasksListener listener) {
    @VisibleForTesting
    void registerRecentTasksListener(IRecentTasksListener listener) {
        mListener = listener;
    }

    private void unregisterRecentTasksListener() {
    @VisibleForTesting
    void unregisterRecentTasksListener() {
        mListener = null;
    }

    @VisibleForTesting
    boolean hasRecentTasksListener() {
        return mListener != null;
    }

    @VisibleForTesting
    ArrayList<GroupedRecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
        // Note: the returned task list is from the most-recent to least-recent order
@@ -442,6 +449,8 @@ public class RecentTasksController implements TaskStackListenerCallback,
        @Override
        public void invalidate() {
            mController = null;
            // Unregister the listener to ensure any registered binder death recipients are unlinked
            mListener.unregister();
        }

        @Override
+2 −0
Original line number Diff line number Diff line
@@ -954,6 +954,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        @Override
        public void invalidate() {
            mController = null;
            // Unregister the listener to ensure any registered binder death recipients are unlinked
            mListener.unregister();
        }

        @Override
+9 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.window.TaskOrganizer;
import android.window.TaskSnapshot;

import androidx.annotation.BinderThread;
import androidx.annotation.VisibleForTesting;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.TriConsumer;
@@ -138,10 +139,16 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
     *
     * @param listener The callback when need a starting window.
     */
    @VisibleForTesting
    void setStartingWindowListener(TriConsumer<Integer, Integer, Integer> listener) {
        mTaskLaunchingCallback = listener;
    }

    @VisibleForTesting
    boolean hasStartingWindowListener() {
        return mTaskLaunchingCallback != null;
    }

    /**
     * Called when a task need a starting window.
     */
@@ -281,6 +288,8 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo
        @Override
        public void invalidate() {
            mController = null;
            // Unregister the listener to ensure any registered binder death recipients are unlinked
            mListener.unregister();
        }

        @Override
Loading