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
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user