DragState.java revision 6e1eb76f02ccc9dbc309b938f62d39312da8cafe
16e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn/* 26e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * Copyright (C) 2011 The Android Open Source Project 36e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * 46e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 56e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * you may not use this file except in compliance with the License. 66e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * You may obtain a copy of the License at 76e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * 86e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 96e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * 106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * Unless required by applicable law or agreed to in writing, software 116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * See the License for the specific language governing permissions and 146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * limitations under the License. 156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */ 166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornpackage com.android.server.wm; 186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport com.android.server.wm.WindowManagerService.H; 206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.content.ClipData; 226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.content.ClipDescription; 236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.graphics.Region; 246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.IBinder; 256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.Message; 266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.Process; 276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.RemoteException; 286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.util.Slog; 296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.DragEvent; 306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.InputChannel; 316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.InputQueue; 326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.Surface; 336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.View; 346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.WindowManager; 356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.WindowManagerPolicy; 366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport java.util.ArrayList; 386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn/** 406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * Drag/drop state 416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */ 426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornclass DragState { 436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final WindowManagerService mService; 446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn IBinder mToken; 456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Surface mSurface; 466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn int mFlags; 476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn IBinder mLocalWin; 486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn ClipData mData; 496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn ClipDescription mDataDescription; 506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn boolean mDragResult; 516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn float mCurrentX, mCurrentY; 526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn float mThumbOffsetX, mThumbOffsetY; 536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn InputChannel mServerChannel, mClientChannel; 546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowState mTargetWindow; 556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn ArrayList<WindowState> mNotifiedWindows; 566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn boolean mDragInProgress; 576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn private final Region mTmpRegion = new Region(); 596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragState(WindowManagerService service, IBinder token, Surface surface, 616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn int flags, IBinder localWin) { 626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService = service; 636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mToken = token; 646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mSurface = surface; 656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mFlags = flags; 666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mLocalWin = localWin; 676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mNotifiedWindows = new ArrayList<WindowState>(); 686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void reset() { 716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mSurface != null) { 726e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mSurface.destroy(); 736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mSurface = null; 756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mFlags = 0; 766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mLocalWin = null; 776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mToken = null; 786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mData = null; 796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mThumbOffsetX = mThumbOffsetY = 0; 806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mNotifiedWindows = null; 816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void register() { 846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "registering drag input channel"); 856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mClientChannel != null) { 866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.e(WindowManagerService.TAG, "Duplicate register of drag input channel"); 876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } else { 886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn InputChannel[] channels = InputChannel.openInputChannelPair("drag"); 896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mServerChannel = channels[0]; 906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mClientChannel = channels[1]; 916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mInputManager.registerInputChannel(mServerChannel, null); 926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler, 936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mH.getLooper().getQueue()); 946e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 956e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 966e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 976e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void unregister() { 986e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "unregistering drag input channel"); 996e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mClientChannel == null) { 1006e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel"); 1016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } else { 1026e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mInputManager.unregisterInputChannel(mServerChannel); 1036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn InputQueue.unregisterInputChannel(mClientChannel); 1046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mClientChannel.dispose(); 1056e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mServerChannel.dispose(); 1066e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mClientChannel = null; 1076e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mServerChannel = null; 1086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn int getDragLayerLw() { 1126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG) 1136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * WindowManagerService.TYPE_LAYER_MULTIPLIER 1146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn + WindowManagerService.TYPE_LAYER_OFFSET; 1156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn /* call out to each visible window/session informing it about the drag 1186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */ 1196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void broadcastDragStartedLw(final float touchX, final float touchY) { 1206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Cache a base-class instance of the clip metadata so that parceling 1216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // works correctly in calling out to the apps. 1226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mDataDescription = (mData != null) ? mData.getDescription() : null; 1236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mNotifiedWindows.clear(); 1246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mDragInProgress = true; 1256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 1276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")"); 1286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int N = mService.mWindows.size(); 1316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn for (int i = 0; i < N; i++) { 1326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn sendDragStartedLw(mService.mWindows.get(i), touchX, touchY, mDataDescription); 1336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the 1376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * designated window is potentially a drop recipient. There are race situations 1386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * around DRAG_ENDED broadcast, so we make sure that once we've declared that 1396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * the drag has ended, we never send out another DRAG_STARTED for this drag action. 1406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * 1416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * This method clones the 'event' parameter if it's being delivered to the same 1426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * process, so it's safe for the caller to call recycle() on the event afterwards. 1436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */ 1446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn private void sendDragStartedLw(WindowState newWin, float touchX, float touchY, 1456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn ClipDescription desc) { 1466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Don't actually send the event if the drag is supposed to be pinned 1476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // to the originating window but 'newWin' is not that window. 1486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) { 1496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final IBinder winBinder = newWin.mClient.asBinder(); 1506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (winBinder != mLocalWin) { 1516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 1526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "Not dispatching local DRAG_STARTED to " + newWin); 1536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return; 1556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mDragInProgress && newWin.isPotentialDragTarget()) { 1596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 1606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn touchX - newWin.mFrame.left, touchY - newWin.mFrame.top, 1616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn null, desc, null, false); 1626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn try { 1636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn newWin.mClient.dispatchDragEvent(event); 1646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // track each window that we've notified that the drag is starting 1656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mNotifiedWindows.add(newWin); 1666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } catch (RemoteException e) { 1676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.w(WindowManagerService.TAG, "Unable to drag-start window " + newWin); 1686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } finally { 1696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // if the callee was local, the dispatch has already recycled the event 1706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (Process.myPid() != newWin.mSession.mPid) { 1716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn event.recycle(); 1726e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn /* helper - construct and send a DRAG_STARTED event only if the window has not 1786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * previously been notified, i.e. it became visible after the drag operation 1796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * was begun. This is a rare case. 1806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */ 1816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void sendDragStartedIfNeededLw(WindowState newWin) { 1826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mDragInProgress) { 1836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // If we have sent the drag-started, we needn't do so again 1846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn for (WindowState ws : mNotifiedWindows) { 1856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (ws == newWin) { 1866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return; 1876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 1906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "need to send DRAG_STARTED to new window " + newWin); 1916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription); 1936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1946e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 1956e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 1966e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void broadcastDragEndedLw() { 1976e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 1986e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED"); 1996e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2006e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, 2016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 0, 0, null, null, null, mDragResult); 2026e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn for (WindowState ws: mNotifiedWindows) { 2036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn try { 2046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn ws.mClient.dispatchDragEvent(evt); 2056e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } catch (RemoteException e) { 2066e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.w(WindowManagerService.TAG, "Unable to drag-end window " + ws); 2076e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mNotifiedWindows.clear(); 2106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mDragInProgress = false; 2116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn evt.recycle(); 2126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void endDragLw() { 2156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mDragState.broadcastDragEndedLw(); 2166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // stop intercepting input 2186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mDragState.unregister(); 2196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mInputMonitor.updateInputWindowsLw(true /*force*/); 2206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // free our resources and drop all the object references 2226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mDragState.reset(); 2236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mDragState = null; 2246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_ORIENTATION) Slog.d(WindowManagerService.TAG, "Performing post-drag rotation"); 2266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn boolean changed = mService.setRotationUncheckedLocked( 2276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowManagerPolicy.USE_LAST_ROTATION, 0, false); 2286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (changed) { 2296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 2306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn void notifyMoveLw(float x, float y) { 2346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int myPid = Process.myPid(); 2356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Move the surface to the given touch 2376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw"); 2386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Surface.openTransaction(); 2396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn try { 2406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY)); 2416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DRAG " 2426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn + mSurface + ": pos=(" + 2436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")"); 2446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } finally { 2456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Surface.closeTransaction(); 2466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw"); 2476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Tell the affected window 2506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowState touchedWin = getTouchedWinAtPointLw(x, y); 2516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (touchedWin == null) { 2526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "No touched win at x=" + x + " y=" + y); 2536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return; 2546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) { 2566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final IBinder touchedBinder = touchedWin.mClient.asBinder(); 2576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (touchedBinder != mLocalWin) { 2586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // This drag is pinned only to the originating window, but the drag 2596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // point is outside that window. Pretend it's over empty space. 2606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn touchedWin = null; 2616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn try { 2646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // have we dragged over a new window? 2656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) { 2666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 2676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow); 2686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // force DRAG_EXITED_EVENT if appropriate 2706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED, 2716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top, 2726e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn null, null, null, false); 2736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mTargetWindow.mClient.dispatchDragEvent(evt); 2746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (myPid != mTargetWindow.mSession.mPid) { 2756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn evt.recycle(); 2766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (touchedWin != null) { 2796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (false && WindowManagerService.DEBUG_DRAG) { 2806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin); 2816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION, 2836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn x - touchedWin.mFrame.left, y - touchedWin.mFrame.top, 2846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn null, null, null, false); 2856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn touchedWin.mClient.dispatchDragEvent(evt); 2866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (myPid != touchedWin.mSession.mPid) { 2876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn evt.recycle(); 2886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } catch (RemoteException e) { 2916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.w(WindowManagerService.TAG, "can't send drag notification to windows"); 2926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mTargetWindow = touchedWin; 2946e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 2956e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 2966e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Tell the drop target about the data. Returns 'true' if we can immediately 2976e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // dispatch the global drag-ended message, 'false' if we need to wait for a 2986e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // result from the recipient. 2996e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn boolean notifyDropLw(float x, float y) { 3006e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowState touchedWin = getTouchedWinAtPointLw(x, y); 3016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (touchedWin == null) { 3026e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // "drop" outside a valid window -- no recipient to apply a 3036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // timeout to, and we can send the drag-ended message immediately. 3046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mDragResult = false; 3056e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return true; 3066e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3076e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (WindowManagerService.DEBUG_DRAG) { 3096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.d(WindowManagerService.TAG, "sending DROP to " + touchedWin); 3106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int myPid = Process.myPid(); 3126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final IBinder token = touchedWin.mClient.asBinder(); 3136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, 3146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn x - touchedWin.mFrame.left, y - touchedWin.mFrame.top, 3156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn null, null, mData, false); 3166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn try { 3176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn touchedWin.mClient.dispatchDragEvent(evt); 3186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // 5 second timeout for this window to respond to the drop 3206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mH.removeMessages(H.DRAG_END_TIMEOUT, token); 3216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Message msg = mService.mH.obtainMessage(H.DRAG_END_TIMEOUT, token); 3226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mService.mH.sendMessageDelayed(msg, 5000); 3236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } catch (RemoteException e) { 3246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn Slog.w(WindowManagerService.TAG, "can't send drop notification to win " + touchedWin); 3256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return true; 3266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } finally { 3276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (myPid != touchedWin.mSession.mPid) { 3286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn evt.recycle(); 3296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn mToken = token; 3326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return false; 3336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Find the visible, touch-deliverable window under the given point 3366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn private WindowState getTouchedWinAtPointLw(float xf, float yf) { 3376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowState touchedWin = null; 3386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int x = (int) xf; 3396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int y = (int) yf; 3406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final ArrayList<WindowState> windows = mService.mWindows; 3416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int N = windows.size(); 3426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn for (int i = N - 1; i >= 0; i--) { 3436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn WindowState child = windows.get(i); 3446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int flags = child.mAttrs.flags; 3456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (!child.isVisibleLw()) { 3466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // not visible == don't tell about drags 3476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn continue; 3486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { 3506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // not touchable == don't tell about drags 3516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn continue; 3526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn child.getTouchableRegion(mTmpRegion); 3556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn final int touchFlags = flags & 3576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 3586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); 3596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn if (mTmpRegion.contains(x, y) || touchFlags == 0) { 3606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn // Found it 3616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn touchedWin = child; 3626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn break; 3636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn 3666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn return touchedWin; 3676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn } 3686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn}