InputManager.java revision 2f0957607411b99810226ad38d59cf18718b86d0
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" 992f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * android:keyboardLayout="@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)". 1062f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * The <code>android:keyboardLayout</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) { 2719e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown InputDeviceListenerDelegate d = mInputDeviceListeners.get(index); 2729e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown d.removeCallbacksAndMessages(null); 273af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.remove(index); 274af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 275af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 276af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 277af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 278af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private int findInputDeviceListenerLocked(InputDeviceListener listener) { 279af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 280af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 281af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDeviceListeners.get(i).mListener == listener) { 282af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return i; 283af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 284af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 285af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return -1; 286af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 287af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 288af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 2899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets information about all supported keyboard layouts. 2909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 2919df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager consults the built-in keyboard layouts as well 2929df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * as all keyboard layouts advertised by applications using a 2939df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver. 2949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 2959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 2969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return A list of all supported keyboard layouts. 2979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 2989df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 2999df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout[] getKeyboardLayouts() { 3019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 3029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayouts(); 3039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get list of keyboard layout informations.", ex); 3059f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return new KeyboardLayout[0]; 3069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout with the specified descriptor. 3119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by 3139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link KeyboardLayout#getDescriptor()}. 3149df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout, or null if it could not be loaded. 3159df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 3199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (keyboardLayoutDescriptor == null) { 3209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 3219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3229df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 3249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayout(keyboardLayoutDescriptor); 3259f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3269f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get keyboard layout information.", ex); 3279df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown return null; 3289df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3299df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3309df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3319df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3329df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout descriptor for the specified input device. 3339df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3349df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param inputDeviceDescriptor The input device descriptor. 3359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout descriptor, or null if unknown or if the default 3369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * keyboard layout will be used. 3379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3389df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public String getKeyboardLayoutForInputDevice(String inputDeviceDescriptor) { 3419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (inputDeviceDescriptor == null) { 3429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 3439df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3449df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3459f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 3469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayoutForInputDevice(inputDeviceDescriptor); 3479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3489f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get keyboard layout for input device.", ex); 3499f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return null; 3509f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 3519df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3529df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3539df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Sets the keyboard layout descriptor for the specified input device. 3559df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 3569df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * This method may have the side-effect of causing the input device in question 3579df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * to be reconfigured. 3589df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 3599df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param inputDeviceDescriptor The input device descriptor. 3619df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, or null to remove 3629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * the mapping so that the default keyboard layout will be used for the input device. 3639df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3649df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3659df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3669f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setKeyboardLayoutForInputDevice(String inputDeviceDescriptor, 3679df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown String keyboardLayoutDescriptor) { 3689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (inputDeviceDescriptor == null) { 3699df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 3709df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3719df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3729df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 3739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.setKeyboardLayoutForInputDevice(inputDeviceDescriptor, keyboardLayoutDescriptor); 3749f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3759f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not set keyboard layout for input device.", ex); 3769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3779df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3789df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 379ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 380ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Gets the mouse pointer speed. 381ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 382ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Only returns the permanent mouse pointer speed. Ignores any temporary pointer 383ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * speed set by {@link #tryPointerSpeed}. 384ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 385ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 3869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 387ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 388ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 389ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 390ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 391ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 3929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public int getPointerSpeed(Context context) { 393ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = DEFAULT_POINTER_SPEED; 394ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 3959f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown speed = Settings.System.getInt(context.getContentResolver(), 396ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED); 397ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (SettingNotFoundException snfe) { 398ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 399ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return speed; 400ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 401ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 402ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 403ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Sets the mouse pointer speed. 404ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 405ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}. 406ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 407ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 4089f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 409ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 410ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 411ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 412ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 413ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4149f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setPointerSpeed(Context context, int speed) { 415ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 416ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 417ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 418ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 4199f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Settings.System.putInt(context.getContentResolver(), 420ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED, speed); 421ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 422ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 423ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 424ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Changes the mouse pointer speed temporarily, but does not save the setting. 425ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 426ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}. 427ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 428ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 429ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 430ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 431ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 432ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 433ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 434ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public void tryPointerSpeed(int speed) { 435ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 436ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 437ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 438ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 439ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 4409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.tryPointerSpeed(speed); 441ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 442ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Log.w(TAG, "Could not set temporary pointer speed.", ex); 443ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 444ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 445ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 446ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 447ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Queries the framework about whether any physical keys exist on the 448ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * any keyboard attached to the device that are capable of producing the given 449ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * array of key codes. 450ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 451ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param keyCodes The array of key codes to query. 452ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return A new array of the same size as the key codes array whose elements 453ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * are set to true if at least one attached keyboard supports the corresponding key code 454ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * at the same index in the key codes array. 455ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 456ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 457ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean[] deviceHasKeys(int[] keyCodes) { 459ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown boolean[] ret = new boolean[keyCodes.length]; 460ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 4619f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret); 462ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException e) { 463ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown // no fallback; just return the empty array 464ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 465ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return ret; 466ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 467ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 468ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 469ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Injects an input event into the event system on behalf of an application. 470ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * The synchronization mode determines whether the method blocks while waiting for 471ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input injection to proceed. 472ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 473ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into 474ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * windows that are owned by other applications. 475ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p><p> 476ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Make sure you correctly set the event time and input source of the event 477ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * before calling this method. 478ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 479ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 480ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param event The event to inject. 481ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param mode The synchronization mode. One of: 482ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_ASYNC}, 483ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or 484ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}. 485ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return True if input event injection succeeded. 486ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 487ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 488ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 4899f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean injectInputEvent(InputEvent event, int mode) { 490ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (event == null) { 491ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("event must not be null"); 492ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 493ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mode != INJECT_INPUT_EVENT_MODE_ASYNC 494ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH 495ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) { 496ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("mode is invalid"); 497ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 498ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 499ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 5009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.injectInputEvent(event, mode); 501ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 502ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 503ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 504ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 505af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 506af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void populateInputDevicesLocked() { 507af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevicesChangedListener == null) { 508af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevicesChangedListener listener = new InputDevicesChangedListener(); 509af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 510af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mIm.registerInputDevicesChangedListener(listener); 511af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 512af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException( 513af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown "Could not get register input device changed listener", ex); 514af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 515af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListener = listener; 516af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 517af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 518af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevices == null) { 519af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids; 520af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 521af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids = mIm.getInputDeviceIds(); 522af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 523af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException("Could not get input device ids.", ex); 524af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 525af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 526af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices = new SparseArray<InputDevice>(); 527af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < ids.length; i++) { 528af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(ids[i], null); 529af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 530af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 531af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 532af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 533af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void onInputDevicesChanged(int[] deviceIdAndGeneration) { 534af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 535af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Received input devices changed."); 536af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 537af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 538af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 539af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = mInputDevices.size(); --i > 0; ) { 540af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = mInputDevices.keyAt(i); 541af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!containsDeviceId(deviceIdAndGeneration, deviceId)) { 542af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 543af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device removed: " + deviceId); 544af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 545af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.removeAt(i); 546af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId); 547af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 548af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 549af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 550af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 551af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = deviceIdAndGeneration[i]; 552af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(deviceId); 553af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 554af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice device = mInputDevices.valueAt(index); 555af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device != null) { 556af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int generation = deviceIdAndGeneration[i + 1]; 557af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device.getGeneration() != generation) { 558af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 559af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device changed: " + deviceId); 560af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 561af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.setValueAt(index, null); 562af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId); 563af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 564af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 565af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } else { 566af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 567af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device added: " + deviceId); 568af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 569af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(deviceId, null); 570af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId); 571af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 572af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 573af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 574af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 575af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 576af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) { 577af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 578af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 579af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i); 580af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown listener.sendMessage(listener.obtainMessage(what, deviceId, 0)); 581af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 582af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 583af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 584af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) { 585af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 586af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (deviceIdAndGeneration[i] == deviceId) { 587af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return true; 588af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 589af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 590af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return false; 591af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 592af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 593af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 594a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * Gets a vibrator service associated with an input device, assuming it has one. 595a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @return The vibrator, never null. 596a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @hide 597a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown */ 598a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public Vibrator getInputDeviceVibrator(int deviceId) { 599a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return new InputDeviceVibrator(deviceId); 600a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 601a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 602a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown /** 603af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Listens for changes in input devices. 604af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 605af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public interface InputDeviceListener { 606af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 607af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been added to the system. 608af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Use {@link InputManager#getInputDevice} to get more information about the device. 609af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 610af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was added. 611af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 612af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceAdded(int deviceId); 613af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 614af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 615af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been removed from the system. 616af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 617af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was removed. 618af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 619af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceRemoved(int deviceId); 620af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 621af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 622af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever the properties of an input device have changed since they 623af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * were last queried. Use {@link InputManager#getInputDevice} to get 624af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * a fresh {@link InputDevice} object with the new properties. 625af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 626af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that changed. 627af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 628af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceChanged(int deviceId); 629af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 630af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 631af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub { 632af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 633af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException { 634af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputManager.this.onInputDevicesChanged(deviceIdAndGeneration); 635af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 636af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 637af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 638af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final class InputDeviceListenerDelegate extends Handler { 639af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public final InputDeviceListener mListener; 640af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 641af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) { 642af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown super(handler != null ? handler.getLooper() : Looper.myLooper()); 643af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener = listener; 644af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 645af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 646af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 647af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void handleMessage(Message msg) { 648af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown switch (msg.what) { 649af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_ADDED: 650af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceAdded(msg.arg1); 651af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 652af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_REMOVED: 653af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceRemoved(msg.arg1); 654af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 655af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_CHANGED: 656af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceChanged(msg.arg1); 657af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 658af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 659af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 660af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 661a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 662a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final class InputDeviceVibrator extends Vibrator { 663a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final int mDeviceId; 664a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final Binder mToken; 665a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 666a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public InputDeviceVibrator(int deviceId) { 667a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mDeviceId = deviceId; 668a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mToken = new Binder(); 669a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 670a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 671a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 672a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public boolean hasVibrator() { 673a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return true; 674a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 675a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 676a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 677a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void vibrate(long milliseconds) { 678a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown vibrate(new long[] { 0, milliseconds}, -1); 679a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 680a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 681a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 682a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void vibrate(long[] pattern, int repeat) { 683a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (repeat >= pattern.length) { 684a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new ArrayIndexOutOfBoundsException(); 685a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 686a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 687a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.vibrate(mDeviceId, pattern, repeat, mToken); 688a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 689a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to vibrate.", ex); 690a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 691a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 692a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 693a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 694a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void cancel() { 695a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 696a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.cancelVibrate(mDeviceId, mToken); 697a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 698a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to cancel vibration.", ex); 699a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 700a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 701a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 7029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown} 703