Merge changes from topic "drag surface stuck"

* changes:
  Fix drag surface would be stuck (1/2)
  Revert "Fix drag and drop (3/3)"
  Revert "Fix drag and drop (2/3)"
  Revert "Fix drag and drop (1/3)"
This commit is contained in:
TreeHugger Robot
2019-09-28 00:08:43 +00:00
committed by Android (Google) Code Review
12 changed files with 75 additions and 52 deletions

View File

@@ -187,8 +187,7 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject,
InputWindowHandle handle);
private static native void nativeTransferTouchFocus(long transactionObj, IBinder fromToken,
IBinder toToken);
private static native boolean nativeGetProtectedContentSupport();
private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key,
Parcel data);
@@ -2238,22 +2237,6 @@ public final class SurfaceControl implements Parcelable {
return this;
}
/**
* Transfers touch focus from one window to another. It is possible for multiple windows to
* have touch focus if they support split touch dispatch
* {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
* method only transfers touch focus of the specified window without affecting
* other windows that may also have touch focus at the same time.
* @param fromToken The token of a window that currently has touch focus.
* @param toToken The token of the window that should receive touch focus in
* place of the first.
* @hide
*/
public Transaction transferTouchFocus(IBinder fromToken, IBinder toToken) {
nativeTransferTouchFocus(mNativeObject, fromToken, toToken);
return this;
}
/**
* Waits until any changes to input windows have been sent from SurfaceFlinger to
* InputFlinger before returning.

View File

@@ -458,15 +458,6 @@ static void nativeSetInputWindowInfo(JNIEnv* env, jclass clazz, jlong transactio
transaction->setInputWindowInfo(ctrl, *handle->getInfo());
}
static void nativeTransferTouchFocus(JNIEnv* env, jclass clazz, jlong transactionObj,
jobject fromTokenObj, jobject toTokenObj) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
sp<IBinder> fromToken(ibinderForJavaObject(env, fromTokenObj));
sp<IBinder> toToken(ibinderForJavaObject(env, toTokenObj));
transaction->transferTouchFocus(fromToken, toToken);
}
static void nativeSyncInputWindows(JNIEnv* env, jclass clazz, jlong transactionObj) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
transaction->syncInputWindows();
@@ -1381,8 +1372,6 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
(void*)nativeSetInputWindowInfo },
{"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;)V",
(void*)nativeTransferTouchFocus },
{"nativeSetMetadata", "(JJILandroid/os/Parcel;)V",
(void*)nativeSetMetadata },
{"nativeGetDisplayedContentSamplingAttributes",

View File

@@ -220,6 +220,8 @@ public class InputManagerService extends IInputManager.Stub
private static native void nativeSetFocusedApplication(long ptr,
int displayId, InputApplicationHandle application);
private static native void nativeSetFocusedDisplay(long ptr, int displayId);
private static native boolean nativeTransferTouchFocus(long ptr,
InputChannel fromChannel, InputChannel toChannel);
private static native void nativeSetPointerSpeed(long ptr, int speed);
private static native void nativeSetShowTouches(long ptr, boolean enabled);
private static native void nativeSetInteractive(long ptr, boolean interactive);
@@ -1533,6 +1535,29 @@ public class InputManagerService extends IInputManager.Stub
nativeSetSystemUiVisibility(mPtr, visibility);
}
/**
* Atomically transfers touch focus from one window to another as identified by
* their input channels. It is possible for multiple windows to have
* touch focus if they support split touch dispatch
* {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this
* method only transfers touch focus of the specified window without affecting
* other windows that may also have touch focus at the same time.
* @param fromChannel The channel of a window that currently has touch focus.
* @param toChannel The channel of the window that should receive touch focus in
* place of the first.
* @return True if the transfer was successful. False if the window with the
* specified channel did not actually have touch focus at the time of the request.
*/
public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) {
if (fromChannel == null) {
throw new IllegalArgumentException("fromChannel must not be null.");
}
if (toChannel == null) {
throw new IllegalArgumentException("toChannel must not be null.");
}
return nativeTransferTouchFocus(mPtr, fromChannel, toChannel);
}
@Override // Binder call
public void tryPointerSpeed(int speed) {
if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,

View File

@@ -113,7 +113,7 @@ class DragDropController {
final WindowState callingWin = mService.windowForClientLocked(
null, window, false);
if (callingWin == null) {
if (callingWin == null || callingWin.cantReceiveTouchInput()) {
Slog.w(TAG_WM, "Bad requesting window " + window);
return null; // !!! TODO: throw here?
}
@@ -167,8 +167,7 @@ class DragDropController {
final SurfaceControl surfaceControl = mDragState.mSurfaceControl;
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> OPEN TRANSACTION performDrag");
final SurfaceControl.Transaction transaction =
callingWin.getPendingTransaction();
final SurfaceControl.Transaction transaction = mDragState.mTransaction;
transaction.setAlpha(surfaceControl, mDragState.mOriginalAlpha);
transaction.setPosition(
surfaceControl, touchX - thumbCenterX, touchY - thumbCenterY);

View File

@@ -120,7 +120,7 @@ class DragState {
// A surface used to catch input events for the drag-and-drop operation.
SurfaceControl mInputSurface;
private final SurfaceControl.Transaction mTransaction;
final SurfaceControl.Transaction mTransaction;
private final Rect mTmpClipRect = new Rect();
@@ -129,7 +129,6 @@ class DragState {
* {@code true} when {@link #closeLocked()} is called.
*/
private boolean mIsClosing;
IBinder mTransferTouchFromToken;
DragState(WindowManagerService service, DragDropController controller, IBinder token,
SurfaceControl surface, int flags, IBinder localWin) {
@@ -167,12 +166,11 @@ class DragState {
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
mTransaction.transferTouchFocus(mTransferTouchFromToken, h.token);
mTransferTouchFromToken = null;
// syncInputWindows here to ensure the input channel isn't removed before the transfer.
// syncInputWindows here to ensure the input window info is sent before the
// transferTouchFocus is called.
mTransaction.syncInputWindows();
mTransaction.apply();
mTransaction.apply(true);
}
/**

View File

@@ -50,6 +50,7 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputWindowHandle;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
@@ -302,7 +303,8 @@ class TaskPositioner implements IBinder.DeathRecipient {
mDisplayContent.getDisplayRotation().pause();
// Notify InputMonitor to take mDragWindowHandle.
mDisplayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);
mDisplayContent.getInputMonitor().updateInputWindowsImmediately();
new SurfaceControl.Transaction().syncInputWindows().apply(true);
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, mDisplayMetrics);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, mDisplayMetrics);

View File

@@ -24,7 +24,6 @@ import android.app.IActivityTaskManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Slog;
@@ -51,7 +50,6 @@ class TaskPositioningController {
private @Nullable TaskPositioner mTaskPositioner;
private final Rect mTmpClipRect = new Rect();
private IBinder mTransferTouchFromToken;
boolean isPositioningLocked() {
return mTaskPositioner != null;
@@ -104,8 +102,6 @@ class TaskPositioningController {
mTmpClipRect.set(0, 0, p.x, p.y);
t.setWindowCrop(mInputSurface, mTmpClipRect);
t.transferTouchFocus(mTransferTouchFromToken, h.token);
mTransferTouchFromToken = null;
}
boolean startMovingTask(IWindow window, float startX, float startY) {
@@ -168,6 +164,7 @@ class TaskPositioningController {
mPositioningDisplay = displayContent;
mTaskPositioner = TaskPositioner.create(mService);
mTaskPositioner.register(displayContent);
// We need to grab the touch focus so that the touch events during the
// resizing/scrolling are not sent to the app. 'win' is the main window
@@ -178,8 +175,12 @@ class TaskPositioningController {
&& displayContent.mCurrentFocus.mAppToken == win.mAppToken) {
transferFocusFromWin = displayContent.mCurrentFocus;
}
mTransferTouchFromToken = transferFocusFromWin.mInputChannel.getToken();
mTaskPositioner.register(displayContent);
if (!mInputManager.transferTouchFocus(
transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) {
Slog.e(TAG_WM, "startPositioningLocked: Unable to transfer touch focus");
cleanUpTaskPositioner();
return false;
}
mTaskPositioner.startDrag(win, resize, preserveOrientation, startX, startY);
return true;

View File

@@ -161,9 +161,8 @@ public abstract class WindowManagerInternal {
default boolean registerInputChannel(
DragState state, Display display, InputManagerService service,
InputChannel source) {
state.mTransferTouchFromToken = source.getToken();
state.register(display);
return true;
return service.transferTouchFocus(source, state.getInputChannel());
}
/**

View File

@@ -1570,6 +1570,27 @@ static void nativeSetSystemUiVisibility(JNIEnv* /* env */,
im->setSystemUiVisibility(visibility);
}
static jboolean nativeTransferTouchFocus(JNIEnv* env,
jclass /* clazz */, jlong ptr, jobject fromChannelObj, jobject toChannelObj) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
sp<InputChannel> fromChannel =
android_view_InputChannel_getInputChannel(env, fromChannelObj);
sp<InputChannel> toChannel =
android_view_InputChannel_getInputChannel(env, toChannelObj);
if (fromChannel == nullptr || toChannel == nullptr) {
return JNI_FALSE;
}
if (im->getInputManager()->getDispatcher()->
transferTouchFocus(fromChannel->getToken(), toChannel->getToken())) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}
static void nativeSetPointerSpeed(JNIEnv* /* env */,
jclass /* clazz */, jlong ptr, jint speed) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1763,6 +1784,8 @@ static const JNINativeMethod gInputManagerMethods[] = {
(void*) nativeSetInputDispatchMode },
{ "nativeSetSystemUiVisibility", "(JI)V",
(void*) nativeSetSystemUiVisibility },
{ "nativeTransferTouchFocus", "(JLandroid/view/InputChannel;Landroid/view/InputChannel;)Z",
(void*) nativeTransferTouchFocus },
{ "nativeSetPointerSpeed", "(JI)V",
(void*) nativeSetPointerSpeed },
{ "nativeSetShowTouches", "(JZ)V",

View File

@@ -20,9 +20,11 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -124,6 +126,7 @@ public class DragDropControllerTests extends WindowTestsBase {
mDisplayContent = spy(mDisplayContent);
mWindow = createDropTargetWindow("Drag test window", 0);
doReturn(mWindow).when(mDisplayContent).getTouchableWinAtPointLocked(0, 0);
when(mWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true);
synchronized (mWm.mGlobalLock) {
mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
@@ -177,6 +180,7 @@ public class DragDropControllerTests extends WindowTestsBase {
.setFormat(PixelFormat.TRANSLUCENT)
.build();
assertTrue(mWm.mInputManager.transferTouchFocus(null, null));
mToken = mTarget.performDrag(
new SurfaceSession(), 0, 0, mWindow.mClient, flag, surface, 0, 0, 0, 0, 0,
data);

View File

@@ -96,11 +96,6 @@ public class StubTransaction extends SurfaceControl.Transaction {
return this;
}
@Override
public SurfaceControl.Transaction transferTouchFocus(IBinder fromToken, IBinder toToken) {
return this;
}
@Override
public SurfaceControl.Transaction setGeometry(SurfaceControl sc, Rect sourceCrop,
Rect destFrame, @Surface.Rotation int orientation) {

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -57,6 +58,10 @@ public class TaskPositioningControllerTests extends WindowTestsBase {
assertNotNull(mWm.mTaskPositioningController);
mTarget = mWm.mTaskPositioningController;
when(mWm.mInputManager.transferTouchFocus(
any(InputChannel.class),
any(InputChannel.class))).thenReturn(true);
mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
mWindow.mInputChannel = new InputChannel();
synchronized (mWm.mGlobalLock) {