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 19037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.InputChannel; 20037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.InputDevice; 21037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.InputEvent; 22037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.InputEventReceiver; 23037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.MotionEvent; 24037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport android.view.WindowManagerPolicy.PointerEventListener; 25037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 26037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport com.android.server.UiThread; 27037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 28037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerimport java.util.ArrayList; 29037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 30037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautnerpublic class PointerEventDispatcher extends InputEventReceiver { 31037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner ArrayList<PointerEventListener> mListeners = new ArrayList<PointerEventListener>(); 32037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner PointerEventListener[] mListenersArray = new PointerEventListener[0]; 33037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 34037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner public PointerEventDispatcher(InputChannel inputChannel) { 35037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner super(inputChannel, UiThread.getHandler().getLooper()); 36037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 37037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 38037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner @Override 39037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner public void onInputEvent(InputEvent event) { 40037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner try { 41037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner if (event instanceof MotionEvent 42037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { 43037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner final MotionEvent motionEvent = (MotionEvent)event; 44037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner PointerEventListener[] listeners; 45037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner synchronized (mListeners) { 46037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner if (mListenersArray == null) { 47037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListenersArray = new PointerEventListener[mListeners.size()]; 48037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListeners.toArray(mListenersArray); 49037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 50037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner listeners = mListenersArray; 51037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 52037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner for (int i = 0; i < listeners.length; ++i) { 53037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner listeners[i].onPointerEvent(motionEvent); 54037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 55037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 56037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } finally { 57037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner finishInputEvent(event, false); 58037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 59037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 60037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 61037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner /** 62037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * Add the specified listener to the list. 63037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * @param listener The listener to add. 64037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner */ 65037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner public void registerInputEventListener(PointerEventListener listener) { 66037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner synchronized (mListeners) { 67037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner if (mListeners.contains(listener)) { 68037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner throw new IllegalStateException("registerInputEventListener: trying to register" + 69037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner listener + " twice."); 70037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 71037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListeners.add(listener); 72037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListenersArray = null; 73037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 74037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 75037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner 76037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner /** 77037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * Remove the specified listener from the list. 78037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner * @param listener The listener to remove. 79037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner */ 80037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner public void unregisterInputEventListener(PointerEventListener listener) { 81037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner synchronized (mListeners) { 82037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner if (!mListeners.contains(listener)) { 83037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner throw new IllegalStateException("registerInputEventListener: " + listener + 84037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner " not registered."); 85037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 86037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListeners.remove(listener); 87037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner mListenersArray = null; 88037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 89037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner } 90037aa8d434984840691378f3cc7d99d63dcc4076Craig Mautner} 91