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

Commit d427c628 authored by Garfield Tan's avatar Garfield Tan
Browse files

Fix a bug that effectively disallows hiding surfaces.

InputMonitor checks DragDropController and TaskPositioningController's
state to decide if it should show or hide respective surface. However
when InputMonitor checks the status when stopping
drag-resizing/drag-and-drop, the status is not yet changed because
TaskPositioner/DragState instance isn't cleared yet.

Therefore this CL clears TaskPositioning before updating InputWindow,
and flags the closing state in DragState to avoid surface leak.

Bug: 120289807
Test: Drag-resize works with a workaround to another race condition.
Change-Id: I743d0a97c937b9d6a06c70d42da34cc77822cd58
parent e656e67e
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -31,13 +31,12 @@ import android.util.Slog;
import android.view.Display;
import android.view.IWindow;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.View;

import com.android.internal.util.Preconditions;
import android.view.InputWindowHandle;
import com.android.server.wm.WindowManagerInternal.IDragDropCallback;

import java.util.concurrent.atomic.AtomicReference;

/**
@@ -71,7 +70,7 @@ class DragDropController {
            new IDragDropCallback() {});

    boolean dragDropActiveLocked() {
        return mDragState != null;
        return mDragState != null && !mDragState.isClosing();
    }

    void showInputSurface(SurfaceControl.Transaction t, int displayId) {
+15 −7
Original line number Diff line number Diff line
@@ -31,25 +31,24 @@ import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Build;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.IUserManager;
import android.os.UserManagerInternal;
import android.util.Slog;
import android.view.Display;
import android.view.DragEvent;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputWindowHandle;
import android.view.PointerIcon;
import android.view.SurfaceControl;
import android.view.View;
@@ -59,8 +58,6 @@ import android.view.animation.Interpolator;

import com.android.internal.view.IDragAndDropPermissions;
import com.android.server.LocalServices;
import android.view.InputApplicationHandle;
import android.view.InputWindowHandle;

import java.util.ArrayList;

@@ -125,6 +122,12 @@ class DragState {

    private final Rect mTmpClipRect = new Rect();

    /**
     * Whether we are finishing this drag and drop. This starts with {@code false}, and is set to
     * {@code true} when {@link #closeLocked()} is called.
     */
    private boolean mIsClosing;

    DragState(WindowManagerService service, DragDropController controller, IBinder token,
            SurfaceControl surface, int flags, IBinder localWin) {
        mService = service;
@@ -137,6 +140,10 @@ class DragState {

    }

    boolean isClosing() {
        return mIsClosing;
    }

    void hideInputSurface(SurfaceControl.Transaction t, int displayId) {
        if (displayId != mDisplayContent.getDisplayId()) {
            return;
@@ -177,6 +184,7 @@ class DragState {
     * DragDropController#mDragState becomes null.
     */
    void closeLocked() {
        mIsClosing = true;
        // Unregister the input interceptor.
        if (mInputInterceptor != null) {
            if (DEBUG_DRAG)
+16 −9
Original line number Diff line number Diff line
@@ -28,12 +28,12 @@ import android.os.Looper;
import android.os.RemoteException;
import android.util.Slog;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.IWindow;
import android.view.InputWindowHandle;
import android.view.SurfaceControl;

import com.android.internal.annotations.GuardedBy;
import com.android.server.input.InputManagerService;
import android.view.InputWindowHandle;

/**
 * Controller for task positioning by drag.
@@ -184,9 +184,7 @@ class TaskPositioningController {
        if (!mInputManager.transferTouchFocus(
                transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) {
            Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
            mTaskPositioner.unregister();
            mTaskPositioner = null;
            displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
            cleanUpTaskPositioner();
            return false;
        }

@@ -199,12 +197,21 @@ class TaskPositioningController {
            if (DEBUG_TASK_POSITIONING) Slog.d(TAG_WM, "finishPositioning");

            synchronized (mService.mGlobalLock) {
                if (mTaskPositioner != null) {
                    mTaskPositioner.unregister();
                    mTaskPositioner = null;
                }
                cleanUpTaskPositioner();
                mPositioningDisplay = null;
            }
        });
    }

    private void cleanUpTaskPositioner() {
        final TaskPositioner positioner = mTaskPositioner;
        if (positioner == null) {
            return;
        }

        // We need to assign task positioner to null first to indicate that we're finishing task
        // positioning.
        mTaskPositioner = null;
        positioner.unregister();
    }
}