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
194532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownimport com.android.server.input.InputApplicationHandle;
204532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownimport com.android.server.input.InputWindowHandle;
2132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownimport com.android.server.wm.WindowManagerService.DragInputEventReceiver;
226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport com.android.server.wm.WindowManagerService.H;
236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.content.ClipData;
256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.content.ClipDescription;
26398341927f3dca68d71024483aa276d10af4c080Craig Mautnerimport android.graphics.Point;
276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.graphics.Region;
286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.IBinder;
296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.Message;
306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.Process;
316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.os.RemoteException;
326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.util.Slog;
33398341927f3dca68d71024483aa276d10af4c080Craig Mautnerimport android.view.Display;
346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.DragEvent;
356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.InputChannel;
366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.Surface;
373866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.View;
396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport android.view.WindowManager;
406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornimport java.util.ArrayList;
426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn/**
446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn * Drag/drop state
456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn */
466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackbornclass DragState {
476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    final WindowManagerService mService;
486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    IBinder mToken;
4929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian    SurfaceControl mSurfaceControl;
506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    int mFlags;
516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    IBinder mLocalWin;
526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    ClipData mData;
536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    ClipDescription mDataDescription;
546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    boolean mDragResult;
556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    float mCurrentX, mCurrentY;
566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    float mThumbOffsetX, mThumbOffsetY;
576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    InputChannel mServerChannel, mClientChannel;
5832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown    DragInputEventReceiver mInputEventReceiver;
59ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown    InputApplicationHandle mDragApplicationHandle;
60ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown    InputWindowHandle mDragWindowHandle;
616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    WindowState mTargetWindow;
626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    ArrayList<WindowState> mNotifiedWindows;
636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    boolean mDragInProgress;
64398341927f3dca68d71024483aa276d10af4c080Craig Mautner    Display mDisplay;
656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    private final Region mTmpRegion = new Region();
676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
683866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    DragState(WindowManagerService service, IBinder token, SurfaceControl surface,
696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            int flags, IBinder localWin) {
706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService = service;
716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mToken = token;
7229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian        mSurfaceControl = surface;
736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mFlags = flags;
746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mLocalWin = localWin;
756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mNotifiedWindows = new ArrayList<WindowState>();
766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void reset() {
7929479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian        if (mSurfaceControl != null) {
8029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            mSurfaceControl.destroy();
816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
8229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian        mSurfaceControl = null;
836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mFlags = 0;
846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mLocalWin = null;
856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mToken = null;
866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mData = null;
876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mThumbOffsetX = mThumbOffsetY = 0;
886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mNotifiedWindows = null;
896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
913486b9696d81da8873ef595daa35b2d39fc83146Craig Mautner    /**
92398341927f3dca68d71024483aa276d10af4c080Craig Mautner     * @param display The Display that the window being dragged is on.
933486b9696d81da8873ef595daa35b2d39fc83146Craig Mautner     */
94398341927f3dca68d71024483aa276d10af4c080Craig Mautner    void register(Display display) {
95398341927f3dca68d71024483aa276d10af4c080Craig Mautner        mDisplay = display;
966e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "registering drag input channel");
976e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (mClientChannel != null) {
986e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.e(WindowManagerService.TAG, "Duplicate register of drag input channel");
996e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } else {
1006e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            InputChannel[] channels = InputChannel.openInputChannelPair("drag");
1016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mServerChannel = channels[0];
1026e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mClientChannel = channels[1];
1036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mService.mInputManager.registerInputChannel(mServerChannel, null);
10432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown            mInputEventReceiver = mService.new DragInputEventReceiver(mClientChannel,
10532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown                    mService.mH.getLooper());
106ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown
107ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragApplicationHandle = new InputApplicationHandle(null);
108ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragApplicationHandle.name = "drag";
109ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragApplicationHandle.dispatchingTimeoutNanos =
110ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
111ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown
11259c009776dae5ccbdfb93d7151ff2065ca049dc3Craig Mautner            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null,
113398341927f3dca68d71024483aa276d10af4c080Craig Mautner                    mDisplay.getDisplayId());
114ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.name = "drag";
115ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.inputChannel = mServerChannel;
116ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.layer = getDragLayerLw();
117ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.layoutParamsFlags = 0;
11895c42974f719d1fac90fc0438eac778e9795681fAdam Lesinski            mDragWindowHandle.layoutParamsPrivateFlags = 0;
119ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
120ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.dispatchingTimeoutNanos =
121ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
122ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.visible = true;
123ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.canReceiveKeys = false;
124ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.hasFocus = true;
125ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.hasWallpaper = false;
126ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.paused = false;
127ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.ownerPid = Process.myPid();
128ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.ownerUid = Process.myUid();
129ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.inputFeatures = 0;
130ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.scaleFactor = 1.0f;
131ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown
132ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            // The drag window cannot receive new touches.
133ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.touchableRegion.setEmpty();
134ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown
135ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            // The drag window covers the entire display
136ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.frameLeft = 0;
137ea4265512c3a2c352f6b99b65094138b96f6de75Jeff Brown            mDragWindowHandle.frameTop = 0;
138398341927f3dca68d71024483aa276d10af4c080Craig Mautner            Point p = new Point();
139398341927f3dca68d71024483aa276d10af4c080Craig Mautner            mDisplay.getRealSize(p);
140398341927f3dca68d71024483aa276d10af4c080Craig Mautner            mDragWindowHandle.frameRight = p.x;
141398341927f3dca68d71024483aa276d10af4c080Craig Mautner            mDragWindowHandle.frameBottom = p.y;
14201a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown
14301a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            // Pause rotations before a drag.
14401a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            if (WindowManagerService.DEBUG_ORIENTATION) {
14501a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown                Slog.d(WindowManagerService.TAG, "Pausing rotation during drag");
14601a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            }
14701a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            mService.pauseRotationLocked();
1486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
1496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
1506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
1516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void unregister() {
1526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "unregistering drag input channel");
1536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (mClientChannel == null) {
1546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel");
1556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } else {
1566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mService.mInputManager.unregisterInputChannel(mServerChannel);
15732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown            mInputEventReceiver.dispose();
15832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown            mInputEventReceiver = null;
1596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mClientChannel.dispose();
1606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mServerChannel.dispose();
1616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mClientChannel = null;
1626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mServerChannel = null;
163cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
164cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            mDragWindowHandle = null;
165cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            mDragApplicationHandle = null;
16601a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown
16701a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            // Resume rotations after a drag.
16801a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            if (WindowManagerService.DEBUG_ORIENTATION) {
16901a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown                Slog.d(WindowManagerService.TAG, "Resuming rotation after drag");
17001a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            }
17101a98ddbdfbaf1f0d2bc602537e6e314364902a3Jeff Brown            mService.resumeRotationLocked();
1726e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
1736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
1746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
1756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    int getDragLayerLw() {
1766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
1776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                * WindowManagerService.TYPE_LAYER_MULTIPLIER
1786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                + WindowManagerService.TYPE_LAYER_OFFSET;
1796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
1806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
1816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    /* call out to each visible window/session informing it about the drag
1826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     */
1836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void broadcastDragStartedLw(final float touchX, final float touchY) {
1846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // Cache a base-class instance of the clip metadata so that parceling
1856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // works correctly in calling out to the apps.
1866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mDataDescription = (mData != null) ? mData.getDescription() : null;
1876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mNotifiedWindows.clear();
1886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mDragInProgress = true;
1896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
1906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (WindowManagerService.DEBUG_DRAG) {
1916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.d(WindowManagerService.TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
1926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
1936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
1945c0e78c445ed4b12fec295f1c7f0799d1e79bf72Craig Mautner        final WindowList windows = mService.getWindowListLocked(mDisplay);
1952d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner        if (windows != null) {
1962d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner            final int N = windows.size();
1972d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner            for (int i = 0; i < N; i++) {
1982d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner                sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
1992d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner            }
2006e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
2026e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
2046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * designated window is potentially a drop recipient.  There are race situations
2056e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * around DRAG_ENDED broadcast, so we make sure that once we've declared that
2066e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * the drag has ended, we never send out another DRAG_STARTED for this drag action.
2076e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     *
2086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * This method clones the 'event' parameter if it's being delivered to the same
2096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * process, so it's safe for the caller to call recycle() on the event afterwards.
2106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     */
2116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
2126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            ClipDescription desc) {
2136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // Don't actually send the event if the drag is supposed to be pinned
2146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // to the originating window but 'newWin' is not that window.
2156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
2166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            final IBinder winBinder = newWin.mClient.asBinder();
2176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (winBinder != mLocalWin) {
2186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (WindowManagerService.DEBUG_DRAG) {
2196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    Slog.d(WindowManagerService.TAG, "Not dispatching local DRAG_STARTED to " + newWin);
2206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
2216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                return;
2226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
2236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (mDragInProgress && newWin.isPotentialDragTarget()) {
226ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn            DragEvent event = obtainDragEvent(newWin, DragEvent.ACTION_DRAG_STARTED,
227ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn                    touchX, touchY, null, desc, null, false);
2286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            try {
2296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                newWin.mClient.dispatchDragEvent(event);
2306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // track each window that we've notified that the drag is starting
2316e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                mNotifiedWindows.add(newWin);
2326e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            } catch (RemoteException e) {
2336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                Slog.w(WindowManagerService.TAG, "Unable to drag-start window " + newWin);
2346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            } finally {
2356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // if the callee was local, the dispatch has already recycled the event
2366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (Process.myPid() != newWin.mSession.mPid) {
2376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    event.recycle();
2386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
2396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
2406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
2426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2436e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    /* helper - construct and send a DRAG_STARTED event only if the window has not
2446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * previously been notified, i.e. it became visible after the drag operation
2456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     * was begun.  This is a rare case.
2466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn     */
2476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void sendDragStartedIfNeededLw(WindowState newWin) {
2486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (mDragInProgress) {
2496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            // If we have sent the drag-started, we needn't do so again
2506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            for (WindowState ws : mNotifiedWindows) {
2516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (ws == newWin) {
2526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    return;
2536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
2546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
2556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (WindowManagerService.DEBUG_DRAG) {
2566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                Slog.d(WindowManagerService.TAG, "need to send DRAG_STARTED to new window " + newWin);
2576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
2586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
2596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
2616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void broadcastDragEndedLw() {
2636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (WindowManagerService.DEBUG_DRAG) {
2646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED");
2656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
2676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                0, 0, null, null, null, mDragResult);
2686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        for (WindowState ws: mNotifiedWindows) {
2696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            try {
2706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                ws.mClient.dispatchDragEvent(evt);
2716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            } catch (RemoteException e) {
2726e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                Slog.w(WindowManagerService.TAG, "Unable to drag-end window " + ws);
2736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
2746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
2756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mNotifiedWindows.clear();
2766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mDragInProgress = false;
2776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        evt.recycle();
2786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
2796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void endDragLw() {
2816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService.mDragState.broadcastDragEndedLw();
2826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // stop intercepting input
2846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService.mDragState.unregister();
2856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
2866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // free our resources and drop all the object references
2886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService.mDragState.reset();
2896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mService.mDragState = null;
2906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
2916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    void notifyMoveLw(float x, float y) {
2936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final int myPid = Process.myPid();
2946e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
2956e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // Move the surface to the given touch
29636991744a221c30a47085442e6416bdde40b85e8Dianne Hackborn        if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
29736991744a221c30a47085442e6416bdde40b85e8Dianne Hackborn                WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
2983866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        SurfaceControl.openTransaction();
2996e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        try {
30029479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian            mSurfaceControl.setPosition(x - mThumbOffsetX, y - mThumbOffsetY);
3016e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "  DRAG "
30229479ebe1007361222bf6ab4d5e2a27927d4b8e8Mathias Agopian                    + mSurfaceControl + ": pos=(" +
3036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
3046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } finally {
3053866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            SurfaceControl.closeTransaction();
30636991744a221c30a47085442e6416bdde40b85e8Dianne Hackborn            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(
30736991744a221c30a47085442e6416bdde40b85e8Dianne Hackborn                    WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
3086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
3106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        // Tell the affected window
3116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        WindowState touchedWin = getTouchedWinAtPointLw(x, y);
3126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (touchedWin == null) {
3136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "No touched win at x=" + x + " y=" + y);
3146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            return;
3156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
3176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            final IBinder touchedBinder = touchedWin.mClient.asBinder();
3186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (touchedBinder != mLocalWin) {
3196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // This drag is pinned only to the originating window, but the drag
3206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // point is outside that window.  Pretend it's over empty space.
3216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                touchedWin = null;
3226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
3236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        try {
3256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            // have we dragged over a new window?
3266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
3276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (WindowManagerService.DEBUG_DRAG) {
3286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow);
3296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
3306e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // force DRAG_EXITED_EVENT if appropriate
331ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn                DragEvent evt = obtainDragEvent(mTargetWindow, DragEvent.ACTION_DRAG_EXITED,
332ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn                        x, y, null, null, null, false);
3336e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                mTargetWindow.mClient.dispatchDragEvent(evt);
3346e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (myPid != mTargetWindow.mSession.mPid) {
3356e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    evt.recycle();
3366e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
3376e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
3386e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (touchedWin != null) {
3396e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (false && WindowManagerService.DEBUG_DRAG) {
3406e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin);
3416e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
342ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn                DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DRAG_LOCATION,
343ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn                        x, y, null, null, null, false);
3446e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                touchedWin.mClient.dispatchDragEvent(evt);
3456e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                if (myPid != touchedWin.mSession.mPid) {
3466e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    evt.recycle();
3476e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                }
3486e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
3496e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } catch (RemoteException e) {
3506e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.w(WindowManagerService.TAG, "can't send drag notification to windows");
3516e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3526e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mTargetWindow = touchedWin;
3536e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
3546e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
3556e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    // Tell the drop target about the data.  Returns 'true' if we can immediately
3566e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    // dispatch the global drag-ended message, 'false' if we need to wait for a
3576e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    // result from the recipient.
3586e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    boolean notifyDropLw(float x, float y) {
3596e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        WindowState touchedWin = getTouchedWinAtPointLw(x, y);
3606e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (touchedWin == null) {
3616e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            // "drop" outside a valid window -- no recipient to apply a
3626e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            // timeout to, and we can send the drag-ended message immediately.
3636e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mDragResult = false;
3646e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            return true;
3656e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3666e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
3676e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        if (WindowManagerService.DEBUG_DRAG) {
3686e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.d(WindowManagerService.TAG, "sending DROP to " + touchedWin);
3696e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3706e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final int myPid = Process.myPid();
3716e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final IBinder token = touchedWin.mClient.asBinder();
372ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
3736e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                null, null, mData, false);
3746e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        try {
3756e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            touchedWin.mClient.dispatchDragEvent(evt);
3766e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
3776e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            // 5 second timeout for this window to respond to the drop
3786e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mService.mH.removeMessages(H.DRAG_END_TIMEOUT, token);
3796e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Message msg = mService.mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
3806e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            mService.mH.sendMessageDelayed(msg, 5000);
3816e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } catch (RemoteException e) {
3826e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            Slog.w(WindowManagerService.TAG, "can't send drop notification to win " + touchedWin);
3836e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            return true;
3846e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        } finally {
3856e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (myPid != touchedWin.mSession.mPid) {
3866e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                evt.recycle();
3876e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
3886e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
3896e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        mToken = token;
3906e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        return false;
3916e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
3926e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
3936e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    // Find the visible, touch-deliverable window under the given point
3946e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    private WindowState getTouchedWinAtPointLw(float xf, float yf) {
3956e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        WindowState touchedWin = null;
3966e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final int x = (int) xf;
3976e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final int y = (int) yf;
39859c009776dae5ccbdfb93d7151ff2065ca049dc3Craig Mautner
3995c0e78c445ed4b12fec295f1c7f0799d1e79bf72Craig Mautner        final WindowList windows = mService.getWindowListLocked(mDisplay);
4002d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner        if (windows == null) {
4012d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner            return null;
4022d5618c22101cfc4d6478cfe1d846798389540c1Craig Mautner        }
4036e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        final int N = windows.size();
4046e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        for (int i = N - 1; i >= 0; i--) {
4056e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            WindowState child = windows.get(i);
4066e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            final int flags = child.mAttrs.flags;
4076e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (!child.isVisibleLw()) {
4086e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // not visible == don't tell about drags
4096e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                continue;
4106e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
4116e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
4126e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // not touchable == don't tell about drags
4136e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                continue;
4146e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
4156e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
4166e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            child.getTouchableRegion(mTmpRegion);
4176e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
4186e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            final int touchFlags = flags &
4196e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                    (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
4206e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
4216e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
4226e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                // Found it
4236e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                touchedWin = child;
4246e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn                break;
4256e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn            }
4266e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        }
4276e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn
4286e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn        return touchedWin;
4296e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn    }
430ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn
431ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn    private static DragEvent obtainDragEvent(WindowState win, int action,
432ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn            float x, float y, Object localState,
433ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn            ClipDescription description, ClipData data, boolean result) {
434ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        float winX = x - win.mFrame.left;
435ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        float winY = y - win.mFrame.top;
436ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        if (win.mEnforceSizeCompat) {
437ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn            winX *= win.mGlobalScale;
438ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn            winY *= win.mGlobalScale;
439ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        }
440ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn        return DragEvent.obtain(action, winX, winY, localState, description, data, result);
441ffb3d939cc78cae523f14a0f8ab37061b5bffc20Dianne Hackborn    }
4426e1eb76f02ccc9dbc309b938f62d39312da8cafeDianne Hackborn}