1037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner/*
2037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * Copyright (C) 2013 The Android Open Source Project
3037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner *
4037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
5037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * you may not use this file except in compliance with the License.
6037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * You may obtain a copy of the License at
7037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner *
8037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
9037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner *
10037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * Unless required by applicable law or agreed to in writing, software
11037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
12037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * See the License for the specific language governing permissions and
14037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * limitations under the License.
15037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner */
16037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
17037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerpackage com.android.server.wm;
18037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
1941aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukaiimport android.graphics.Rect;
20037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.graphics.Region;
216f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheevimport android.hardware.input.InputManager;
22037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.MotionEvent;
23037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.WindowManagerPolicy.PointerEventListener;
24037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
25037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport com.android.server.wm.WindowManagerService.H;
26037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
27e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wrightimport static android.view.PointerIcon.TYPE_NOT_SPECIFIED;
28e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wrightimport static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
29e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wrightimport static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
30e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wrightimport static android.view.PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW;
31e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wrightimport static android.view.PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;
3241aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai
33e4a0c5722b1d8db95dfc842d716452dbbf02c86dWale Ogunwalepublic class TaskTapPointerEventListener implements PointerEventListener {
34037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
3533d8e739206b7a5ed99cf9bf73d63f9b6c0d2a4etingna_sung    final private Region mTouchExcludeRegion = new Region();
36037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner    private final WindowManagerService mService;
37037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner    private final DisplayContent mDisplayContent;
3841aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai    private final Rect mTmpRect = new Rect();
39e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright    private int mPointerIconType = TYPE_NOT_SPECIFIED;
40037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
41e4a0c5722b1d8db95dfc842d716452dbbf02c86dWale Ogunwale    public TaskTapPointerEventListener(WindowManagerService service,
42037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner            DisplayContent displayContent) {
43037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner        mService = service;
44037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner        mDisplayContent = displayContent;
45037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner    }
46037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner
47037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner    @Override
48037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner    public void onPointerEvent(MotionEvent motionEvent) {
49037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner        final int action = motionEvent.getAction();
50037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner        switch (action & MotionEvent.ACTION_MASK) {
518e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            case MotionEvent.ACTION_DOWN: {
529817dd098dcb4e37e1bec8b1e44ddb25a89cf8ecChong Zhang                final int x = (int) motionEvent.getX();
539817dd098dcb4e37e1bec8b1e44ddb25a89cf8ecChong Zhang                final int y = (int) motionEvent.getY();
548e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
558e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                synchronized (this) {
568e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    if (!mTouchExcludeRegion.contains(x, y)) {
579817dd098dcb4e37e1bec8b1e44ddb25a89cf8ecChong Zhang                        mService.mH.obtainMessage(H.TAP_OUTSIDE_TASK,
589817dd098dcb4e37e1bec8b1e44ddb25a89cf8ecChong Zhang                                x, y, mDisplayContent).sendToTarget();
598e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                    }
608e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang                }
618e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang            }
622e2c81a8d67f6ceccf178c5c7264d27e8c72e9ffChong Zhang            break;
638e89b31a62fb9ec5ad33908c5e8e9c7ab2fd949fChong Zhang
6441aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai            case MotionEvent.ACTION_HOVER_MOVE: {
6541aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai                final int x = (int) motionEvent.getX();
6641aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai                final int y = (int) motionEvent.getY();
6715ead903c69b043eeb44fc627929d4919e985df3Wale Ogunwale                final Task task = mDisplayContent.findTaskForResizePoint(x, y);
68e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                int iconType = TYPE_NOT_SPECIFIED;
696f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                if (task != null) {
706f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                    task.getDimBounds(mTmpRect);
716f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                    if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) {
726f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        if (x < mTmpRect.left) {
73e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                            iconType =
74e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                (y < mTmpRect.top) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
75e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                (y > mTmpRect.bottom) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
76e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                TYPE_HORIZONTAL_DOUBLE_ARROW;
776f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        } else if (x > mTmpRect.right) {
78e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                            iconType =
79e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                (y < mTmpRect.top) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
80e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                (y > mTmpRect.bottom) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
81e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                                TYPE_HORIZONTAL_DOUBLE_ARROW;
826f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        } else if (y < mTmpRect.top || y > mTmpRect.bottom) {
83e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                            iconType = TYPE_VERTICAL_DOUBLE_ARROW;
846f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        }
8541aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai                    }
866f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                }
87e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                if (mPointerIconType != iconType) {
88e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                    mPointerIconType = iconType;
89e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                    if (mPointerIconType == TYPE_NOT_SPECIFIED) {
906f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        // Find the underlying window and ask it restore the pointer icon.
916f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                        mService.mH.obtainMessage(H.RESTORE_POINTER_ICON,
926f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                                x, y, mDisplayContent).sendToTarget();
936f0b045d5778b38cab97be5a1bca602f4ffb88f7Vladislav Kaznacheev                    } else {
94e051f6f1fdb5e21cbed394d29dfcab5c642e4129Michael Wright                        InputManager.getInstance().setPointerIconType(mPointerIconType);
9541aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai                    }
9641aab00c3e762c6b648483ee7b45b162e4da7f7fJun Mukai                }
97b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang            }
982e2c81a8d67f6ceccf178c5c7264d27e8c72e9ffChong Zhang            break;
99b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang        }
100b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang    }
101b15758ab7a6481717d0d29612e870d7241061c31Chong Zhang
1022e2c81a8d67f6ceccf178c5c7264d27e8c72e9ffChong Zhang    void setTouchExcludeRegion(Region newRegion) {
10333d8e739206b7a5ed99cf9bf73d63f9b6c0d2a4etingna_sung        synchronized (this) {
10433d8e739206b7a5ed99cf9bf73d63f9b6c0d2a4etingna_sung           mTouchExcludeRegion.set(newRegion);
10533d8e739206b7a5ed99cf9bf73d63f9b6c0d2a4etingna_sung        }
10633d8e739206b7a5ed99cf9bf73d63f9b6c0d2a4etingna_sung    }
107037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner}
108