blob: bee2bacf83d2e7fa210e35c99e67ef32a1a031eb [file] [log] [blame]
Daichi Hirono52cb2152017-09-11 15:29:42 +09001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wm;
18
19import static android.view.InputDevice.SOURCE_CLASS_POINTER;
20import static android.view.MotionEvent.ACTION_CANCEL;
21import static android.view.MotionEvent.ACTION_DOWN;
22import static android.view.MotionEvent.ACTION_MOVE;
23import static android.view.MotionEvent.ACTION_UP;
24import static android.view.MotionEvent.BUTTON_STYLUS_PRIMARY;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
26import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
27
28import android.os.Looper;
29import android.util.Slog;
30import android.view.InputChannel;
31import android.view.InputDevice;
32import android.view.InputEvent;
33import android.view.InputEventReceiver;
34import android.view.MotionEvent;
35
36/**
37 * Input receiver for drag and drop
38 */
39class DragInputEventReceiver extends InputEventReceiver {
Daichi Hirono52cb2152017-09-11 15:29:42 +090040 private final DragDropController mDragDropController;
41
42 // Set, if stylus button was down at the start of the drag.
43 private boolean mStylusButtonDownAtStart;
44 // Indicates the first event to check for button state.
45 private boolean mIsStartEvent = true;
46 // Set to true to ignore input events after the drag gesture is complete but the drag events
47 // are still being dispatched.
48 private boolean mMuteInput = false;
49
Daichi Hirono768012e2017-10-30 10:05:37 +090050 DragInputEventReceiver(InputChannel inputChannel, Looper looper,
51 DragDropController controller) {
Daichi Hirono52cb2152017-09-11 15:29:42 +090052 super(inputChannel, looper);
53 mDragDropController = controller;
Daichi Hirono52cb2152017-09-11 15:29:42 +090054 }
55
56 @Override
57 public void onInputEvent(InputEvent event, int displayId) {
58 boolean handled = false;
59 try {
Daichi Hirono768012e2017-10-30 10:05:37 +090060 if (!(event instanceof MotionEvent)
61 || (event.getSource() & SOURCE_CLASS_POINTER) == 0
62 || mMuteInput) {
63 return;
Daichi Hirono52cb2152017-09-11 15:29:42 +090064 }
Daichi Hirono768012e2017-10-30 10:05:37 +090065 final MotionEvent motionEvent = (MotionEvent) event;
66 final float newX = motionEvent.getRawX();
67 final float newY = motionEvent.getRawY();
68 final boolean isStylusButtonDown =
69 (motionEvent.getButtonState() & BUTTON_STYLUS_PRIMARY) != 0;
70
71 if (mIsStartEvent) {
72 // First event and the button was down, check for the button being
73 // lifted in the future, if that happens we'll drop the item.
74 mStylusButtonDownAtStart = isStylusButtonDown;
75 mIsStartEvent = false;
76 }
77
78 switch (motionEvent.getAction()) {
79 case ACTION_DOWN:
80 if (DEBUG_DRAG) Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
81 return;
82 case ACTION_MOVE:
83 if (mStylusButtonDownAtStart && !isStylusButtonDown) {
84 if (DEBUG_DRAG) {
85 Slog.d(TAG_WM, "Button no longer pressed; dropping at " + newX + ","
86 + newY);
87 }
88 mMuteInput = true;
89 }
90 break;
91 case ACTION_UP:
92 if (DEBUG_DRAG) {
93 Slog.d(TAG_WM, "Got UP on move channel; dropping at " + newX + "," + newY);
94 }
95 mMuteInput = true;
96 break;
97 case ACTION_CANCEL:
98 if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
99 mMuteInput = true;
100 break;
101 default:
102 return;
103 }
104
105 mDragDropController.handleMotionEvent(!mMuteInput /* keepHandling */, newX, newY);
106 handled = true;
Daichi Hirono52cb2152017-09-11 15:29:42 +0900107 } catch (Exception e) {
108 Slog.e(TAG_WM, "Exception caught by drag handleMotion", e);
109 } finally {
110 finishInputEvent(event, handled);
111 }
112 }
113}