RecentsViewTouchHandler.java revision 6519c1b0fe85c5f25115539e936e4333e8537098
1be7607af8875236b9cf7bdb5f5aa089c207529afWinson/* 2be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Copyright (C) 2014 The Android Open Source Project 3be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 4be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Licensed under the Apache License, Version 2.0 (the "License"); 5be7607af8875236b9cf7bdb5f5aa089c207529afWinson * you may not use this file except in compliance with the License. 6be7607af8875236b9cf7bdb5f5aa089c207529afWinson * You may obtain a copy of the License at 7be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 8be7607af8875236b9cf7bdb5f5aa089c207529afWinson * http://www.apache.org/licenses/LICENSE-2.0 9be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 10be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Unless required by applicable law or agreed to in writing, software 11be7607af8875236b9cf7bdb5f5aa089c207529afWinson * distributed under the License is distributed on an "AS IS" BASIS, 12be7607af8875236b9cf7bdb5f5aa089c207529afWinson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be7607af8875236b9cf7bdb5f5aa089c207529afWinson * See the License for the specific language governing permissions and 14be7607af8875236b9cf7bdb5f5aa089c207529afWinson * limitations under the License. 15be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 16be7607af8875236b9cf7bdb5f5aa089c207529afWinson 17be7607af8875236b9cf7bdb5f5aa089c207529afWinsonpackage com.android.systemui.recents.views; 18be7607af8875236b9cf7bdb5f5aa089c207529afWinson 19c694a509ff768b6a942616676dd8103e20d06e66Winsonimport android.app.ActivityManager; 20be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.graphics.Point; 2119cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport android.graphics.Rect; 22131d53a7d817560ad06b5f26dc64a2969aeed53fWinsonimport android.view.InputDevice; 23be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.view.MotionEvent; 24131d53a7d817560ad06b5f26dc64a2969aeed53fWinsonimport android.view.PointerIcon; 259e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ngimport android.view.View; 263e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winsonimport android.view.ViewConfiguration; 27231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinsonimport android.view.ViewDebug; 28c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson 2919cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport com.android.internal.policy.DividerSnapAlgorithm; 3053ec42cb17693b2d631746e1e5d31021a3359163Winsonimport com.android.systemui.recents.Recents; 31be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.EventBus; 3219cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport com.android.systemui.recents.events.activity.ConfigurationChangedEvent; 333975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ngimport com.android.systemui.recents.events.activity.HideRecentsEvent; 349e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ngimport com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent; 359b001396c26e5b5ee95e0a54213a8a421179e365Winsonimport com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent; 369b001396c26e5b5ee95e0a54213a8a421179e365Winsonimport com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent; 37eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent; 38be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; 39be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; 40eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent; 41d759a7123a7cacf431399b310421c59a6c818e53Winsonimport com.android.systemui.recents.misc.SystemServicesProxy; 426519c1b0fe85c5f25115539e936e4333e8537098Winson Chungimport com.android.systemui.shared.recents.model.Task; 436519c1b0fe85c5f25115539e936e4333e8537098Winson Chungimport com.android.systemui.shared.recents.model.TaskStack; 44be7607af8875236b9cf7bdb5f5aa089c207529afWinson 45eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport java.util.ArrayList; 46eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 47be7607af8875236b9cf7bdb5f5aa089c207529afWinson/** 48be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Handles touch events for a RecentsView. 49be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 50eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonpublic class RecentsViewTouchHandler { 51eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 52be7607af8875236b9cf7bdb5f5aa089c207529afWinson private RecentsView mRv; 53be7607af8875236b9cf7bdb5f5aa089c207529afWinson 54231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task") 55be7607af8875236b9cf7bdb5f5aa089c207529afWinson private Task mDragTask; 56231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task_view_") 57be7607af8875236b9cf7bdb5f5aa089c207529afWinson private TaskView mTaskView; 58be7607af8875236b9cf7bdb5f5aa089c207529afWinson 59231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 60479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson private Point mTaskViewOffset = new Point(); 61231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 62be7607af8875236b9cf7bdb5f5aa089c207529afWinson private Point mDownPos = new Point(); 63231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 643e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private boolean mDragRequested; 65231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 663e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private boolean mIsDragging; 673e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private float mDragSlop; 68131d53a7d817560ad06b5f26dc64a2969aeed53fWinson private int mDeviceId = -1; 69eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 70eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson private DropTarget mLastDropTarget; 7119cf2972582198484816ac15ba83a4f46946082bJorim Jaggi private DividerSnapAlgorithm mDividerSnapAlgorithm; 72eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson private ArrayList<DropTarget> mDropTargets = new ArrayList<>(); 736519c1b0fe85c5f25115539e936e4333e8537098Winson Chung private ArrayList<DockState> mVisibleDockStates = new ArrayList<>(); 74be7607af8875236b9cf7bdb5f5aa089c207529afWinson 75be7607af8875236b9cf7bdb5f5aa089c207529afWinson public RecentsViewTouchHandler(RecentsView rv) { 76be7607af8875236b9cf7bdb5f5aa089c207529afWinson mRv = rv; 773e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragSlop = ViewConfiguration.get(rv.getContext()).getScaledTouchSlop(); 7819cf2972582198484816ac15ba83a4f46946082bJorim Jaggi updateSnapAlgorithm(); 7919cf2972582198484816ac15ba83a4f46946082bJorim Jaggi } 8019cf2972582198484816ac15ba83a4f46946082bJorim Jaggi 8119cf2972582198484816ac15ba83a4f46946082bJorim Jaggi private void updateSnapAlgorithm() { 8219cf2972582198484816ac15ba83a4f46946082bJorim Jaggi Rect insets = new Rect(); 8319cf2972582198484816ac15ba83a4f46946082bJorim Jaggi SystemServicesProxy.getInstance(mRv.getContext()).getStableInsets(insets); 8419cf2972582198484816ac15ba83a4f46946082bJorim Jaggi mDividerSnapAlgorithm = DividerSnapAlgorithm.create(mRv.getContext(), insets); 85be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 86be7607af8875236b9cf7bdb5f5aa089c207529afWinson 87882072baacaee4ecd43f0209b691a9af746462f2Winson /** 88eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson * Registers a new drop target for the current drag only. 89eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson */ 90eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public void registerDropTargetForCurrentDrag(DropTarget target) { 91eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mDropTargets.add(target); 92eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 93eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 94eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson /** 95036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson * Returns the set of visible dock states for this current drag. 96036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson */ 976519c1b0fe85c5f25115539e936e4333e8537098Winson Chung public ArrayList<DockState> getVisibleDockStates() { 98036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson return mVisibleDockStates; 99036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson } 100036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson 101be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** Touch preprocessing for handling below */ 102be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean onInterceptTouchEvent(MotionEvent ev) { 1039e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return handleTouchEvent(ev) || mDragRequested; 104be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 105be7607af8875236b9cf7bdb5f5aa089c207529afWinson 106be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** Handles touch events once we have intercepted them */ 107be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean onTouchEvent(MotionEvent ev) { 1084165d336b6cd69715eda7fbdfd272a878097170eWinson handleTouchEvent(ev); 1093975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng if (ev.getAction() == MotionEvent.ACTION_UP && mRv.getStack().getStackTaskCount() == 0) { 1103975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng EventBus.getDefault().send(new HideRecentsEvent(false, true)); 1113975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng } 1123975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng return true; 1134165d336b6cd69715eda7fbdfd272a878097170eWinson } 1144165d336b6cd69715eda7fbdfd272a878097170eWinson 1154165d336b6cd69715eda7fbdfd272a878097170eWinson /**** Events ****/ 1164165d336b6cd69715eda7fbdfd272a878097170eWinson 1174165d336b6cd69715eda7fbdfd272a878097170eWinson public final void onBusEvent(DragStartEvent event) { 118d759a7123a7cacf431399b310421c59a6c818e53Winson SystemServicesProxy ssp = Recents.getSystemServices(); 1194165d336b6cd69715eda7fbdfd272a878097170eWinson mRv.getParent().requestDisallowInterceptTouchEvent(true); 1203e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragRequested = true; 1213e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // We defer starting the actual drag handling until the user moves past the drag slop 1223e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mIsDragging = false; 1234165d336b6cd69715eda7fbdfd272a878097170eWinson mDragTask = event.task; 1244165d336b6cd69715eda7fbdfd272a878097170eWinson mTaskView = event.taskView; 125eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mDropTargets.clear(); 1264165d336b6cd69715eda7fbdfd272a878097170eWinson 127479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson int[] recentsViewLocation = new int[2]; 128479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mRv.getLocationInWindow(recentsViewLocation); 129479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskViewOffset.set(mTaskView.getLeft() - recentsViewLocation[0] + event.tlOffset.x, 130479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.getTop() - recentsViewLocation[1] + event.tlOffset.y); 131b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng 132b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng // Change space coordinates relative to the view to RecentsView when user initiates a touch 133b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng if (event.isUserTouchInitiated) { 134b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng float x = mDownPos.x - mTaskViewOffset.x; 135b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng float y = mDownPos.y - mTaskViewOffset.y; 136b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng mTaskView.setTranslationX(x); 137b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng mTaskView.setTranslationY(y); 138b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng } 139eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 140036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson mVisibleDockStates.clear(); 1419be3a060827154617eed9132c64431af56d98eb4Erik Wolsheimer if (ActivityManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask() 14219cf2972582198484816ac15ba83a4f46946082bJorim Jaggi && mDividerSnapAlgorithm.isSplitScreenFeasible()) { 143f21c3dace89b168f5e5e4e96532d977b8b0a1cf5Winson Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(), 144f21c3dace89b168f5e5e4e96532d977b8b0a1cf5Winson event.task.resizeMode); 145931845fcb3823ce175fcfc7c6ce2d9751102c331Winson if (!event.task.isDockable) { 1469b001396c26e5b5ee95e0a54213a8a421179e365Winson EventBus.getDefault().send(new ShowIncompatibleAppOverlayEvent()); 147931845fcb3823ce175fcfc7c6ce2d9751102c331Winson } else { 148931845fcb3823ce175fcfc7c6ce2d9751102c331Winson // Add the dock state drop targets (these take priority) 1496519c1b0fe85c5f25115539e936e4333e8537098Winson Chung DockState[] dockStates = Recents.getConfiguration() 150b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng .getDockStatesForCurrentOrientation(); 1516519c1b0fe85c5f25115539e936e4333e8537098Winson Chung for (DockState dockState : dockStates) { 152931845fcb3823ce175fcfc7c6ce2d9751102c331Winson registerDropTargetForCurrentDrag(dockState); 15399ef458ff1b79c93a8dfdc289fb6ff80fd7aacf6Winson dockState.update(mRv.getContext()); 154931845fcb3823ce175fcfc7c6ce2d9751102c331Winson mVisibleDockStates.add(dockState); 155931845fcb3823ce175fcfc7c6ce2d9751102c331Winson } 156eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 157eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 158eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 159eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Request other drop targets to register themselves 160d952961977a0eb6c1fefcb0707d1c61741515f68Winson EventBus.getDefault().send(new DragStartInitializeDropTargetsEvent(event.task, 161d952961977a0eb6c1fefcb0707d1c61741515f68Winson event.taskView, this)); 162131d53a7d817560ad06b5f26dc64a2969aeed53fWinson if (mDeviceId != -1) { 163df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung InputDevice device = InputDevice.getDevice(mDeviceId); 164df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung if (device != null) { 165df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung device.setPointerType(PointerIcon.TYPE_GRABBING); 166df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung } 167131d53a7d817560ad06b5f26dc64a2969aeed53fWinson } 1684165d336b6cd69715eda7fbdfd272a878097170eWinson } 1694165d336b6cd69715eda7fbdfd272a878097170eWinson 1704165d336b6cd69715eda7fbdfd272a878097170eWinson public final void onBusEvent(DragEndEvent event) { 1719b001396c26e5b5ee95e0a54213a8a421179e365Winson if (!mDragTask.isDockable) { 1729b001396c26e5b5ee95e0a54213a8a421179e365Winson EventBus.getDefault().send(new HideIncompatibleAppOverlayEvent()); 1739b001396c26e5b5ee95e0a54213a8a421179e365Winson } 1743e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragRequested = false; 1754165d336b6cd69715eda7fbdfd272a878097170eWinson mDragTask = null; 1764165d336b6cd69715eda7fbdfd272a878097170eWinson mTaskView = null; 177eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mLastDropTarget = null; 1784165d336b6cd69715eda7fbdfd272a878097170eWinson } 179be7607af8875236b9cf7bdb5f5aa089c207529afWinson 18019cf2972582198484816ac15ba83a4f46946082bJorim Jaggi public final void onBusEvent(ConfigurationChangedEvent event) { 1819832f8f463a7d5448af2294bce05eac85f4dbef0Winson if (event.fromDisplayDensityChange || event.fromDeviceOrientationChange) { 18225160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi updateSnapAlgorithm(); 18325160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi } 18419cf2972582198484816ac15ba83a4f46946082bJorim Jaggi } 18519cf2972582198484816ac15ba83a4f46946082bJorim Jaggi 1869e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng void cancelStackActionButtonClick() { 1879e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().setPressed(false); 1889e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 1899e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 1909e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private boolean isWithinStackActionButton(float x, float y) { 1919e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng Rect rect = mRv.getStackActionButtonBoundsFromStackLayout(); 1929e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return mRv.getStackActionButton().getVisibility() == View.VISIBLE && 1939e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().pointInView(x - rect.left, y - rect.top, 0 /* slop */); 1949e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 1959e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 1969e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private void changeStackActionButtonDrawableHotspot(float x, float y) { 1979e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng Rect rect = mRv.getStackActionButtonBoundsFromStackLayout(); 1989e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().drawableHotspotChanged(x - rect.left, y - rect.top); 1999e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 2009e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2014165d336b6cd69715eda7fbdfd272a878097170eWinson /** 2024165d336b6cd69715eda7fbdfd272a878097170eWinson * Handles dragging touch events 2034165d336b6cd69715eda7fbdfd272a878097170eWinson */ 2049e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private boolean handleTouchEvent(MotionEvent ev) { 205a20eeda52951021da758fefba7bf956c9c9d15a2Jorim Jaggi int action = ev.getActionMasked(); 2069e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng boolean consumed = false; 2079e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng float evX = ev.getX(); 2089e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng float evY = ev.getY(); 209a20eeda52951021da758fefba7bf956c9c9d15a2Jorim Jaggi switch (action) { 210be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_DOWN: 2119e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mDownPos.set((int) evX, (int) evY); 212131d53a7d817560ad06b5f26dc64a2969aeed53fWinson mDeviceId = ev.getDeviceId(); 2139e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2149e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (isWithinStackActionButton(evX, evY)) { 2159e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng changeStackActionButtonDrawableHotspot(evX, evY); 2169e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().setPressed(true); 2179e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 218be7607af8875236b9cf7bdb5f5aa089c207529afWinson break; 219be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_MOVE: { 2203e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson float x = evX - mTaskViewOffset.x; 2213e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson float y = evY - mTaskViewOffset.y; 2223e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2239e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) { 2249e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng changeStackActionButtonDrawableHotspot(evX, evY); 2259e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 2269e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2273e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mDragRequested) { 2283e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (!mIsDragging) { 2293e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mIsDragging = Math.hypot(evX - mDownPos.x, evY - mDownPos.y) > mDragSlop; 2304165d336b6cd69715eda7fbdfd272a878097170eWinson } 2313e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mIsDragging) { 2323e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson int width = mRv.getMeasuredWidth(); 2333e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson int height = mRv.getMeasuredHeight(); 2343e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2353e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson DropTarget currentDropTarget = null; 2363e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2373e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // Give priority to the current drop target to retain the touch handling 2383e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget != null) { 2393e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget.acceptsDrop((int) evX, (int) evY, width, height, 24008deff0a67bd1e2d44477ed7c84c39fb3299fb7cWinson mRv.mSystemInsets, true /* isCurrentTarget */)) { 2413e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget = mLastDropTarget; 2423e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2433e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2443e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2453e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // Otherwise, find the next target to handle this event 2463e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (currentDropTarget == null) { 2473e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson for (DropTarget target : mDropTargets) { 2483e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (target.acceptsDrop((int) evX, (int) evY, width, height, 24908deff0a67bd1e2d44477ed7c84c39fb3299fb7cWinson mRv.mSystemInsets, false /* isCurrentTarget */)) { 2503e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget = target; 2513e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson break; 2523e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2533e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2543e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2553e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget != currentDropTarget) { 2563e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mLastDropTarget = currentDropTarget; 2573e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, 2583e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget)); 2593e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 260be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 261479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.setTranslationX(x); 262479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.setTranslationY(y); 2634165d336b6cd69715eda7fbdfd272a878097170eWinson } 264be7607af8875236b9cf7bdb5f5aa089c207529afWinson break; 265be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 266be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_UP: 267be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_CANCEL: { 2689e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) { 2699e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng EventBus.getDefault().send(new DismissAllTaskViewsEvent()); 2709e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng consumed = true; 2719e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 2729e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng cancelStackActionButtonClick(); 2733e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mDragRequested) { 274f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi boolean cancelled = action == MotionEvent.ACTION_CANCEL; 275f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi if (cancelled) { 276f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, null)); 277f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi } 278479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, 279f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi !cancelled ? mLastDropTarget : null)); 28009d8a184c6d9d996663da1756ab4ac7d54c04b45Winson break; 28109d8a184c6d9d996663da1756ab4ac7d54c04b45Winson } 282131d53a7d817560ad06b5f26dc64a2969aeed53fWinson mDeviceId = -1; 283be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 284be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 2859e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return consumed; 286be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 287be7607af8875236b9cf7bdb5f5aa089c207529afWinson} 288