AccessibilityInputFilter.java revision 213c13aadd5bd4fd3876528f17f179379ca1c1f6
10029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown/* 20029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Copyright (C) 2011 The Android Open Source Project 30029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 40029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 50029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * you may not use this file except in compliance with the License. 60029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * You may obtain a copy of the License at 70029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 80029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 90029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Unless required by applicable law or agreed to in writing, software 110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * See the License for the specific language governing permissions and 140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * limitations under the License. 150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownpackage com.android.server.accessibility; 180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.content.Context; 20d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganovimport android.os.PowerManager; 21545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganovimport android.util.Pools.SimplePool; 220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.util.Slog; 23545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganovimport android.view.Choreographer; 24152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganovimport android.view.Display; 25736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovimport android.view.InputDevice; 260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.InputEvent; 27c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.InputFilter; 280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.MotionEvent; 290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.WindowManagerPolicy; 3086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 32545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov/** 33545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * This class is an input filter for implementing accessibility features such 34545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * as display magnification and explore by touch. 35545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * 36545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov * NOTE: This class has to be created and poked only from the main thread. 37545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov */ 381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganovclass AccessibilityInputFilter extends InputFilter implements EventStreamTransformation { 391cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 401cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private static final String TAG = AccessibilityInputFilter.class.getSimpleName(); 411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 42736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov private static final boolean DEBUG = false; 430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 441cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov /** 451cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * Flag for enabling the screen magnification feature. 461cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * 471cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * @see #setEnabledFeatures(int) 481cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov */ 491cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov static final int FLAG_FEATURE_SCREEN_MAGNIFIER = 0x00000001; 501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 511cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov /** 521cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * Flag for enabling the touch exploration feature. 531cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * 541cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov * @see #setEnabledFeatures(int) 551cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov */ 561cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov static final int FLAG_FEATURE_TOUCH_EXPLORATION = 0x00000002; 571cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 58545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private final Runnable mProcessBatchedEventsRunnable = new Runnable() { 59545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov @Override 60545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public void run() { 61545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov final long frameTimeNanos = mChoreographer.getFrameTimeNanos(); 62545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (DEBUG) { 63545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov Slog.i(TAG, "Begin batch processing for frame: " + frameTimeNanos); 64545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 65545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov processBatchedEvents(frameTimeNanos); 66545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (DEBUG) { 67545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov Slog.i(TAG, "End batch processing."); 68545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 69545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (mEventQueue != null) { 70545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov scheduleProcessBatchedEvents(); 71545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 72545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 73545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov }; 74545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 750029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private final Context mContext; 760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 77d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganov private final PowerManager mPm; 78d1ff736d01cebaee70b76f012b660ae549c252b9Svetoslav Ganov 79e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov private final AccessibilityManagerService mAms; 804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 81545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private final Choreographer mChoreographer; 82545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 831cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private int mCurrentDeviceId; 84736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 851cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private boolean mInstalled; 861cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 871cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private int mEnabledFeatures; 884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov 891cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private TouchExplorer mTouchExplorer; 90213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav 911cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private ScreenMagnifier mScreenMagnifier; 92213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav 931cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private EventStreamTransformation mEventHandler; 94736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov 95545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private MotionEventHolder mEventQueue; 96545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 97213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav private boolean mMotionEventSequenceStarted; 98213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav 99213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav private boolean mHoverEventSequenceStarted; 100213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav 1011cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov AccessibilityInputFilter(Context context, AccessibilityManagerService service) { 1020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown super(context.getMainLooper()); 1030029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mContext = context; 104e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov mAms = service; 1051cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 106545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mChoreographer = Choreographer.getInstance(); 1070029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown @Override 1100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onInstalled() { 1110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (DEBUG) { 1120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown Slog.d(TAG, "Accessibility input filter installed."); 1130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1141cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mInstalled = true; 1151cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov disableFeatures(); 1161cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov enableFeatures(); 1170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown super.onInstalled(); 1180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown @Override 1210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onUninstalled() { 1220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (DEBUG) { 1230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown Slog.d(TAG, "Accessibility input filter uninstalled."); 1240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1251cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mInstalled = false; 1261cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov disableFeatures(); 1270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown super.onUninstalled(); 1280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown @Override 1310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onInputEvent(InputEvent event, int policyFlags) { 1320029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (DEBUG) { 133736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov Slog.d(TAG, "Received event: " + event + ", policyFlags=0x" 134736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov + Integer.toHexString(policyFlags)); 1350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1361cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mEventHandler == null) { 1371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov super.onInputEvent(event, policyFlags); 1381cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov return; 1391cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 1401cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (event.getSource() != InputDevice.SOURCE_TOUCHSCREEN) { 1411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov super.onInputEvent(event, policyFlags); 1421cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov return; 1431cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 1441cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if ((policyFlags & WindowManagerPolicy.FLAG_PASS_TO_USER) == 0) { 145213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mMotionEventSequenceStarted = false; 146213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mHoverEventSequenceStarted = false; 1471cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler.clear(); 1481cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov super.onInputEvent(event, policyFlags); 1491cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov return; 1501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 1511cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov final int deviceId = event.getDeviceId(); 1521cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mCurrentDeviceId != deviceId) { 153213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mMotionEventSequenceStarted = false; 154213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mHoverEventSequenceStarted = false; 155213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mEventHandler.clear(); 1561cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mCurrentDeviceId = deviceId; 1571cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 158213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (mCurrentDeviceId < 0) { 159213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav super.onInputEvent(event, policyFlags); 160213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav return; 161213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 162213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav // We do not handle scroll events. 163213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav MotionEvent motionEvent = (MotionEvent) event; 164213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (motionEvent.getActionMasked() == MotionEvent.ACTION_SCROLL) { 165213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav super.onInputEvent(event, policyFlags); 166213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav return; 167213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 168213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav // Wait for a down touch event to start processing. 169213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (motionEvent.isTouchEvent()) { 170213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (!mMotionEventSequenceStarted) { 171213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (motionEvent.getActionMasked() != MotionEvent.ACTION_DOWN) { 172213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav return; 173213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 174213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mMotionEventSequenceStarted = true; 175213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 176213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } else { 177213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav // Wait for an enter hover event to start processing. 178213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (!mHoverEventSequenceStarted) { 179213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav if (motionEvent.getActionMasked() != MotionEvent.ACTION_HOVER_ENTER) { 180213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav return; 181213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 182213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mHoverEventSequenceStarted = true; 183213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 184213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav } 185545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov batchMotionEvent((MotionEvent) event, policyFlags); 186545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 187545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 188545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private void scheduleProcessBatchedEvents() { 189545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, 190545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mProcessBatchedEventsRunnable, null); 191545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 192545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 193545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private void batchMotionEvent(MotionEvent event, int policyFlags) { 194545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (DEBUG) { 195545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov Slog.i(TAG, "Batching event: " + event + ", policyFlags: " + policyFlags); 196545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 197545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (mEventQueue == null) { 198545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mEventQueue = MotionEventHolder.obtain(event, policyFlags); 199545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov scheduleProcessBatchedEvents(); 200545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov return; 201545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 202545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (mEventQueue.event.addBatch(event)) { 203545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov return; 204545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 205545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov MotionEventHolder holder = MotionEventHolder.obtain(event, policyFlags); 206545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov holder.next = mEventQueue; 207545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mEventQueue.previous = holder; 208545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mEventQueue = holder; 209545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 210545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 211545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private void processBatchedEvents(long frameNanos) { 212545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov MotionEventHolder current = mEventQueue; 213545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov while (current.next != null) { 214545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov current = current.next; 215545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 216545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov while (true) { 217545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (current == null) { 218545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mEventQueue = null; 219545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov break; 220545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 221545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (current.event.getEventTimeNano() >= frameNanos) { 222545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov // Finished with this choreographer frame. Do the rest on the next one. 223545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov current.next = null; 224545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov break; 225545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 226545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov handleMotionEvent(current.event, current.policyFlags); 227545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov MotionEventHolder prior = current; 228545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov current = current.previous; 229545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov prior.recycle(); 230545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 231545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 232545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 233545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private void handleMotionEvent(MotionEvent event, int policyFlags) { 234545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (DEBUG) { 235545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov Slog.i(TAG, "Handling batched event: " + event + ", policyFlags: " + policyFlags); 236545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 2371cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mPm.userActivity(event.getEventTime(), false); 238545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov MotionEvent transformedEvent = MotionEvent.obtain(event); 239545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov mEventHandler.onMotionEvent(transformedEvent, event, policyFlags); 24045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov transformedEvent.recycle(); 2411cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2421cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2431cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov @Override 24445af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov public void onMotionEvent(MotionEvent transformedEvent, MotionEvent rawEvent, 24545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov int policyFlags) { 24645af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov sendInputEvent(transformedEvent, policyFlags); 2471cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2481cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2491cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov @Override 2501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov public void onAccessibilityEvent(AccessibilityEvent event) { 2511cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov // TODO Implement this to inject the accessibility event 2521cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov // into the accessibility manager service similarly 2531cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov // to how this is done for input events. 2541cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2551cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2561cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov @Override 2571cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov public void setNext(EventStreamTransformation sink) { 2581cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov /* do nothing */ 2591cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2601cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2611cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov @Override 2621cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov public void clear() { 2631cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov /* do nothing */ 2641cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2651cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2661cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov void setEnabledFeatures(int enabledFeatures) { 2671cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mEnabledFeatures == enabledFeatures) { 2681cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov return; 2691cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2701cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mInstalled) { 2711cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov disableFeatures(); 2721cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2731cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEnabledFeatures = enabledFeatures; 2741cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mInstalled) { 2751cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov enableFeatures(); 2761cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2771cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2781cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2791cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov void notifyAccessibilityEvent(AccessibilityEvent event) { 2801cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mEventHandler != null) { 2811cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler.onAccessibilityEvent(event); 2821cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2831cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2841cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 2851cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private void enableFeatures() { 286213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mMotionEventSequenceStarted = false; 287213c13aadd5bd4fd3876528f17f179379ca1c1f6Svetoslav mHoverEventSequenceStarted = false; 2881cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if ((mEnabledFeatures & FLAG_FEATURE_SCREEN_MAGNIFIER) != 0) { 289152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov mEventHandler = mScreenMagnifier = new ScreenMagnifier(mContext, 290152e9bb81aa5b2ab4637f4b2dae04b3ce89fa891Svetoslav Ganov Display.DEFAULT_DISPLAY, mAms); 2911cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler.setNext(this); 2921cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 2931cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) { 2941cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mTouchExplorer = new TouchExplorer(mContext, mAms); 2951cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mTouchExplorer.setNext(this); 2961cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mEventHandler != null) { 2971cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler.setNext(mTouchExplorer); 298736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } else { 2991cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler = mTouchExplorer; 300736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov } 3010029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 3020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 30386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov 3041cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov private void disableFeatures() { 305ee33ad24cdc31ed0d7f99e110e041b0a63c9b0f1Svetoslav Ganov if (mTouchExplorer != null) { 3061cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mTouchExplorer.clear(); 3071cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mTouchExplorer.onDestroy(); 3081cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mTouchExplorer = null; 3091cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 3101cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov if (mScreenMagnifier != null) { 3111cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mScreenMagnifier.clear(); 3121cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mScreenMagnifier.onDestroy(); 3131cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mScreenMagnifier = null; 314ee33ad24cdc31ed0d7f99e110e041b0a63c9b0f1Svetoslav Ganov } 3151cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov mEventHandler = null; 3161cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov } 3171cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov 3181cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov @Override 3191cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov public void onDestroy() { 3201cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov /* ignore */ 32186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov } 322545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 323545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private static class MotionEventHolder { 324545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private static final int MAX_POOL_SIZE = 32; 325545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov private static final SimplePool<MotionEventHolder> sPool = 326545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov new SimplePool<MotionEventHolder>(MAX_POOL_SIZE); 327545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 328545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public int policyFlags; 329545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public MotionEvent event; 330545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public MotionEventHolder next; 331545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public MotionEventHolder previous; 332545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 333545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public static MotionEventHolder obtain(MotionEvent event, int policyFlags) { 334545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov MotionEventHolder holder = sPool.acquire(); 335545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov if (holder == null) { 336545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov holder = new MotionEventHolder(); 337545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 338545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov holder.event = MotionEvent.obtain(event); 339545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov holder.policyFlags = policyFlags; 340545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov return holder; 341545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 342545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov 343545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov public void recycle() { 344545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov event.recycle(); 345545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov event = null; 346545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov policyFlags = 0; 347545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov next = null; 348545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov previous = null; 349545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov sPool.release(this); 350545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 351545252f4fde6fbb70b07e97a120c7d1405758017Svetoslav Ganov } 3520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown} 353