blob: 79baab6bfbb676bc0e58a9fa14499abeb90cbc61 [file] [log] [blame]
/*
* 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);
}
}
}