diff options
author | Craig Mautner <cmautner@google.com> | 2013-06-12 23:07:39 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-06-12 23:07:39 +0000 |
commit | ac5396a3a8cac5a87b4710c458157701c94ce752 (patch) | |
tree | cce09003224997dd47987ce1dd08230b85bdd64d /services | |
parent | 554ec841abe7975e836333326a2d44a7e64c13fb (diff) | |
parent | 037aa8d434984840691378f3cc7d99d63dcc4076 (diff) | |
download | frameworks_base-ac5396a3a8cac5a87b4710c458157701c94ce752.zip frameworks_base-ac5396a3a8cac5a87b4710c458157701c94ce752.tar.gz frameworks_base-ac5396a3a8cac5a87b4710c458157701c94ce752.tar.bz2 |
Merge "Centralize all system InputEventReceiver monitors."
Diffstat (limited to 'services')
5 files changed, 197 insertions, 124 deletions
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 4a3699c..82e8c7f 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -28,7 +28,6 @@ import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; -import android.view.InputChannel; import java.io.PrintWriter; import java.util.ArrayList; @@ -101,11 +100,8 @@ class DisplayContent { /** Sorted most recent at top, oldest at [0]. */ ArrayList<TaskStack> mStackHistory = new ArrayList<TaskStack>(); - /** Forward motion events to mTapDetector. */ - InputChannel mTapInputChannel; - /** Detect user tapping outside of current focused stack bounds .*/ - StackTapDetector mTapDetector; + StackTapPointerEventListener mTapDetector; /** Detect user tapping outside of current focused stack bounds .*/ Region mTouchExcludeRegion = new Region(); diff --git a/services/java/com/android/server/wm/PointerEventDispatcher.java b/services/java/com/android/server/wm/PointerEventDispatcher.java new file mode 100644 index 0000000..6b0e4c9 --- /dev/null +++ b/services/java/com/android/server/wm/PointerEventDispatcher.java @@ -0,0 +1,90 @@ +/* + * 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 android.view.InputChannel; +import android.view.InputDevice; +import android.view.InputEvent; +import android.view.InputEventReceiver; +import android.view.MotionEvent; +import android.view.WindowManagerPolicy.PointerEventListener; + +import com.android.server.UiThread; + +import java.util.ArrayList; + +public class PointerEventDispatcher extends InputEventReceiver { + ArrayList<PointerEventListener> mListeners = new ArrayList<PointerEventListener>(); + PointerEventListener[] mListenersArray = new PointerEventListener[0]; + + public PointerEventDispatcher(InputChannel inputChannel) { + super(inputChannel, UiThread.getHandler().getLooper()); + } + + @Override + public void onInputEvent(InputEvent event) { + try { + if (event instanceof MotionEvent + && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { + final MotionEvent motionEvent = (MotionEvent)event; + PointerEventListener[] listeners; + synchronized (mListeners) { + if (mListenersArray == null) { + mListenersArray = new PointerEventListener[mListeners.size()]; + mListeners.toArray(mListenersArray); + } + listeners = mListenersArray; + } + for (int i = 0; i < listeners.length; ++i) { + listeners[i].onPointerEvent(motionEvent); + } + } + } finally { + finishInputEvent(event, false); + } + } + + /** + * Add the specified listener to the list. + * @param listener The listener to add. + */ + public void registerInputEventListener(PointerEventListener listener) { + synchronized (mListeners) { + if (mListeners.contains(listener)) { + throw new IllegalStateException("registerInputEventListener: trying to register" + + listener + " twice."); + } + mListeners.add(listener); + mListenersArray = null; + } + } + + /** + * Remove the specified listener from the list. + * @param listener The listener to remove. + */ + public void unregisterInputEventListener(PointerEventListener listener) { + synchronized (mListeners) { + if (!mListeners.contains(listener)) { + throw new IllegalStateException("registerInputEventListener: " + listener + + " not registered."); + } + mListeners.remove(listener); + mListenersArray = null; + } + } +} diff --git a/services/java/com/android/server/wm/StackTapDetector.java b/services/java/com/android/server/wm/StackTapDetector.java deleted file mode 100644 index 7127fd2..0000000 --- a/services/java/com/android/server/wm/StackTapDetector.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 android.graphics.Region; -import android.os.Looper; -import android.view.DisplayInfo; -import android.view.InputChannel; -import android.view.InputDevice; -import android.view.InputEvent; -import android.view.InputEventReceiver; -import android.view.MotionEvent; - -import com.android.server.wm.WindowManagerService.H; - -public class StackTapDetector extends InputEventReceiver { - private static final int TAP_TIMEOUT_MSEC = 300; - private static final float TAP_MOTION_SLOP_INCHES = 0.125f; - - private final int mMotionSlop; - private float mDownX; - private float mDownY; - private int mPointerId; - final private Region mTouchExcludeRegion; - private final WindowManagerService mService; - private final DisplayContent mDisplayContent; - - public StackTapDetector(WindowManagerService service, DisplayContent displayContent, - InputChannel inputChannel, Looper looper) { - super(inputChannel, looper); - mService = service; - mDisplayContent = displayContent; - mTouchExcludeRegion = displayContent.mTouchExcludeRegion; - DisplayInfo info = displayContent.getDisplayInfo(); - mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES); - } - - @Override - public void onInputEvent(InputEvent event) { - try { - if (!(event instanceof MotionEvent) - || !event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { - return; - } - final MotionEvent motionEvent = (MotionEvent)event; - final int action = motionEvent.getAction(); - switch (action & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - mPointerId = motionEvent.getPointerId(0); - mDownX = motionEvent.getX(); - mDownY = motionEvent.getY(); - break; - case MotionEvent.ACTION_MOVE: - if (mPointerId >= 0) { - int index = motionEvent.findPointerIndex(mPointerId); - if ((motionEvent.getEventTime() - motionEvent.getDownTime()) - > TAP_TIMEOUT_MSEC - || (motionEvent.getX(index) - mDownX) > mMotionSlop - || (motionEvent.getY(index) - mDownY) > mMotionSlop) { - mPointerId = -1; - } - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_POINTER_UP: { - int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) - >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - // Extract the index of the pointer that left the touch sensor - if (mPointerId == motionEvent.getPointerId(index)) { - final int x = (int)motionEvent.getX(index); - final int y = (int)motionEvent.getY(index); - synchronized (this) { - if ((motionEvent.getEventTime() - motionEvent.getDownTime()) - < TAP_TIMEOUT_MSEC - && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop - && !mTouchExcludeRegion.contains(x, y)) { - mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, - mDisplayContent).sendToTarget(); - } - } - mPointerId = -1; - } - break; - } - } - } finally { - finishInputEvent(event, false /*ignored for monitors*/); - } - } -} diff --git a/services/java/com/android/server/wm/StackTapPointerEventListener.java b/services/java/com/android/server/wm/StackTapPointerEventListener.java new file mode 100644 index 0000000..19d8ab3 --- /dev/null +++ b/services/java/com/android/server/wm/StackTapPointerEventListener.java @@ -0,0 +1,87 @@ +/* + * 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 android.graphics.Region; +import android.view.DisplayInfo; +import android.view.MotionEvent; +import android.view.WindowManagerPolicy.PointerEventListener; + +import com.android.server.wm.WindowManagerService.H; + +public class StackTapPointerEventListener implements PointerEventListener { + private static final int TAP_TIMEOUT_MSEC = 300; + private static final float TAP_MOTION_SLOP_INCHES = 0.125f; + + private final int mMotionSlop; + private float mDownX; + private float mDownY; + private int mPointerId; + final private Region mTouchExcludeRegion; + private final WindowManagerService mService; + private final DisplayContent mDisplayContent; + + public StackTapPointerEventListener(WindowManagerService service, + DisplayContent displayContent) { + mService = service; + mDisplayContent = displayContent; + mTouchExcludeRegion = displayContent.mTouchExcludeRegion; + DisplayInfo info = displayContent.getDisplayInfo(); + mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES); + } + + @Override + public void onPointerEvent(MotionEvent motionEvent) { + final int action = motionEvent.getAction(); + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: + mPointerId = motionEvent.getPointerId(0); + mDownX = motionEvent.getX(); + mDownY = motionEvent.getY(); + break; + case MotionEvent.ACTION_MOVE: + if (mPointerId >= 0) { + int index = motionEvent.findPointerIndex(mPointerId); + if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC + || (motionEvent.getX(index) - mDownX) > mMotionSlop + || (motionEvent.getY(index) - mDownY) > mMotionSlop) { + mPointerId = -1; + } + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_POINTER_UP: { + int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) + >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + // Extract the index of the pointer that left the touch sensor + if (mPointerId == motionEvent.getPointerId(index)) { + final int x = (int)motionEvent.getX(index); + final int y = (int)motionEvent.getY(index); + if ((motionEvent.getEventTime() - motionEvent.getDownTime()) + < TAP_TIMEOUT_MSEC + && (x - mDownX) < mMotionSlop && (y - mDownY) < mMotionSlop + && !mTouchExcludeRegion.contains(x, y)) { + mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, + mDisplayContent).sendToTarget(); + } + mPointerId = -1; + } + break; + } + } + } +} diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index f166c31..079134b 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -124,6 +124,7 @@ import android.view.WindowManagerGlobal; import android.view.WindowManagerPolicy; import android.view.WindowManager.LayoutParams; import android.view.WindowManagerPolicy.FakeWindow; +import android.view.WindowManagerPolicy.PointerEventListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Transformation; @@ -281,8 +282,6 @@ public class WindowManagerService extends IWindowManager.Stub private static final String SYSTEM_SECURE = "ro.secure"; private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; - private static final String TAP_INPUT_CHANNEL_NAME = "StackTapDetector"; - private static final int MAX_SCREENSHOT_RETRIES = 3; final private KeyguardDisableHandler mKeyguardDisableHandler; @@ -594,6 +593,8 @@ public class WindowManagerService extends IWindowManager.Stub SparseArray<Task> mTaskIdToTask = new SparseArray<Task>(); SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>(); + private final PointerEventDispatcher mPointerEventDispatcher; + final class DragInputEventReceiver extends InputEventReceiver { public DragInputEventReceiver(InputChannel inputChannel, Looper looper) { super(inputChannel, looper); @@ -728,6 +729,8 @@ public class WindowManagerService extends IWindowManager.Stub mDisplaySettings = new DisplaySettings(context); mDisplaySettings.readSettingsLocked(); + mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG)); + mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager.registerDisplayListener(this, null); Display[] displays = mDisplayManager.getDisplays(); @@ -5098,6 +5101,16 @@ public class WindowManagerService extends IWindowManager.Stub mAnimatorDurationScale }; } + @Override + public void registerPointerEventListener(PointerEventListener listener) { + mPointerEventDispatcher.registerInputEventListener(listener); + } + + @Override + public void unregisterPointerEventListener(PointerEventListener listener) { + mPointerEventDispatcher.unregisterInputEventListener(listener); + } + // Called by window manager policy. Not exposed externally. @Override public int getLidState() { @@ -5117,12 +5130,6 @@ public class WindowManagerService extends IWindowManager.Stub // Called by window manager policy. Not exposed externally. @Override - public InputChannel monitorInput(String inputChannelName) { - return mInputManager.monitorInput(inputChannelName); - } - - // Called by window manager policy. Not exposed externally. - @Override public void switchKeyboardLayout(int deviceId, int direction) { mInputManager.switchKeyboardLayout(deviceId, direction); } @@ -10652,10 +10659,8 @@ public class WindowManagerService extends IWindowManager.Stub // TODO: Create an input channel for each display with touch capability. if (displayId == Display.DEFAULT_DISPLAY) { - InputChannel inputChannel = monitorInput(TAP_INPUT_CHANNEL_NAME); - displayContent.mTapInputChannel = inputChannel; - displayContent.mTapDetector = - new StackTapDetector(this, displayContent, inputChannel, Looper.myLooper()); + displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent); + registerPointerEventListener(displayContent.mTapDetector); } return displayContent; @@ -10838,10 +10843,9 @@ public class WindowManagerService extends IWindowManager.Stub if (displayContent != null) { mDisplayContents.delete(displayId); - if (displayContent.mTapInputChannel != null) { - displayContent.mTapInputChannel.dispose(); + if (displayId == Display.DEFAULT_DISPLAY) { + unregisterPointerEventListener(displayContent.mTapDetector); } - WindowList windows = displayContent.getWindowList(); while (!windows.isEmpty()) { final WindowState win = windows.get(windows.size() - 1); |