Fix regression in app drag target windows
- Only disallow non-local, non-global intercepting windows from receiving drags. The window which originated the drag still might want to receive drag events to kick off animations/etc. Bug: 178690347 Test: atest DragDropControllerTests Change-Id: I856d179993e687ba343e35d87bd1f3c613e637db
This commit is contained in:
@@ -497,9 +497,10 @@ class DragState {
|
||||
if (targetWin == null) {
|
||||
return false;
|
||||
}
|
||||
if (!interceptsGlobalDrag && containsAppExtras) {
|
||||
// App-drags can only go to windows that can intercept global drag, and not to normal
|
||||
// app windows
|
||||
final boolean isLocalWindow = mLocalWin == targetWin.mClient.asBinder();
|
||||
if (!isLocalWindow && !interceptsGlobalDrag && containsAppExtras) {
|
||||
// App-drags can only go to local windows or windows that can intercept global drag, and
|
||||
// not to other app windows
|
||||
return false;
|
||||
}
|
||||
if (!targetWin.isPotentialDragTarget(interceptsGlobalDrag)) {
|
||||
@@ -507,7 +508,7 @@ class DragState {
|
||||
}
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0 || !targetWindowSupportsGlobalDrag(targetWin)) {
|
||||
// Drag is limited to the current window.
|
||||
if (mLocalWin != targetWin.mClient.asBinder()) {
|
||||
if (!isLocalWindow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,25 +239,31 @@ public class DragDropControllerTests extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterceptGlobalDragDropIgnoresOtherWindows() {
|
||||
public void testPrivateInterceptGlobalDragDropIgnoresNonLocalWindows() {
|
||||
WindowState nonLocalWindow = createDropTargetWindow("App drag test window", 0);
|
||||
WindowState globalInterceptWindow = createDropTargetWindow("Global drag test window", 0);
|
||||
globalInterceptWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
|
||||
|
||||
// Necessary for now since DragState.sendDragStartedLocked() will recycle drag events
|
||||
// immediately after dispatching, which is a problem when using mockito arguments captor
|
||||
// because it returns and modifies the same drag event
|
||||
TestIWindow iwindow = (TestIWindow) mWindow.mClient;
|
||||
final ArrayList<DragEvent> dragEvents = new ArrayList<>();
|
||||
iwindow.setDragEventJournal(dragEvents);
|
||||
TestIWindow localIWindow = (TestIWindow) mWindow.mClient;
|
||||
final ArrayList<DragEvent> localWindowDragEvents = new ArrayList<>();
|
||||
localIWindow.setDragEventJournal(localWindowDragEvents);
|
||||
TestIWindow nonLocalIWindow = (TestIWindow) nonLocalWindow.mClient;
|
||||
final ArrayList<DragEvent> nonLocalWindowDragEvents = new ArrayList<>();
|
||||
nonLocalIWindow.setDragEventJournal(nonLocalWindowDragEvents);
|
||||
TestIWindow globalInterceptIWindow = (TestIWindow) globalInterceptWindow.mClient;
|
||||
final ArrayList<DragEvent> globalInterceptWindowDragEvents = new ArrayList<>();
|
||||
globalInterceptIWindow.setDragEventJournal(globalInterceptWindowDragEvents);
|
||||
|
||||
startDrag(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ,
|
||||
createClipDataForActivity(null, mock(UserHandle.class)), () -> {
|
||||
// Verify the start-drag event is sent for the intercept window but not the
|
||||
// other window
|
||||
assertTrue(dragEvents.isEmpty());
|
||||
// Verify the start-drag event is sent for the local and global intercept window
|
||||
// but not the other window
|
||||
assertTrue(nonLocalWindowDragEvents.isEmpty());
|
||||
assertTrue(localWindowDragEvents.get(0).getAction()
|
||||
== ACTION_DRAG_STARTED);
|
||||
assertTrue(globalInterceptWindowDragEvents.get(0).getAction()
|
||||
== ACTION_DRAG_STARTED);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user