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