InputManager.java revision a47425a13c19f95057df78b8bb65bb25657e8753
19df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown/* 29df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Copyright (C) 2012 The Android Open Source Project 39df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 49df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 59df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * you may not use this file except in compliance with the License. 69df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * You may obtain a copy of the License at 79df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 89df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 99df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Unless required by applicable law or agreed to in writing, software 119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * See the License for the specific language governing permissions and 149df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * limitations under the License. 159df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownpackage android.hardware.input; 189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant; 209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant.SdkConstantType; 219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.content.Context; 22a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Binder; 23af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Handler; 24ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.IBinder; 25af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Looper; 26af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Message; 27ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.RemoteException; 28ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.ServiceManager; 29a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Vibrator; 30ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings; 31ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings.SettingNotFoundException; 329df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.util.Log; 339f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.util.SparseArray; 34ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputDevice; 35ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputEvent; 369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 37af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport java.util.ArrayList; 38af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown/** 409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Provides information about input devices and available key layouts. 419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Get an instance of this class by calling 439df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#getSystemService(java.lang.String) 449df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Context.getSystemService()} with the argument 459df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#INPUT_SERVICE}. 469df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 479df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 489df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownpublic final class InputManager { 499df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown private static final String TAG = "InputManager"; 50af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final boolean DEBUG = false; 51af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 52af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_ADDED = 1; 53af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_REMOVED = 2; 54af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_CHANGED = 3; 559df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 569f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private static InputManager sInstance; 579df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private final IInputManager mIm; 59af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 60af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // Guarded by mInputDevicesLock 61af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final Object mInputDevicesLock = new Object(); 62af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private SparseArray<InputDevice> mInputDevices; 63af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private InputDevicesChangedListener mInputDevicesChangedListener; 64af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = 65af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new ArrayList<InputDeviceListenerDelegate>(); 669df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 679df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Broadcast Action: Query available keyboard layouts. 699df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 709df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager service locates available keyboard layouts 719df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by querying broadcast receivers that are registered for this action. 729df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * An application can offer additional keyboard layouts to the user 739df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by declaring a suitable broadcast receiver in its manifest. 749df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 759df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Here is an example broadcast receiver declaration that an application 769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * might include in its AndroidManifest.xml to advertise keyboard layouts. 779df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The meta-data specifies a resource that contains a description of each keyboard 789df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layout that is provided by the application. 799df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <pre><code> 809df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <receiver android:name=".InputDeviceReceiver"> 819df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <intent-filter> 829df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" /> 839df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </intent-filter> 849df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS" 859df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:resource="@xml/keyboard_layouts" /> 869df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </receiver> 879df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </code></pre> 889df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to 909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * an XML resource whose root element is <code><keyboard-layouts></code> that 919df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * contains zero or more <code><keyboard-layout></code> elements. 929df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Each <code><keyboard-layout></code> element specifies the name, label, and location 939df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * of a key character map for a particular keyboard layout. 949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <pre></code> 959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <?xml version="1.0" encoding="utf-8"?> 969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android"> 979df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layout android:name="keyboard_layout_english_us" 989df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:label="@string/keyboard_layout_english_us_label" 999df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:kcm="@raw/keyboard_layout_english_us" /> 1009df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </keyboard-layouts> 1019df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 1029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:name</code> attribute specifies an identifier by which 1039df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * the keyboard layout will be known in the package. 1049df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:label</code> attributes specifies a human-readable descriptive 1059df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * label to describe the keyboard layout in the user interface, such as "English (US)". 1069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:kcm</code> attribute refers to a 1079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <a href="http://source.android.com/tech/input/key-character-map-files.html"> 1089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * key character map</a> resource that defines the keyboard layout. 1099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String ACTION_QUERY_KEYBOARD_LAYOUTS = 1139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS"; 1149df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 1159df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 1169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Metadata Key: Keyboard layout metadata associated with 1179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}. 1189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 1199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Specifies the resource id of a XML resource that describes the keyboard 1209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layouts that are provided by the application. 1219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1229df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String META_DATA_KEYBOARD_LAYOUTS = 1249df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; 1259df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 126ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 127ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The minimum (slowest) pointer speed (-7). 128ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 129ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 130ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MIN_POINTER_SPEED = -7; 131ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 132ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 133ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The maximum (fastest) pointer speed (7). 134ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 135ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 136ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MAX_POINTER_SPEED = 7; 137ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 138ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 139ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The default pointer speed (0). 140ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 141ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 142ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int DEFAULT_POINTER_SPEED = 0; 143ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 144ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 145ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: None. 146ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Never blocks. Injection is asynchronous and is assumed always to be successful. 147ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 148ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 149ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h 150ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 151ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 152ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for result. 153ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for previous events to be dispatched so that the input dispatcher can 154ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * determine whether input event injection will be permitted based on the current 155ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input focus. Does not wait for the input event to finish being handled 156ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * by the application. 157ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 158ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 159ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1; // see InputDispatcher.h 160ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 161ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 162ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for finish. 163ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for the event to be delivered to the application and handled. 164ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 165ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 166ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h 167ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1689f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private InputManager(IInputManager im) { 1699f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm = im; 170ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 171ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown /** 1739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Gets an instance of the input manager. 1749f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 1759f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @return The input manager instance. 1769f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 1779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @hide 1789f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown */ 1799f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public static InputManager getInstance() { 1809f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown synchronized (InputManager.class) { 1819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (sInstance == null) { 1829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); 1839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown sInstance = new InputManager(IInputManager.Stub.asInterface(b)); 1849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1859f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return sInstance; 1869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1879df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 1889df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 1899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 190af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets information about the input device with the specified id. 191af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param id The device id. 192af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device or null if not found. 193af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 194af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDevice getInputDevice(int id) { 195af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 196af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 197af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 198af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(id); 199af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 200af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return null; 201af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 202af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 203af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDevice inputDevice = mInputDevices.valueAt(index); 204af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (inputDevice == null) { 205af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 206af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown inputDevice = mIm.getInputDevice(id); 207af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 208af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException("Could not get input device information.", ex); 209af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 210af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 211af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.setValueAt(index, inputDevice); 212af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return inputDevice; 213af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 214af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 215af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 216af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 217af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets the ids of all input devices in the system. 218af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device ids. 219af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 220af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public int[] getInputDeviceIds() { 221af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 222af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 223af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 224af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int count = mInputDevices.size(); 225af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids = new int[count]; 226af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < count; i++) { 227af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids[i] = mInputDevices.keyAt(i); 228af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 229af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return ids; 230af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 231af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 232af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 233af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 234af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Registers an input device listener to receive notifications about when 235af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * input devices are added, removed or changed. 236af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 237af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to register. 238af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param handler The handler on which the listener should be invoked, or null 239af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * if the listener should be invoked on the calling thread's looper. 240af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 241af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #unregisterInputDeviceListener 242af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 243af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { 244af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 245af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 246af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 247af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 248af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 249af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 250af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 251af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); 252af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 253af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 254af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 255af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 256af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 257af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Unregisters an input device listener. 258af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 259af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to unregister. 260af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 261af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #registerInputDeviceListener 262af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 263af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void unregisterInputDeviceListener(InputDeviceListener listener) { 264af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 265af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 266af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 267af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 268af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 269af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 270af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 271af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.remove(index); 272af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 273af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 274af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 275af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 276af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private int findInputDeviceListenerLocked(InputDeviceListener listener) { 277af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 278af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 279af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDeviceListeners.get(i).mListener == listener) { 280af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return i; 281af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 282af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 283af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return -1; 284af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 285af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 286af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 2879df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets information about all supported keyboard layouts. 2889df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 2899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager consults the built-in keyboard layouts as well 2909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * as all keyboard layouts advertised by applications using a 2919df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver. 2929df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 2939df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 2949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return A list of all supported keyboard layouts. 2959f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 2969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 2979df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 2989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout[] getKeyboardLayouts() { 2999f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 3009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayouts(); 3019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get list of keyboard layout informations.", ex); 3039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return new KeyboardLayout[0]; 3049df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3059df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout with the specified descriptor. 3099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by 3119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link KeyboardLayout#getDescriptor()}. 3129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout, or null if it could not be loaded. 3139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3149df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3159df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 3179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (keyboardLayoutDescriptor == null) { 3189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 3199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 3229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayout(keyboardLayoutDescriptor); 3239f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get keyboard layout information.", ex); 3259df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown return null; 3269df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3279df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3289df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3299df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3309df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout descriptor for the specified input device. 3319df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3329df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param inputDeviceDescriptor The input device descriptor. 3339df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout descriptor, or null if unknown or if the default 3349df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * keyboard layout will be used. 3359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor) { 3399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (inputDeviceDescriptor == null) { 3409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 3419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3439f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 3449f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayoutForInputDevice(inputDeviceDescriptor); 3459f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get keyboard layout for input device.", ex); 3479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return null; 3489f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 3499df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3509df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3519df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3529df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Sets the keyboard layout descriptor for the specified input device. 3539df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 3549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * This method may have the side-effect of causing the input device in question 3559df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * to be reconfigured. 3569df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 3579df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3589df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param inputDeviceDescriptor The input device descriptor. 3599df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, or null to remove 3609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * the mapping so that the default keyboard layout will be used for the input device. 3619df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3639df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3649f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor, 3659df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown String keyboardLayoutDescriptor) { 3669df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (inputDeviceDescriptor == null) { 3679df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 3689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3699df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3709df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 3719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.setKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor); 3729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not set keyboard layout for input device.", ex); 3749df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3759df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 377ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 378ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Gets the mouse pointer speed. 379ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 380ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Only returns the permanent mouse pointer speed. Ignores any temporary pointer 381ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * speed set by {@link #tryPointerSpeed}. 382ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 383ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 3849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 385ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 386ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 387ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 388ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 389ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 3909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public int getPointerSpeed(Context context) { 391ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = DEFAULT_POINTER_SPEED; 392ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 3939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown speed = Settings.System.getInt(context.getContentResolver(), 394ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED); 395ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (SettingNotFoundException snfe) { 396ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 397ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return speed; 398ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 399ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 400ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 401ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Sets the mouse pointer speed. 402ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 403ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}. 404ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 405ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 4069f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 407ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 408ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 409ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 410ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 411ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setPointerSpeed(Context context, int speed) { 413ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 414ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 415ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 416ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 4179f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Settings.System.putInt(context.getContentResolver(), 418ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED, speed); 419ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 420ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 421ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 422ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Changes the mouse pointer speed temporarily, but does not save the setting. 423ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 424ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}. 425ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 426ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 427ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 428ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 429ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 430ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 431ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 432ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public void tryPointerSpeed(int speed) { 433ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 434ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 435ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 436ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 437ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 4389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.tryPointerSpeed(speed); 439ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 440ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Log.w(TAG, "Could not set temporary pointer speed.", ex); 441ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 442ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 443ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 444ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 445ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Queries the framework about whether any physical keys exist on the 446ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * any keyboard attached to the device that are capable of producing the given 447ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * array of key codes. 448ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 449ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param keyCodes The array of key codes to query. 450ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return A new array of the same size as the key codes array whose elements 451ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * are set to true if at least one attached keyboard supports the corresponding key code 452ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * at the same index in the key codes array. 453ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 454ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 455ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4569f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean[] deviceHasKeys(int[] keyCodes) { 457ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown boolean[] ret = new boolean[keyCodes.length]; 458ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 4599f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret); 460ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException e) { 461ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown // no fallback; just return the empty array 462ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 463ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return ret; 464ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 465ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 466ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 467ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Injects an input event into the event system on behalf of an application. 468ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * The synchronization mode determines whether the method blocks while waiting for 469ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input injection to proceed. 470ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 471ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into 472ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * windows that are owned by other applications. 473ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p><p> 474ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Make sure you correctly set the event time and input source of the event 475ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * before calling this method. 476ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 477ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 478ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param event The event to inject. 479ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param mode The synchronization mode. One of: 480ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_ASYNC}, 481ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or 482ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}. 483ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return True if input event injection succeeded. 484ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 485ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 486ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4879f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean injectInputEvent(InputEvent event, int mode) { 488ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (event == null) { 489ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("event must not be null"); 490ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 491ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mode != INJECT_INPUT_EVENT_MODE_ASYNC 492ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH 493ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) { 494ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("mode is invalid"); 495ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 496ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 497ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 4989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.injectInputEvent(event, mode); 499ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 500ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 501ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 502ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 503af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 504af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void populateInputDevicesLocked() { 505af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevicesChangedListener == null) { 506af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevicesChangedListener listener = new InputDevicesChangedListener(); 507af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 508af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mIm.registerInputDevicesChangedListener(listener); 509af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 510af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException( 511af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown "Could not get register input device changed listener", ex); 512af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 513af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListener = listener; 514af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 515af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 516af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevices == null) { 517af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids; 518af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 519af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids = mIm.getInputDeviceIds(); 520af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 521af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException("Could not get input device ids.", ex); 522af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 523af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 524af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices = new SparseArray<InputDevice>(); 525af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < ids.length; i++) { 526af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(ids[i], null); 527af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 528af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 529af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 530af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 531af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void onInputDevicesChanged(int[] deviceIdAndGeneration) { 532af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 533af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Received input devices changed."); 534af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 535af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 536af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 537af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = mInputDevices.size(); --i > 0; ) { 538af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = mInputDevices.keyAt(i); 539af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!containsDeviceId(deviceIdAndGeneration, deviceId)) { 540af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 541af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device removed: " + deviceId); 542af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 543af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.removeAt(i); 544af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId); 545af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 546af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 547af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 548af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 549af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = deviceIdAndGeneration[i]; 550af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(deviceId); 551af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 552af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice device = mInputDevices.valueAt(index); 553af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device != null) { 554af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int generation = deviceIdAndGeneration[i + 1]; 555af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device.getGeneration() != generation) { 556af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 557af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device changed: " + deviceId); 558af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 559af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.setValueAt(index, null); 560af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId); 561af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 562af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 563af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } else { 564af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 565af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device added: " + deviceId); 566af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 567af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(deviceId, null); 568af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId); 569af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 570af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 571af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 572af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 573af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 574af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) { 575af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 576af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 577af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i); 578af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown listener.sendMessage(listener.obtainMessage(what, deviceId, 0)); 579af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 580af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 581af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 582af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) { 583af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 584af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (deviceIdAndGeneration[i] == deviceId) { 585af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return true; 586af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 587af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 588af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return false; 589af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 590af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 591af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 592a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * Gets a vibrator service associated with an input device, assuming it has one. 593a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @return The vibrator, never null. 594a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @hide 595a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown */ 596a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public Vibrator getInputDeviceVibrator(int deviceId) { 597a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return new InputDeviceVibrator(deviceId); 598a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 599a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 600a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown /** 601af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Listens for changes in input devices. 602af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 603af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public interface InputDeviceListener { 604af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 605af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been added to the system. 606af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Use {@link InputManager#getInputDevice} to get more information about the device. 607af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 608af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was added. 609af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 610af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceAdded(int deviceId); 611af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 612af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 613af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been removed from the system. 614af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 615af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was removed. 616af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 617af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceRemoved(int deviceId); 618af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 619af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 620af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever the properties of an input device have changed since they 621af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * were last queried. Use {@link InputManager#getInputDevice} to get 622af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * a fresh {@link InputDevice} object with the new properties. 623af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 624af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that changed. 625af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 626af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceChanged(int deviceId); 627af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 628af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 629af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub { 630af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 631af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException { 632af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputManager.this.onInputDevicesChanged(deviceIdAndGeneration); 633af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 634af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 635af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 636af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final class InputDeviceListenerDelegate extends Handler { 637af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public final InputDeviceListener mListener; 638af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 639af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) { 640af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown super(handler != null ? handler.getLooper() : Looper.myLooper()); 641af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener = listener; 642af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 643af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 644af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 645af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void handleMessage(Message msg) { 646af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown switch (msg.what) { 647af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_ADDED: 648af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceAdded(msg.arg1); 649af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 650af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_REMOVED: 651af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceRemoved(msg.arg1); 652af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 653af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_CHANGED: 654af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceChanged(msg.arg1); 655af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 656af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 657af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 658af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 659a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 660a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final class InputDeviceVibrator extends Vibrator { 661a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final int mDeviceId; 662a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final Binder mToken; 663a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 664a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public InputDeviceVibrator(int deviceId) { 665a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mDeviceId = deviceId; 666a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mToken = new Binder(); 667a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 668a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 669a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 670a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public boolean hasVibrator() { 671a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return true; 672a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 673a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 674a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 675a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void vibrate(long milliseconds) { 676a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown vibrate(new long[] { 0, milliseconds}, -1); 677a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 678a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 679a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 680a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void vibrate(long[] pattern, int repeat) { 681a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (repeat >= pattern.length) { 682a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new ArrayIndexOutOfBoundsException(); 683a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 684a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 685a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.vibrate(mDeviceId, pattern, repeat, mToken); 686a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 687a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to vibrate.", ex); 688a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 689a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 690a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 691a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 692a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void cancel() { 693a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 694a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.cancelVibrate(mDeviceId, mToken); 695a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 696a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to cancel vibration.", ex); 697a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 698a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 699a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 7009df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown} 701