Loading services/core/java/com/android/server/wm/DragInputEventReceiver.java 0 → 100644 +151 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static android.view.InputDevice.SOURCE_CLASS_POINTER; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.BUTTON_STYLUS_PRIMARY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.os.Looper; import android.util.Slog; import android.view.InputChannel; import android.view.InputDevice; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.MotionEvent; /** * Input receiver for drag and drop */ class DragInputEventReceiver extends InputEventReceiver { private final WindowManagerService mService; private final DragDropController mDragDropController; // Set, if stylus button was down at the start of the drag. private boolean mStylusButtonDownAtStart; // Indicates the first event to check for button state. private boolean mIsStartEvent = true; // Set to true to ignore input events after the drag gesture is complete but the drag events // are still being dispatched. private boolean mMuteInput = false; public DragInputEventReceiver(InputChannel inputChannel, Looper looper, DragDropController controller, WindowManagerService service) { super(inputChannel, looper); mDragDropController = controller; mService = service; } @Override public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { synchronized (mService.mWindowMap) { if (!mDragDropController.dragDropActiveLocked()) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager // has a chance to clean-up the input handle. handled = true; return; } if (!(event instanceof MotionEvent) || (event.getSource() & SOURCE_CLASS_POINTER) == 0 || mMuteInput) { return; } final MotionEvent motionEvent = (MotionEvent) event; boolean endDrag = false; final float newX = motionEvent.getRawX(); final float newY = motionEvent.getRawY(); final boolean isStylusButtonDown = (motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0; if (mIsStartEvent) { if (isStylusButtonDown) { // First event and the button was down, check for the button being // lifted in the future, if that happens we'll drop the item. mStylusButtonDownAtStart = true; } mIsStartEvent = false; } switch (motionEvent.getAction()) { case ACTION_DOWN: { if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer"); } break; case ACTION_MOVE: { if (mStylusButtonDownAtStart && !isStylusButtonDown) { if (DEBUG_DRAG) { Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + "," + newY); } mMuteInput = true; endDrag = mDragDropController.mDragState .notifyDropLocked(newX, newY); } else { // move the surface and tell the involved window(s) where we are mDragDropController.mDragState.notifyMoveLocked(newX, newY); } } break; case ACTION_UP: { if (DEBUG_DRAG) { Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY); } mMuteInput = true; endDrag = mDragDropController.mDragState .notifyDropLocked(newX, newY); } break; case ACTION_CANCEL: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!"); mMuteInput = true; endDrag = true; } break; } if (endDrag) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state"); // tell all the windows that the drag has ended // endDragLocked will post back to looper to dispose the receiver // since we still need the receiver for the last finishInputEvent. mDragDropController.mDragState.endDragLocked(); mStylusButtonDownAtStart = false; mIsStartEvent = true; } handled = true; } } catch (Exception e) { Slog.e(TAG_WM, "Exception caught by drag handleMotion", e); } finally { finishInputEvent(event, handled); } } } services/core/java/com/android/server/wm/DragState.java +2 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ import android.view.animation.Interpolator; import com.android.internal.view.IDragAndDropPermissions; import com.android.server.input.InputApplicationHandle; import com.android.server.input.InputWindowHandle; import com.android.server.wm.WindowManagerService.DragInputEventReceiver; import java.util.ArrayList; Loading Loading @@ -151,8 +150,8 @@ class DragState { mServerChannel = channels[0]; mClientChannel = channels[1]; mService.mInputManager.registerInputChannel(mServerChannel, null); mInputEventReceiver = mService.new DragInputEventReceiver(mClientChannel, mService.mH.getLooper()); mInputEventReceiver = new DragInputEventReceiver(mClientChannel, mService.mH.getLooper(), mDragDropController, mService); mDragApplicationHandle = new InputApplicationHandle(null); mDragApplicationHandle.name = "drag"; Loading services/core/java/com/android/server/wm/WindowManagerService.java +0 −104 Original line number Diff line number Diff line Loading @@ -771,110 +771,6 @@ public class WindowManagerService extends IWindowManager.Stub private WindowContentFrameStats mTempWindowRenderStats; final class DragInputEventReceiver extends InputEventReceiver { // Set, if stylus button was down at the start of the drag. private boolean mStylusButtonDownAtStart; // Indicates the first event to check for button state. private boolean mIsStartEvent = true; // Set to true to ignore input events after the drag gesture is complete but the drag events // are still being dispatched. private boolean mMuteInput = false; public DragInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); } @Override public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { if (mDragDropController.mDragState == null) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager // has a chance to clean-up the input handle. handled = true; return; } if (event instanceof MotionEvent && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 && !mMuteInput) { final MotionEvent motionEvent = (MotionEvent)event; boolean endDrag = false; final float newX = motionEvent.getRawX(); final float newY = motionEvent.getRawY(); final boolean isStylusButtonDown = (motionEvent.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0; if (mIsStartEvent) { if (isStylusButtonDown) { // First event and the button was down, check for the button being // lifted in the future, if that happens we'll drop the item. mStylusButtonDownAtStart = true; } mIsStartEvent = false; } switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: { if (DEBUG_DRAG) { Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer"); } } break; case MotionEvent.ACTION_MOVE: { if (mStylusButtonDownAtStart && !isStylusButtonDown) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { endDrag = mDragDropController.mDragState.notifyDropLocked(newX, newY); } } else { synchronized (mWindowMap) { // move the surface and tell the involved window(s) where we are mDragDropController.mDragState.notifyMoveLocked(newX, newY); } } } break; case MotionEvent.ACTION_UP: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { endDrag = mDragDropController.mDragState.notifyDropLocked(newX, newY); } } break; case MotionEvent.ACTION_CANCEL: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!"); mMuteInput = true; endDrag = true; } break; } if (endDrag) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state"); // tell all the windows that the drag has ended synchronized (mWindowMap) { // endDragLocked will post back to looper to dispose the receiver // since we still need the receiver for the last finishInputEvent. mDragDropController.mDragState.endDragLocked(); } mStylusButtonDownAtStart = false; mIsStartEvent = true; } handled = true; } } catch (Exception e) { Slog.e(TAG_WM, "Exception caught by drag handleMotion", e); } finally { finishInputEvent(event, handled); } } } /** * Whether the UI is currently running in touch mode (not showing * navigational focus because the user is directly pressing the screen). Loading Loading
services/core/java/com/android/server/wm/DragInputEventReceiver.java 0 → 100644 +151 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static android.view.InputDevice.SOURCE_CLASS_POINTER; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_UP; import static android.view.MotionEvent.BUTTON_STYLUS_PRIMARY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.os.Looper; import android.util.Slog; import android.view.InputChannel; import android.view.InputDevice; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.MotionEvent; /** * Input receiver for drag and drop */ class DragInputEventReceiver extends InputEventReceiver { private final WindowManagerService mService; private final DragDropController mDragDropController; // Set, if stylus button was down at the start of the drag. private boolean mStylusButtonDownAtStart; // Indicates the first event to check for button state. private boolean mIsStartEvent = true; // Set to true to ignore input events after the drag gesture is complete but the drag events // are still being dispatched. private boolean mMuteInput = false; public DragInputEventReceiver(InputChannel inputChannel, Looper looper, DragDropController controller, WindowManagerService service) { super(inputChannel, looper); mDragDropController = controller; mService = service; } @Override public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { synchronized (mService.mWindowMap) { if (!mDragDropController.dragDropActiveLocked()) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager // has a chance to clean-up the input handle. handled = true; return; } if (!(event instanceof MotionEvent) || (event.getSource() & SOURCE_CLASS_POINTER) == 0 || mMuteInput) { return; } final MotionEvent motionEvent = (MotionEvent) event; boolean endDrag = false; final float newX = motionEvent.getRawX(); final float newY = motionEvent.getRawY(); final boolean isStylusButtonDown = (motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0; if (mIsStartEvent) { if (isStylusButtonDown) { // First event and the button was down, check for the button being // lifted in the future, if that happens we'll drop the item. mStylusButtonDownAtStart = true; } mIsStartEvent = false; } switch (motionEvent.getAction()) { case ACTION_DOWN: { if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer"); } break; case ACTION_MOVE: { if (mStylusButtonDownAtStart && !isStylusButtonDown) { if (DEBUG_DRAG) { Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + "," + newY); } mMuteInput = true; endDrag = mDragDropController.mDragState .notifyDropLocked(newX, newY); } else { // move the surface and tell the involved window(s) where we are mDragDropController.mDragState.notifyMoveLocked(newX, newY); } } break; case ACTION_UP: { if (DEBUG_DRAG) { Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY); } mMuteInput = true; endDrag = mDragDropController.mDragState .notifyDropLocked(newX, newY); } break; case ACTION_CANCEL: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!"); mMuteInput = true; endDrag = true; } break; } if (endDrag) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state"); // tell all the windows that the drag has ended // endDragLocked will post back to looper to dispose the receiver // since we still need the receiver for the last finishInputEvent. mDragDropController.mDragState.endDragLocked(); mStylusButtonDownAtStart = false; mIsStartEvent = true; } handled = true; } } catch (Exception e) { Slog.e(TAG_WM, "Exception caught by drag handleMotion", e); } finally { finishInputEvent(event, handled); } } }
services/core/java/com/android/server/wm/DragState.java +2 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,6 @@ import android.view.animation.Interpolator; import com.android.internal.view.IDragAndDropPermissions; import com.android.server.input.InputApplicationHandle; import com.android.server.input.InputWindowHandle; import com.android.server.wm.WindowManagerService.DragInputEventReceiver; import java.util.ArrayList; Loading Loading @@ -151,8 +150,8 @@ class DragState { mServerChannel = channels[0]; mClientChannel = channels[1]; mService.mInputManager.registerInputChannel(mServerChannel, null); mInputEventReceiver = mService.new DragInputEventReceiver(mClientChannel, mService.mH.getLooper()); mInputEventReceiver = new DragInputEventReceiver(mClientChannel, mService.mH.getLooper(), mDragDropController, mService); mDragApplicationHandle = new InputApplicationHandle(null); mDragApplicationHandle.name = "drag"; Loading
services/core/java/com/android/server/wm/WindowManagerService.java +0 −104 Original line number Diff line number Diff line Loading @@ -771,110 +771,6 @@ public class WindowManagerService extends IWindowManager.Stub private WindowContentFrameStats mTempWindowRenderStats; final class DragInputEventReceiver extends InputEventReceiver { // Set, if stylus button was down at the start of the drag. private boolean mStylusButtonDownAtStart; // Indicates the first event to check for button state. private boolean mIsStartEvent = true; // Set to true to ignore input events after the drag gesture is complete but the drag events // are still being dispatched. private boolean mMuteInput = false; public DragInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); } @Override public void onInputEvent(InputEvent event, int displayId) { boolean handled = false; try { if (mDragDropController.mDragState == null) { // The drag has ended but the clean-up message has not been processed by // window manager. Drop events that occur after this until window manager // has a chance to clean-up the input handle. handled = true; return; } if (event instanceof MotionEvent && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 && !mMuteInput) { final MotionEvent motionEvent = (MotionEvent)event; boolean endDrag = false; final float newX = motionEvent.getRawX(); final float newY = motionEvent.getRawY(); final boolean isStylusButtonDown = (motionEvent.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0; if (mIsStartEvent) { if (isStylusButtonDown) { // First event and the button was down, check for the button being // lifted in the future, if that happens we'll drop the item. mStylusButtonDownAtStart = true; } mIsStartEvent = false; } switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: { if (DEBUG_DRAG) { Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer"); } } break; case MotionEvent.ACTION_MOVE: { if (mStylusButtonDownAtStart && !isStylusButtonDown) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { endDrag = mDragDropController.mDragState.notifyDropLocked(newX, newY); } } else { synchronized (mWindowMap) { // move the surface and tell the involved window(s) where we are mDragDropController.mDragState.notifyMoveLocked(newX, newY); } } } break; case MotionEvent.ACTION_UP: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY); mMuteInput = true; synchronized (mWindowMap) { endDrag = mDragDropController.mDragState.notifyDropLocked(newX, newY); } } break; case MotionEvent.ACTION_CANCEL: { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!"); mMuteInput = true; endDrag = true; } break; } if (endDrag) { if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state"); // tell all the windows that the drag has ended synchronized (mWindowMap) { // endDragLocked will post back to looper to dispose the receiver // since we still need the receiver for the last finishInputEvent. mDragDropController.mDragState.endDragLocked(); } mStylusButtonDownAtStart = false; mIsStartEvent = true; } handled = true; } } catch (Exception e) { Slog.e(TAG_WM, "Exception caught by drag handleMotion", e); } finally { finishInputEvent(event, handled); } } } /** * Whether the UI is currently running in touch mode (not showing * navigational focus because the user is directly pressing the screen). Loading