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:
committed by
Android (Google) Code Review
commit
08e59efeb6
@@ -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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user