InputFilter.java revision 0029c66203ab9ded4342976bf7a17bb63af8c44a
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.wm;
180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Handler;
200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Looper;
210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Message;
220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.InputEvent;
230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.KeyEvent;
240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.MotionEvent;
250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.WindowManagerPolicy;
260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown/**
280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Filters input events before they are dispatched to the system.
290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p>
300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * At most one input filter can be installed by calling
310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerService#setInputFilter}.  When an input filter is installed, the
320029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * system's behavior changes as follows:
330029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <ul>
340029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>Input events are first delivered to the {@link WindowManagerPolicy}
350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * interception methods before queueing as usual.  This critical step takes care of managing
360029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the power state of the device and handling wake keys.</li>
370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>Input events are then asynchronously delivered to the input filter's
380029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * applications as usual.  The input filter only receives input events that were
400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * generated by input device; the input filter will not receive input events that were
410029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * injected into the system by other means, such as by instrumentation.</li>
420029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>The input filter processes and optionally transforms the stream of events.  For example,
430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * it may transform a sequence of motion events representing an accessibility gesture into
440029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * a different sequence of motion events, key presses or other system-level interactions.
450029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter can send events to be dispatched by calling
460029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link #sendInputEvent(InputEvent)} and passing appropriate policy flags for the
470029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * input event.</li>
480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </ul>
490029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p>
500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <h3>The importance of input event consistency</h3>
510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p>
520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter mechanism is very low-level.  At a minimum, it needs to ensure that it
530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * sends an internally consistent stream of input events to the dispatcher.  There are
540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * very important invariants to be maintained.
550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * For example, if a key down is sent, a corresponding key up should also be sent eventually.
570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Likewise, for touch events, each pointer must individually go down with
580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link MotionEvent#ACTION_DOWN} or {@link MotionEvent#ACTION_POINTER_DOWN} and then
590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * individually go up with {@link MotionEvent#ACTION_POINTER_UP} or {@link MotionEvent#ACTION_UP}
600029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * and the sequence of pointer ids used must be consistent throughout the gesture.
610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
620029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Sometimes a filter may wish to cancel a previously dispatched key or motion.  It should
630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * use {@link KeyEvent#FLAG_CANCELED} or {@link MotionEvent#ACTION_CANCEL} accordingly.
640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter must take into account the fact that the input events coming from different
660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * devices or even different sources all consist of distinct streams of input.
670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify
680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the source of the event and its semantics.  There are be multiple sources of keys,
690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * touches and other input: they must be kept separate.
700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p>
710029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <h3>Policy flags</h3>
720029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p>
730029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Input events received from the dispatcher and sent to the dispatcher have policy flags
740029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * associated with them.  Policy flags control some functions of the dispatcher.
750029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The early policy interception decides whether an input event should be delivered
770029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * to applications or dropped.  The policy indicates its decision by setting the
780029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag.  The input filter may
790029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * sometimes receive events that do not have this flag set.  It should take note of
800029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the fact that the policy intends to drop the event, clean up its state, and
810029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * then send appropriate cancelation events to the dispatcher if needed.
820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * For example, suppose the input filter is processing a gesture and one of the touch events
840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set.
850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter should clear its internal state about the gesture and then send key or
860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * motion events to the dispatcher to cancel any keys or pointers that are down.
870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Corollary: Events that set sent to the dispatcher should usually include the
890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p>
910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * It may be prudent to disable automatic key repeating for synthetically generated
920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * keys by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p>
940029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */
950029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownpublic abstract class InputFilter {
960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private static final int MSG_INSTALL = 1;
970029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private static final int MSG_UNINSTALL = 2;
980029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private static final int MSG_INPUT_EVENT = 3;
990029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1000029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private final H mH;
1010029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private Host mHost;
1020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1030029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Creates the input filter.
1050029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     *
1060029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param looper The looper to run callbacks on.
1070029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public InputFilter(Looper looper) {
1090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mH = new H(looper);
1100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called when the input filter is installed.
1140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * This method is guaranteed to be non-reentrant.
1150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     *
1160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param host The input filter host environment.
1170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    final void install(Host host) {
1190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mH.obtainMessage(MSG_INSTALL, host).sendToTarget();
1200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called when the input filter is uninstalled.
1240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * This method is guaranteed to be non-reentrant.
1250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    final void uninstall() {
1270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mH.obtainMessage(MSG_UNINSTALL).sendToTarget();
1280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called to enqueue the input event for filtering.
1320029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * The event will be recycled after the input filter processes it.
1330029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * This method is guaranteed to be non-reentrant.
1340029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     *
1350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param event The input event to enqueue.
1360029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    final void filterInputEvent(InputEvent event, int policyFlags) {
1380029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mH.obtainMessage(MSG_INPUT_EVENT, policyFlags, 0, event).sendToTarget();
1390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1410029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1420029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Sends an input event to the dispatcher.
1430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     *
1440029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param event The input event to publish.
1450029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param policyFlags The input event policy flags.
1460029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1470029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void sendInputEvent(InputEvent event, int policyFlags) {
1480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (event == null) {
1490029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            throw new IllegalArgumentException("event must not be null");
1500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
1510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (mHost == null) {
1520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            throw new IllegalStateException("Cannot send input event because the input filter " +
1530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    "is not installed.");
1540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
1550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mHost.sendInputEvent(event, policyFlags);
1560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called when an input event has been received from the dispatcher.
1600029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * <p>
1610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * The default implementation sends the input event back to the dispatcher, unchanged.
1620029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * </p><p>
1630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * The event will be recycled when this method returns.  If you want to keep it around,
1640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * make a copy!
1650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * </p>
1660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     *
1670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param event The input event that was received.
1680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * @param policyFlags The input event policy flags.
1690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onInputEvent(InputEvent event, int policyFlags) {
1710029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        sendInputEvent(event, policyFlags);
1720029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1730029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1740029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1750029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called when the filter is installed into the dispatch pipeline.
1760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * <p>
1770029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * This method is called before the input filter receives any input events.
1780029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * The input filter should take this opportunity to prepare itself.
1790029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * </p>
1800029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1810029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onInstalled() {
1820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    /**
1850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * Called when the filter is uninstalled from the dispatch pipeline.
1860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * <p>
1870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * This method is called after the input filter receives its last input event.
1880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * The input filter should take this opportunity to clean up.
1890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     * </p>
1900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown     */
1910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    public void onUninstalled() {
1920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
1930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1940029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    private final class H extends Handler {
1950029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        public H(Looper looper) {
1960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            super(looper);
1970029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
1980029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
1990029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        @Override
2000029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        public void handleMessage(Message msg) {
2010029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            switch (msg.what) {
2020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                case MSG_INSTALL:
2030029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    mHost = (Host)msg.obj;
2040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    onInstalled();
2050029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    break;
2060029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
2070029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                case MSG_UNINSTALL:
2080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    try {
2090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                        onUninstalled();
2100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    } finally {
2110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                        mHost = null;
2120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    }
2130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    break;
2140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
2150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                case MSG_INPUT_EVENT: {
2160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    final InputEvent event = (InputEvent)msg.obj;
2170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    try {
2180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                        onInputEvent(event, msg.arg1);
2190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    } finally {
2200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                        event.recycle();
2210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    }
2220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    break;
2230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                }
2240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            }
2250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
2260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
2270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
2280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    interface Host {
2290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        public void sendInputEvent(InputEvent event, int policyFlags);
2300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    }
2310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown}
232