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 17c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovpackage android.view; 180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Handler; 200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Looper; 210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.os.Message; 22c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.os.RemoteException; 23c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.IInputFilter; 240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.InputEvent; 2521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brownimport android.view.InputEventConsistencyVerifier; 260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.KeyEvent; 270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.MotionEvent; 280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.WindowManagerPolicy; 290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown/** 310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Filters input events before they are dispatched to the system. 320029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 330029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * At most one input filter can be installed by calling 340029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerService#setInputFilter}. When an input filter is installed, the 350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * system's behavior changes as follows: 360029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <ul> 370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>Input events are first delivered to the {@link WindowManagerPolicy} 384532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * interception methods before queuing as usual. This critical step takes care of managing 390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the power state of the device and handling wake keys.</li> 400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>Input events are then asynchronously delivered to the input filter's 410029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to 420029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * applications as usual. The input filter only receives input events that were 430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * generated by input device; the input filter will not receive input events that were 440029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * injected into the system by other means, such as by instrumentation.</li> 450029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <li>The input filter processes and optionally transforms the stream of events. For example, 460029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * it may transform a sequence of motion events representing an accessibility gesture into 470029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * a different sequence of motion events, key presses or other system-level interactions. 480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter can send events to be dispatched by calling 490029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link #sendInputEvent(InputEvent)} and passing appropriate policy flags for the 500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * input event.</li> 510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </ul> 520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <h3>The importance of input event consistency</h3> 540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter mechanism is very low-level. At a minimum, it needs to ensure that it 560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * sends an internally consistent stream of input events to the dispatcher. There are 570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * very important invariants to be maintained. 580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * For example, if a key down is sent, a corresponding key up should also be sent eventually. 600029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Likewise, for touch events, each pointer must individually go down with 610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link MotionEvent#ACTION_DOWN} or {@link MotionEvent#ACTION_POINTER_DOWN} and then 620029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * individually go up with {@link MotionEvent#ACTION_POINTER_UP} or {@link MotionEvent#ACTION_UP} 630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * and the sequence of pointer ids used must be consistent throughout the gesture. 640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Sometimes a filter may wish to cancel a previously dispatched key or motion. It should 660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * use {@link KeyEvent#FLAG_CANCELED} or {@link MotionEvent#ACTION_CANCEL} accordingly. 670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter must take into account the fact that the input events coming from different 690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * devices or even different sources all consist of distinct streams of input. 700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify 710029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the source of the event and its semantics. There are be multiple sources of keys, 720029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * touches and other input: they must be kept separate. 730029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 740029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <h3>Policy flags</h3> 750029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Input events received from the dispatcher and sent to the dispatcher have policy flags 770029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * associated with them. Policy flags control some functions of the dispatcher. 780029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 790029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The early policy interception decides whether an input event should be delivered 800029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * to applications or dropped. The policy indicates its decision by setting the 810029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag. The input filter may 820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * sometimes receive events that do not have this flag set. It should take note of 830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * the fact that the policy intends to drop the event, clean up its state, and 844532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * then send appropriate cancellation events to the dispatcher if needed. 850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * For example, suppose the input filter is processing a gesture and one of the touch events 870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set. 880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter should clear its internal state about the gesture and then send key or 890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * motion events to the dispatcher to cancel any keys or pointers that are down. 900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Corollary: Events that set sent to the dispatcher should usually include the 920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag. Otherwise, they will be dropped! 930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 944532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * It may be prudent to disable automatic key repeating for synthetic key events 954532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag. 960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 97c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov * 98c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov * @hide 990029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 100c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovpublic abstract class InputFilter extends IInputFilter.Stub { 1010029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private static final int MSG_INSTALL = 1; 1020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private static final int MSG_UNINSTALL = 2; 1030029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private static final int MSG_INPUT_EVENT = 3; 1040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 10521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown // Consistency verifiers for debugging purposes. 10621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown private final InputEventConsistencyVerifier mInboundInputEventConsistencyVerifier = 10721bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown InputEventConsistencyVerifier.isInstrumentationEnabled() ? 10821bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown new InputEventConsistencyVerifier(this, 109736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov InputEventConsistencyVerifier.FLAG_RAW_DEVICE_INPUT, 110736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov "InputFilter#InboundInputEventConsistencyVerifier") : null; 11121bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown private final InputEventConsistencyVerifier mOutboundInputEventConsistencyVerifier = 11221bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown InputEventConsistencyVerifier.isInstrumentationEnabled() ? 11321bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown new InputEventConsistencyVerifier(this, 114736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov InputEventConsistencyVerifier.FLAG_RAW_DEVICE_INPUT, 115736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov "InputFilter#OutboundInputEventConsistencyVerifier") : null; 11621bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown 117c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov private final H mH; 118c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov 119c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov private IInputFilterHost mHost; 120c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov 1210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Creates the input filter. 1230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 1240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param looper The looper to run callbacks on. 1250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 1260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public InputFilter(Looper looper) { 1270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mH = new H(looper); 1280029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1290029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1300029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1310029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called when the input filter is installed. 1320029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * This method is guaranteed to be non-reentrant. 1330029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 1340029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param host The input filter host environment. 1350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 136c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov public final void install(IInputFilterHost host) { 1370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mH.obtainMessage(MSG_INSTALL, host).sendToTarget(); 1380029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1410029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called when the input filter is uninstalled. 1420029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * This method is guaranteed to be non-reentrant. 1430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 144c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov public final void uninstall() { 1450029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mH.obtainMessage(MSG_UNINSTALL).sendToTarget(); 1460029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1470029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1490029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called to enqueue the input event for filtering. 1500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The event will be recycled after the input filter processes it. 1510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * This method is guaranteed to be non-reentrant. 1520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 1530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param event The input event to enqueue. 1540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 155c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov final public void filterInputEvent(InputEvent event, int policyFlags) { 1560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mH.obtainMessage(MSG_INPUT_EVENT, policyFlags, 0, event).sendToTarget(); 1570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1600029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Sends an input event to the dispatcher. 1610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 1620029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param event The input event to publish. 1630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param policyFlags The input event policy flags. 1640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 1650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void sendInputEvent(InputEvent event, int policyFlags) { 1660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (event == null) { 1670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown throw new IllegalArgumentException("event must not be null"); 1680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (mHost == null) { 1700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown throw new IllegalStateException("Cannot send input event because the input filter " + 1710029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown "is not installed."); 1720029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 17321bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown if (mOutboundInputEventConsistencyVerifier != null) { 17421bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown mOutboundInputEventConsistencyVerifier.onInputEvent(event, 0); 17521bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown } 176c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 177c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov mHost.sendInputEvent(event, policyFlags); 178c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException re) { 179c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 180c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 1810029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 1840029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called when an input event has been received from the dispatcher. 1850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 1860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The default implementation sends the input event back to the dispatcher, unchanged. 1870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p><p> 1880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The event will be recycled when this method returns. If you want to keep it around, 1890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * make a copy! 1900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 1910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 1920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param event The input event that was received. 1930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param policyFlags The input event policy flags. 1940029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 1950029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onInputEvent(InputEvent event, int policyFlags) { 1960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown sendInputEvent(event, policyFlags); 1970029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 1980029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 1990029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 2000029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called when the filter is installed into the dispatch pipeline. 2010029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 2020029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * This method is called before the input filter receives any input events. 2030029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter should take this opportunity to prepare itself. 2040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 2050029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 2060029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onInstalled() { 2070029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 2090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 2100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Called when the filter is uninstalled from the dispatch pipeline. 2110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * <p> 2120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * This method is called after the input filter receives its last input event. 2130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter should take this opportunity to clean up. 2140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * </p> 2150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 2160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void onUninstalled() { 2170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 2190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown private final class H extends Handler { 2200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public H(Looper looper) { 2210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown super(looper); 2220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 2240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown @Override 2250029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown public void handleMessage(Message msg) { 2260029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown switch (msg.what) { 2270029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown case MSG_INSTALL: 228c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov mHost = (IInputFilterHost) msg.obj; 22921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown if (mInboundInputEventConsistencyVerifier != null) { 23021bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown mInboundInputEventConsistencyVerifier.reset(); 23121bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown } 23221bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown if (mOutboundInputEventConsistencyVerifier != null) { 23321bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown mOutboundInputEventConsistencyVerifier.reset(); 23421bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown } 2350029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown onInstalled(); 2360029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown break; 2370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 2380029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown case MSG_UNINSTALL: 2390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown try { 2400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown onUninstalled(); 2410029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } finally { 2420029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mHost = null; 2430029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2440029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown break; 2450029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 2460029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown case MSG_INPUT_EVENT: { 2470029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown final InputEvent event = (InputEvent)msg.obj; 2480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown try { 24921bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown if (mInboundInputEventConsistencyVerifier != null) { 25021bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown mInboundInputEventConsistencyVerifier.onInputEvent(event, 0); 25121bc5c917d4ee2a9b2b8173091e6bba85eaff899Jeff Brown } 2520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown onInputEvent(event, msg.arg1); 2530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } finally { 2540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown event.recycle(); 2550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown break; 2570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2600029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 2610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown} 262