StackTapPointerEventListener.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
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 17package com.android.server.wm; 18 19import android.graphics.Region; 20import android.view.DisplayInfo; 21import android.view.MotionEvent; 22import android.view.WindowManagerPolicy.PointerEventListener; 23 24import com.android.server.wm.WindowManagerService.H; 25 26public class StackTapPointerEventListener implements PointerEventListener { 27 private static final int TAP_TIMEOUT_MSEC = 300; 28 private static final float TAP_MOTION_SLOP_INCHES = 0.125f; 29 30 private final int mMotionSlop; 31 private float mDownX; 32 private float mDownY; 33 private int mPointerId; 34 final private Region mTouchExcludeRegion; 35 private final WindowManagerService mService; 36 private final DisplayContent mDisplayContent; 37 38 public StackTapPointerEventListener(WindowManagerService service, 39 DisplayContent displayContent) { 40 mService = service; 41 mDisplayContent = displayContent; 42 mTouchExcludeRegion = displayContent.mTouchExcludeRegion; 43 DisplayInfo info = displayContent.getDisplayInfo(); 44 mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES); 45 } 46 47 @Override 48 public void onPointerEvent(MotionEvent motionEvent) { 49 final int action = motionEvent.getAction(); 50 switch (action & MotionEvent.ACTION_MASK) { 51 case MotionEvent.ACTION_DOWN: 52 mPointerId = motionEvent.getPointerId(0); 53 mDownX = motionEvent.getX(); 54 mDownY = motionEvent.getY(); 55 break; 56 case MotionEvent.ACTION_MOVE: 57 if (mPointerId >= 0) { 58 int index = motionEvent.findPointerIndex(mPointerId); 59 if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC 60 || (motionEvent.getX(index) - mDownX) > mMotionSlop 61 || (motionEvent.getY(index) - mDownY) > mMotionSlop) { 62 mPointerId = -1; 63 } 64 } 65 break; 66 case MotionEvent.ACTION_UP: 67 case MotionEvent.ACTION_POINTER_UP: { 68 int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) 69 >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 70 // Extract the index of the pointer that left the touch sensor 71 if (mPointerId == motionEvent.getPointerId(index)) { 72 final int x = (int)motionEvent.getX(index); 73 final int y = (int)motionEvent.getY(index); 74 if ((motionEvent.getEventTime() - motionEvent.getDownTime()) 75 < TAP_TIMEOUT_MSEC 76 && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop 77 && !mTouchExcludeRegion.contains(x, y)) { 78 mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, 79 mDisplayContent).sendToTarget(); 80 } 81 mPointerId = -1; 82 } 83 break; 84 } 85 } 86 } 87} 88