| /* |
| * Copyright (C) 2013 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.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW; |
| import static android.view.PointerIcon.TYPE_NOT_SPECIFIED; |
| import static android.view.PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW; |
| import static android.view.PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW; |
| import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW; |
| |
| import android.graphics.Rect; |
| import android.graphics.Region; |
| import android.hardware.input.InputManager; |
| import android.view.MotionEvent; |
| import android.view.WindowManagerPolicyConstants.PointerEventListener; |
| |
| import com.android.server.wm.WindowManagerService.H; |
| |
| /** |
| * 1. Adjust the top most focus display if touch down on some display. |
| * 2. Adjust the pointer icon when cursor moves to the task bounds. |
| */ |
| public class TaskTapPointerEventListener implements PointerEventListener { |
| |
| private final Region mTouchExcludeRegion = new Region(); |
| private final WindowManagerService mService; |
| private final DisplayContent mDisplayContent; |
| private final Rect mTmpRect = new Rect(); |
| private int mPointerIconType = TYPE_NOT_SPECIFIED; |
| |
| public TaskTapPointerEventListener(WindowManagerService service, |
| DisplayContent displayContent) { |
| mService = service; |
| mDisplayContent = displayContent; |
| } |
| |
| @Override |
| public void onPointerEvent(MotionEvent motionEvent) { |
| switch (motionEvent.getActionMasked()) { |
| case MotionEvent.ACTION_DOWN: { |
| final int x = (int) motionEvent.getX(); |
| final int y = (int) motionEvent.getY(); |
| |
| synchronized (this) { |
| if (!mTouchExcludeRegion.contains(x, y)) { |
| mService.mTaskPositioningController.handleTapOutsideTask( |
| mDisplayContent, x, y); |
| } |
| } |
| } |
| break; |
| case MotionEvent.ACTION_HOVER_ENTER: |
| case MotionEvent.ACTION_HOVER_MOVE: { |
| final int x = (int) motionEvent.getX(); |
| final int y = (int) motionEvent.getY(); |
| final Task task = mDisplayContent.findTaskForResizePoint(x, y); |
| int iconType = TYPE_NOT_SPECIFIED; |
| if (task != null) { |
| task.getDimBounds(mTmpRect); |
| if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) { |
| if (x < mTmpRect.left) { |
| iconType = |
| (y < mTmpRect.top) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW : |
| (y > mTmpRect.bottom) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW : |
| TYPE_HORIZONTAL_DOUBLE_ARROW; |
| } else if (x > mTmpRect.right) { |
| iconType = |
| (y < mTmpRect.top) ? TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW : |
| (y > mTmpRect.bottom) ? TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW : |
| TYPE_HORIZONTAL_DOUBLE_ARROW; |
| } else if (y < mTmpRect.top || y > mTmpRect.bottom) { |
| iconType = TYPE_VERTICAL_DOUBLE_ARROW; |
| } |
| } |
| } |
| if (mPointerIconType != iconType) { |
| mPointerIconType = iconType; |
| if (mPointerIconType == TYPE_NOT_SPECIFIED) { |
| // Find the underlying window and ask it restore the pointer icon. |
| mService.mH.removeMessages(H.RESTORE_POINTER_ICON); |
| mService.mH.obtainMessage(H.RESTORE_POINTER_ICON, |
| x, y, mDisplayContent).sendToTarget(); |
| } else { |
| InputManager.getInstance().setPointerIconType(mPointerIconType); |
| } |
| } |
| } |
| break; |
| case MotionEvent.ACTION_HOVER_EXIT: { |
| final int x = (int) motionEvent.getX(); |
| final int y = (int) motionEvent.getY(); |
| if (mPointerIconType != TYPE_NOT_SPECIFIED) { |
| mPointerIconType = TYPE_NOT_SPECIFIED; |
| // Find the underlying window and ask it to restore the pointer icon. |
| mService.mH.removeMessages(H.RESTORE_POINTER_ICON); |
| mService.mH.obtainMessage(H.RESTORE_POINTER_ICON, |
| x, y, mDisplayContent).sendToTarget(); |
| } |
| } |
| break; |
| } |
| } |
| |
| void setTouchExcludeRegion(Region newRegion) { |
| synchronized (this) { |
| mTouchExcludeRegion.set(newRegion); |
| } |
| } |
| } |