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