• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 
17 package com.android.server.wm;
18 
19 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
20 import static android.view.PointerIcon.TYPE_NOT_SPECIFIED;
21 import static android.view.PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW;
22 import static android.view.PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
23 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
24 
25 import android.graphics.Rect;
26 import android.graphics.Region;
27 import android.hardware.input.InputManager;
28 import android.view.InputDevice;
29 import android.view.MotionEvent;
30 import android.view.WindowManagerPolicyConstants.PointerEventListener;
31 
32 import com.android.server.wm.WindowManagerService.H;
33 
34 /**
35  * 1. Adjust the top most focus display if touch down on some display.
36  * 2. Adjust the pointer icon when cursor moves to the task bounds.
37  */
38 public class TaskTapPointerEventListener implements PointerEventListener {
39 
40     private final Region mTouchExcludeRegion = new Region();
41     private final WindowManagerService mService;
42     private final DisplayContent mDisplayContent;
43     private final Rect mTmpRect = new Rect();
44     private int mPointerIconType = TYPE_NOT_SPECIFIED;
45 
TaskTapPointerEventListener(WindowManagerService service, DisplayContent displayContent)46     public TaskTapPointerEventListener(WindowManagerService service,
47             DisplayContent displayContent) {
48         mService = service;
49         mDisplayContent = displayContent;
50     }
51 
restorePointerIcon(int x, int y)52     private void restorePointerIcon(int x, int y) {
53         if (mPointerIconType != TYPE_NOT_SPECIFIED) {
54             mPointerIconType = TYPE_NOT_SPECIFIED;
55             // Find the underlying window and ask it to restore the pointer icon.
56             mService.mH.removeMessages(H.RESTORE_POINTER_ICON);
57             mService.mH.obtainMessage(H.RESTORE_POINTER_ICON,
58                     x, y, mDisplayContent).sendToTarget();
59         }
60     }
61 
62     @Override
onPointerEvent(MotionEvent motionEvent)63     public void onPointerEvent(MotionEvent motionEvent) {
64         switch (motionEvent.getActionMasked()) {
65             case MotionEvent.ACTION_DOWN: {
66                 final int x;
67                 final int y;
68                 if (motionEvent.getSource() == InputDevice.SOURCE_MOUSE) {
69                     x = (int) motionEvent.getXCursorPosition();
70                     y = (int) motionEvent.getYCursorPosition();
71                 } else {
72                     x = (int) motionEvent.getX();
73                     y = (int) motionEvent.getY();
74                 }
75 
76                 synchronized (this) {
77                     if (!mTouchExcludeRegion.contains(x, y)) {
78                         mService.mTaskPositioningController.handleTapOutsideTask(
79                                 mDisplayContent, x, y);
80                     }
81                 }
82             }
83             break;
84             case MotionEvent.ACTION_HOVER_ENTER:
85             case MotionEvent.ACTION_HOVER_MOVE: {
86                 final int x = (int) motionEvent.getX();
87                 final int y = (int) motionEvent.getY();
88                 if (mTouchExcludeRegion.contains(x, y)) {
89                     restorePointerIcon(x, y);
90                     break;
91                 }
92                 final Task task = mDisplayContent.findTaskForResizePoint(x, y);
93                 int iconType = TYPE_NOT_SPECIFIED;
94                 if (task != null) {
95                     task.getDimBounds(mTmpRect);
96                     if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) {
97                         if (x < mTmpRect.left) {
98                             iconType =
99                                 (y < mTmpRect.top) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
100                                 (y > mTmpRect.bottom) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
101                                 TYPE_HORIZONTAL_DOUBLE_ARROW;
102                         } else if (x > mTmpRect.right) {
103                             iconType =
104                                 (y < mTmpRect.top) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
105                                 (y > mTmpRect.bottom) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
106                                 TYPE_HORIZONTAL_DOUBLE_ARROW;
107                         } else if (y < mTmpRect.top || y > mTmpRect.bottom) {
108                             iconType = TYPE_VERTICAL_DOUBLE_ARROW;
109                         }
110                     }
111                 }
112                 if (mPointerIconType != iconType) {
113                     mPointerIconType = iconType;
114                     if (mPointerIconType == TYPE_NOT_SPECIFIED) {
115                         // Find the underlying window and ask it restore the pointer icon.
116                         mService.mH.removeMessages(H.RESTORE_POINTER_ICON);
117                         mService.mH.obtainMessage(H.RESTORE_POINTER_ICON,
118                                 x, y, mDisplayContent).sendToTarget();
119                     } else {
120                         InputManager.getInstance().setPointerIconType(mPointerIconType);
121                     }
122                 }
123             }
124             break;
125             case MotionEvent.ACTION_HOVER_EXIT: {
126                 final int x = (int) motionEvent.getX();
127                 final int y = (int) motionEvent.getY();
128                 restorePointerIcon(x, y);
129             }
130             break;
131         }
132     }
133 
setTouchExcludeRegion(Region newRegion)134     void setTouchExcludeRegion(Region newRegion) {
135         synchronized (this) {
136            mTouchExcludeRegion.set(newRegion);
137         }
138     }
139 }
140