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 19cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport com.android.internal.util.ArrayUtils; 20cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant; 229df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant.SdkConstantType; 239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.content.Context; 247b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlockimport android.media.AudioAttributes; 25a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Binder; 26af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Handler; 27ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.IBinder; 28af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Looper; 29af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Message; 30fb290df3c9a6f37ec050163029e25844de2f8590RoboErikimport android.os.Parcel; 31fb290df3c9a6f37ec050163029e25844de2f8590RoboErikimport android.os.Parcelable; 32ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.RemoteException; 33ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.ServiceManager; 34a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Vibrator; 35ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings; 36ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings.SettingNotFoundException; 379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.util.Log; 389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.util.SparseArray; 39ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputDevice; 40ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputEvent; 419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 42af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport java.util.ArrayList; 43af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 449df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown/** 459df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Provides information about input devices and available key layouts. 469df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 479df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Get an instance of this class by calling 489df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#getSystemService(java.lang.String) 499df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Context.getSystemService()} with the argument 509df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#INPUT_SERVICE}. 519df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 529df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 539df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownpublic final class InputManager { 549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown private static final String TAG = "InputManager"; 55af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final boolean DEBUG = false; 56af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 57af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_ADDED = 1; 58af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_REMOVED = 2; 59af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_CHANGED = 3; 609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 619f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private static InputManager sInstance; 629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 639f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private final IInputManager mIm; 64af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 65af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // Guarded by mInputDevicesLock 66af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final Object mInputDevicesLock = new Object(); 67af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private SparseArray<InputDevice> mInputDevices; 68af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private InputDevicesChangedListener mInputDevicesChangedListener; 69af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = 70af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new ArrayList<InputDeviceListenerDelegate>(); 719df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 729df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 739df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Broadcast Action: Query available keyboard layouts. 749df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 759df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager service locates available keyboard layouts 769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by querying broadcast receivers that are registered for this action. 779df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * An application can offer additional keyboard layouts to the user 789df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by declaring a suitable broadcast receiver in its manifest. 799df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 809df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Here is an example broadcast receiver declaration that an application 819df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * might include in its AndroidManifest.xml to advertise keyboard layouts. 829df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The meta-data specifies a resource that contains a description of each keyboard 839df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layout that is provided by the application. 849df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <pre><code> 85d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * <receiver android:name=".InputDeviceReceiver" 86d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * android:label="@string/keyboard_layouts_label"> 879df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <intent-filter> 889df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" /> 899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </intent-filter> 909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS" 919df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:resource="@xml/keyboard_layouts" /> 929df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </receiver> 939df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </code></pre> 949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to 969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * an XML resource whose root element is <code><keyboard-layouts></code> that 979df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * contains zero or more <code><keyboard-layout></code> elements. 989df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Each <code><keyboard-layout></code> element specifies the name, label, and location 99d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * of a key character map for a particular keyboard layout. The label on the receiver 100d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * is used to name the collection of keyboard layouts provided by this receiver in the 101d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * keyboard layout settings. 1029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <pre></code> 1039df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <?xml version="1.0" encoding="utf-8"?> 1049df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android"> 1059df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layout android:name="keyboard_layout_english_us" 1069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:label="@string/keyboard_layout_english_us_label" 1072f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * android:keyboardLayout="@raw/keyboard_layout_english_us" /> 1089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </keyboard-layouts> 1099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 1109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:name</code> attribute specifies an identifier by which 1119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * the keyboard layout will be known in the package. 1129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:label</code> attributes specifies a human-readable descriptive 1139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * label to describe the keyboard layout in the user interface, such as "English (US)". 1142f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * The <code>android:keyboardLayout</code> attribute refers to a 1159df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <a href="http://source.android.com/tech/input/key-character-map-files.html"> 1169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * key character map</a> resource that defines the keyboard layout. 1179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String ACTION_QUERY_KEYBOARD_LAYOUTS = 1219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS"; 1229df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 1239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 1249df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Metadata Key: Keyboard layout metadata associated with 1259df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}. 1269df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 1279df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Specifies the resource id of a XML resource that describes the keyboard 1289df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layouts that are provided by the application. 1299df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1309df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1319df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String META_DATA_KEYBOARD_LAYOUTS = 1329df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; 1339df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 134ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 135ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The minimum (slowest) pointer speed (-7). 136ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 137ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 138ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MIN_POINTER_SPEED = -7; 139ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 140ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 141ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The maximum (fastest) pointer speed (7). 142ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 143ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 144ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MAX_POINTER_SPEED = 7; 145ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 146ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 147ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The default pointer speed (0). 148ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 149ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 150ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int DEFAULT_POINTER_SPEED = 0; 151ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 152ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 153ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: None. 154ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Never blocks. Injection is asynchronous and is assumed always to be successful. 155ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 156ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 157ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h 158ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 159ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 160ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for result. 161ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for previous events to be dispatched so that the input dispatcher can 162ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * determine whether input event injection will be permitted based on the current 163ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input focus. Does not wait for the input event to finish being handled 164ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * by the application. 165ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 166ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 167ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1; // see InputDispatcher.h 168ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 169ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 170ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for finish. 171ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for the event to be delivered to the application and handled. 172ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 173ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 174ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h 175ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1769f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private InputManager(IInputManager im) { 1779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm = im; 178ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 179ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1809f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown /** 1819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Gets an instance of the input manager. 1829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 1839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @return The input manager instance. 1849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 1859f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @hide 1869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown */ 1879f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public static InputManager getInstance() { 1889f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown synchronized (InputManager.class) { 1899f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (sInstance == null) { 1909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); 1919f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown sInstance = new InputManager(IInputManager.Stub.asInterface(b)); 1929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return sInstance; 1949f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 1969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 1979df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 198af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets information about the input device with the specified id. 199af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param id The device id. 200af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device or null if not found. 201af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 202af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDevice getInputDevice(int id) { 203af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 204af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 205af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 206af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(id); 207af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 208af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return null; 209af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 210af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 211af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDevice inputDevice = mInputDevices.valueAt(index); 212af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (inputDevice == null) { 213af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 214af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown inputDevice = mIm.getInputDevice(id); 215af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 216af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException("Could not get input device information.", ex); 217af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2188f124842dd16125062f048257889c85380879b68Jeff Brown if (inputDevice != null) { 2198f124842dd16125062f048257889c85380879b68Jeff Brown mInputDevices.setValueAt(index, inputDevice); 2208f124842dd16125062f048257889c85380879b68Jeff Brown } 221af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 222af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return inputDevice; 223af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 224af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 225af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 226af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 227cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Gets information about the input device with the specified descriptor. 228cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @param descriptor The input device descriptor. 229cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @return The input device or null if not found. 230cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 231cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 232cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown public InputDevice getInputDeviceByDescriptor(String descriptor) { 233cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (descriptor == null) { 234cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("descriptor must not be null."); 235cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 236cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 237cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mInputDevicesLock) { 238cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown populateInputDevicesLocked(); 239cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 240cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown int numDevices = mInputDevices.size(); 241cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown for (int i = 0; i < numDevices; i++) { 242cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown InputDevice inputDevice = mInputDevices.valueAt(i); 243cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (inputDevice == null) { 244cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown int id = mInputDevices.keyAt(i); 245cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 246cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown inputDevice = mIm.getInputDevice(id); 247cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 248cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Ignore the problem for the purposes of this method. 2498f124842dd16125062f048257889c85380879b68Jeff Brown } 2508f124842dd16125062f048257889c85380879b68Jeff Brown if (inputDevice == null) { 251cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown continue; 252cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 253cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mInputDevices.setValueAt(i, inputDevice); 254cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 255cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (descriptor.equals(inputDevice.getDescriptor())) { 256cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return inputDevice; 257cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 258cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 259cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return null; 260cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 261cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 262cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 263cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 264af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets the ids of all input devices in the system. 265af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device ids. 266af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 267af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public int[] getInputDeviceIds() { 268af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 269af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 270af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 271af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int count = mInputDevices.size(); 272af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids = new int[count]; 273af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < count; i++) { 274af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids[i] = mInputDevices.keyAt(i); 275af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 276af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return ids; 277af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 278af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 279af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 280af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 281af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Registers an input device listener to receive notifications about when 282af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * input devices are added, removed or changed. 283af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 284af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to register. 285af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param handler The handler on which the listener should be invoked, or null 286af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * if the listener should be invoked on the calling thread's looper. 287af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 288af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #unregisterInputDeviceListener 289af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 290af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { 291af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 292af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 293af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 294af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 295af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 296af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 297af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 298af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); 299af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 300af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 301af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 302af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 303af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 304af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Unregisters an input device listener. 305af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 306af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to unregister. 307af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 308af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #registerInputDeviceListener 309af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 310af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void unregisterInputDeviceListener(InputDeviceListener listener) { 311af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 312af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 313af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 314af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 315af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 316af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 317af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 3189e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown InputDeviceListenerDelegate d = mInputDeviceListeners.get(index); 3199e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown d.removeCallbacksAndMessages(null); 320af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.remove(index); 321af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 322af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 323af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 324af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 325af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private int findInputDeviceListenerLocked(InputDeviceListener listener) { 326af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 327af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 328af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDeviceListeners.get(i).mListener == listener) { 329af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return i; 330af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 331af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 332af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return -1; 333af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 334af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 335af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 3369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets information about all supported keyboard layouts. 3379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 3389df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager consults the built-in keyboard layouts as well 3399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * as all keyboard layouts advertised by applications using a 3409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver. 3419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 3429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3439df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return A list of all supported keyboard layouts. 3449f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 3459df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3469df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout[] getKeyboardLayouts() { 3489f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 3499f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayouts(); 3509f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3519f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get list of keyboard layout informations.", ex); 3529f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return new KeyboardLayout[0]; 3539df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3559df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3569df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 3579df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout with the specified descriptor. 3589df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3599df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by 3609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link KeyboardLayout#getDescriptor()}. 3619df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout, or null if it could not be loaded. 3629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 3639df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3649df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 3659df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 3669df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (keyboardLayoutDescriptor == null) { 3679df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 3689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3699df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3709df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 3719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayout(keyboardLayoutDescriptor); 3729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 3739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Log.w(TAG, "Could not get keyboard layout information.", ex); 3749df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown return null; 3759df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3779df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3789df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 379fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Gets the current keyboard layout descriptor for the specified input 380fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * device. 3819df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 382fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier Identifier for the input device 383fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @return The keyboard layout descriptor, or null if no keyboard layout has 384fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * been set. 3859df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 3869df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 387fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) { 3889f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 389fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return mIm.getCurrentKeyboardLayoutForInputDevice(identifier); 3909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 391cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Log.w(TAG, "Could not get current keyboard layout for input device.", ex); 3929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return null; 3939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 3949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 3959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 3969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 397fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Sets the current keyboard layout descriptor for the specified input 398fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * device. 3999df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 400fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 401fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 4029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 4039df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 404fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 405fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The keyboard layout descriptor to use, 406fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * must not be null. 4079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 4089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 409fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 4109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown String keyboardLayoutDescriptor) { 411fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 412fb290df3c9a6f37ec050163029e25844de2f8590RoboErik throw new IllegalArgumentException("identifier must not be null"); 4139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 414cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 415cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 416cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 417cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 418cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 419fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.setCurrentKeyboardLayoutForInputDevice(identifier, 420cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown keyboardLayoutDescriptor); 421cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 422cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Log.w(TAG, "Could not set current keyboard layout for input device.", ex); 423cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 424cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 425cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 426cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 427fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Gets all keyboard layout descriptors that are enabled for the specified 428fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * input device. 429cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 430fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 431cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @return The keyboard layout descriptors. 432cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 433cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 434fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public String[] getKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { 435fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 436cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 437cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 438cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 439cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 440fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return mIm.getKeyboardLayoutsForInputDevice(identifier); 441cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 442cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Log.w(TAG, "Could not get keyboard layouts for input device.", ex); 443cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return ArrayUtils.emptyArray(String.class); 444cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 445cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 446cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 447cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 448cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Adds the keyboard layout descriptor for the specified input device. 449cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * <p> 450fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 451fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 452cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * </p> 453cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 454fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 455fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to 456fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * add. 457cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 458cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 459fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 460cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 461fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 462cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 463cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 464cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 465cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 466cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 467cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 468cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 469fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.addKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor); 470cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 471cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Log.w(TAG, "Could not add keyboard layout for input device.", ex); 472cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 473cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 474cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 475cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 476cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Removes the keyboard layout descriptor for the specified input device. 477cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * <p> 478fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 479fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 480cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * </p> 481cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 482fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 483fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to 484fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * remove. 485cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 486cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 487fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 488cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 489fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 490cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 491cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 492cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 493cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 494cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 4959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 4969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 497fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.removeKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor); 4989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 499cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Log.w(TAG, "Could not remove keyboard layout for input device.", ex); 5009df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5019df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 503ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 504d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * Gets the TouchCalibration applied to the specified input device's coordinates. 505d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 506d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param inputDeviceDescriptor The input device descriptor. 507d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @return The TouchCalibration currently assigned for use with the given 508d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * input device. If none is set, an identity TouchCalibration is returned. 509d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 510d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @hide 511d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke */ 512d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) { 513d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke try { 514d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation); 515d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } catch (RemoteException ex) { 516d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke Log.w(TAG, "Could not get calibration matrix for input device.", ex); 517d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke return TouchCalibration.IDENTITY; 518d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 519d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 520d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 521d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke /** 522d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * Sets the TouchCalibration to apply to the specified input device's coordinates. 523d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * <p> 524d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * This method may have the side-effect of causing the input device in question 525d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * to be reconfigured. Requires {@link android.Manifest.permissions.SET_INPUT_CALIBRATION}. 526d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * </p> 527d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 528d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param inputDeviceDescriptor The input device descriptor. 529d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param calibration The calibration to be applied 530d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 531d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @hide 532d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke */ 533d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, 534d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke TouchCalibration calibration) { 535d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke try { 536d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration); 537d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } catch (RemoteException ex) { 538d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke Log.w(TAG, "Could not set calibration matrix for input device.", ex); 539d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 540d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 541d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 542d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke /** 543ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Gets the mouse pointer speed. 544ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 545ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Only returns the permanent mouse pointer speed. Ignores any temporary pointer 546ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * speed set by {@link #tryPointerSpeed}. 547ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 548ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 5499f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 550ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 551ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 552ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 553ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 554ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 5559f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public int getPointerSpeed(Context context) { 556ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = DEFAULT_POINTER_SPEED; 557ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 5589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown speed = Settings.System.getInt(context.getContentResolver(), 559ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED); 560ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (SettingNotFoundException snfe) { 561ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 562ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return speed; 563ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 564ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 565ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 566ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Sets the mouse pointer speed. 567ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 568ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}. 569ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 570ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 5719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 572ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 573ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 574ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 575ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 576ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 5779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setPointerSpeed(Context context, int speed) { 578ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 579ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 580ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 581ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 5829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Settings.System.putInt(context.getContentResolver(), 583ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED, speed); 584ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 585ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 586ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 587ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Changes the mouse pointer speed temporarily, but does not save the setting. 588ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 589ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}. 590ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 591ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 592ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 593ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 594ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 595ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 596ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 597ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public void tryPointerSpeed(int speed) { 598ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 599ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 600ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 601ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 602ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 6039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.tryPointerSpeed(speed); 604ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 605ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Log.w(TAG, "Could not set temporary pointer speed.", ex); 606ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 607ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 608ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 609ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 610ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Queries the framework about whether any physical keys exist on the 611ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * any keyboard attached to the device that are capable of producing the given 612ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * array of key codes. 613ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 614ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param keyCodes The array of key codes to query. 615ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return A new array of the same size as the key codes array whose elements 616ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * are set to true if at least one attached keyboard supports the corresponding key code 617ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * at the same index in the key codes array. 618ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 619ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 620ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 6219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean[] deviceHasKeys(int[] keyCodes) { 622b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright return deviceHasKeys(-1, keyCodes); 623b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright } 624b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright 625b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright /** 626b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * Queries the framework about whether any physical keys exist on the 627b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * any keyboard attached to the device that are capable of producing the given 628b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * array of key codes. 629b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * 630b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @param id The id of the device to query. 631b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @param keyCodes The array of key codes to query. 632b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @return A new array of the same size as the key codes array whose elements are set to true 633b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * if the given device could produce the corresponding key code at the same index in the key 634b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * codes array. 635b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * 636b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @hide 637b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright */ 638b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright public boolean[] deviceHasKeys(int id, int[] keyCodes) { 639ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown boolean[] ret = new boolean[keyCodes.length]; 640ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 641b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret); 642ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException e) { 643ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown // no fallback; just return the empty array 644ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 645ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return ret; 646ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 647ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 648b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright 649ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 650ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Injects an input event into the event system on behalf of an application. 651ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * The synchronization mode determines whether the method blocks while waiting for 652ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input injection to proceed. 653ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 654ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into 655ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * windows that are owned by other applications. 656ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p><p> 657ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Make sure you correctly set the event time and input source of the event 658ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * before calling this method. 659ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 660ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 661ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param event The event to inject. 662ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param mode The synchronization mode. One of: 663ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_ASYNC}, 664ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or 665ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}. 666ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return True if input event injection succeeded. 667ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 668ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 669ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 6709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean injectInputEvent(InputEvent event, int mode) { 671ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (event == null) { 672ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("event must not be null"); 673ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 674ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mode != INJECT_INPUT_EVENT_MODE_ASYNC 675ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH 676ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) { 677ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("mode is invalid"); 678ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 679ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 680ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 6819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.injectInputEvent(event, mode); 682ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 683ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 684ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 685ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 686af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 687af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void populateInputDevicesLocked() { 688af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevicesChangedListener == null) { 689af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevicesChangedListener listener = new InputDevicesChangedListener(); 690af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 691af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mIm.registerInputDevicesChangedListener(listener); 692af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 693af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException( 694af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown "Could not get register input device changed listener", ex); 695af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 696af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListener = listener; 697af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 698af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 699af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevices == null) { 700af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids; 701af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 702af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids = mIm.getInputDeviceIds(); 703af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 704af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException("Could not get input device ids.", ex); 705af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 706af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 707af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices = new SparseArray<InputDevice>(); 708af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < ids.length; i++) { 709af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(ids[i], null); 710af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 711af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 712af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 713af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 714af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void onInputDevicesChanged(int[] deviceIdAndGeneration) { 715af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 716af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Received input devices changed."); 717af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 718af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 719af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 720af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = mInputDevices.size(); --i > 0; ) { 721af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = mInputDevices.keyAt(i); 722af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!containsDeviceId(deviceIdAndGeneration, deviceId)) { 723af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 724af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device removed: " + deviceId); 725af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 726af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.removeAt(i); 727af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId); 728af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 729af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 730af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 731af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 732af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = deviceIdAndGeneration[i]; 733af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(deviceId); 734af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 735af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice device = mInputDevices.valueAt(index); 736af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device != null) { 737af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int generation = deviceIdAndGeneration[i + 1]; 738af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device.getGeneration() != generation) { 739af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 740af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device changed: " + deviceId); 741af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 742af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.setValueAt(index, null); 743af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId); 744af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 745af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 746af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } else { 747af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 748af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device added: " + deviceId); 749af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 750af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(deviceId, null); 751af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId); 752af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 753af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 754af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 755af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 756af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 757af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) { 758af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 759af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 760af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i); 761af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown listener.sendMessage(listener.obtainMessage(what, deviceId, 0)); 762af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 763af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 764af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 765af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) { 766af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 767af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (deviceIdAndGeneration[i] == deviceId) { 768af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return true; 769af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 770af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 771af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return false; 772af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 773af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 774af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 775a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * Gets a vibrator service associated with an input device, assuming it has one. 776a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @return The vibrator, never null. 777a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @hide 778a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown */ 779a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public Vibrator getInputDeviceVibrator(int deviceId) { 780a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return new InputDeviceVibrator(deviceId); 781a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 782a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 783a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown /** 784af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Listens for changes in input devices. 785af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 786af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public interface InputDeviceListener { 787af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 788af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been added to the system. 789af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Use {@link InputManager#getInputDevice} to get more information about the device. 790af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 791af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was added. 792af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 793af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceAdded(int deviceId); 794af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 795af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 796af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been removed from the system. 797af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 798af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was removed. 799af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 800af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceRemoved(int deviceId); 801af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 802af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 803af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever the properties of an input device have changed since they 804af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * were last queried. Use {@link InputManager#getInputDevice} to get 805af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * a fresh {@link InputDevice} object with the new properties. 806af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 807af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that changed. 808af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 809af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceChanged(int deviceId); 810af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 811af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 812af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub { 813af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 814af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException { 815af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputManager.this.onInputDevicesChanged(deviceIdAndGeneration); 816af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 817af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 818af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 819af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final class InputDeviceListenerDelegate extends Handler { 820af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public final InputDeviceListener mListener; 821af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 822af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) { 823af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown super(handler != null ? handler.getLooper() : Looper.myLooper()); 824af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener = listener; 825af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 826af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 827af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 828af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void handleMessage(Message msg) { 829af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown switch (msg.what) { 830af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_ADDED: 831af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceAdded(msg.arg1); 832af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 833af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_REMOVED: 834af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceRemoved(msg.arg1); 835af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 836af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_CHANGED: 837af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceChanged(msg.arg1); 838af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 839af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 840af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 841af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 842a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 843a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final class InputDeviceVibrator extends Vibrator { 844a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final int mDeviceId; 845a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final Binder mToken; 846a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 847a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public InputDeviceVibrator(int deviceId) { 848a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mDeviceId = deviceId; 849a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mToken = new Binder(); 850a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 851a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 852a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 853a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public boolean hasVibrator() { 854a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return true; 855a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 856a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 8571af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock /** 8581af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock * @hide 8591af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock */ 860a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 8617b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) { 862a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown vibrate(new long[] { 0, milliseconds}, -1); 863a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 864a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 8651af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock /** 8661af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock * @hide 8671af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock */ 868a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 8698fd7f1ed7c11d35b3f2a97878e68ee38a551dd15Christoph Studer public void vibrate(int uid, String opPkg, long[] pattern, int repeat, 8707b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock AudioAttributes attributes) { 871a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (repeat >= pattern.length) { 872a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new ArrayIndexOutOfBoundsException(); 873a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 874a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 875a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.vibrate(mDeviceId, pattern, repeat, mToken); 876a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 877a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to vibrate.", ex); 878a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 879a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 880a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 881a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 882a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void cancel() { 883a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 884a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.cancelVibrate(mDeviceId, mToken); 885a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 886a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Log.w(TAG, "Failed to cancel vibration.", ex); 887a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 888a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 889a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 8909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown} 891