InputManager.java revision c53962d4ede82a03b62f0c8bb86bd0da090a15eb
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 19d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport com.android.internal.inputmethod.InputMethodSubtypeHandle; 2039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport com.android.internal.os.SomeArgs; 21cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport com.android.internal.util.ArrayUtils; 22cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 239209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wrightimport android.annotation.IntDef; 249df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant; 259df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.annotation.SdkConstant.SdkConstantType; 269df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.content.Context; 277b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlockimport android.media.AudioAttributes; 28a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Binder; 29af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Handler; 30ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.IBinder; 31af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Looper; 32af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Message; 33ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.RemoteException; 34ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.ServiceManager; 3539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport android.os.SystemClock; 36a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brownimport android.os.Vibrator; 37ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings; 38ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.provider.Settings.SettingNotFoundException; 399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownimport android.util.Log; 409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.util.SparseArray; 41ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputDevice; 42ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.view.InputEvent; 43d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport android.view.PointerIcon; 44d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport android.view.inputmethod.InputMethodInfo; 45d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport android.view.inputmethod.InputMethodSubtype; 469df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 479209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wrightimport java.lang.annotation.Retention; 489209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wrightimport java.lang.annotation.RetentionPolicy; 49af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport java.util.ArrayList; 5039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport java.util.List; 51af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 529df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown/** 539df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Provides information about input devices and available key layouts. 549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 559df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Get an instance of this class by calling 569df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#getSystemService(java.lang.String) 579df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Context.getSystemService()} with the argument 589df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link android.content.Context#INPUT_SERVICE}. 599df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 619df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brownpublic final class InputManager { 629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown private static final String TAG = "InputManager"; 63af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final boolean DEBUG = false; 64af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 65af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_ADDED = 1; 66af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_REMOVED = 2; 67af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DEVICE_CHANGED = 3; 689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 699f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private static InputManager sInstance; 709df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private final IInputManager mIm; 72af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 73af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // Guarded by mInputDevicesLock 74af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final Object mInputDevicesLock = new Object(); 75af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private SparseArray<InputDevice> mInputDevices; 76af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private InputDevicesChangedListener mInputDevicesChangedListener; 77af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final ArrayList<InputDeviceListenerDelegate> mInputDeviceListeners = 78af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new ArrayList<InputDeviceListenerDelegate>(); 799df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 8039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright // Guarded by mTabletModeLock 8139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final Object mTabletModeLock = new Object(); 8239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private TabletModeChangedListener mTabletModeChangedListener; 8339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private List<OnTabletModeChangedListenerDelegate> mOnTabletModeChangedListeners; 8439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 859df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 869df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Broadcast Action: Query available keyboard layouts. 879df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 889df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager service locates available keyboard layouts 899df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by querying broadcast receivers that are registered for this action. 909df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * An application can offer additional keyboard layouts to the user 919df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * by declaring a suitable broadcast receiver in its manifest. 929df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 939df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Here is an example broadcast receiver declaration that an application 949df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * might include in its AndroidManifest.xml to advertise keyboard layouts. 959df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The meta-data specifies a resource that contains a description of each keyboard 969df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layout that is provided by the application. 979df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <pre><code> 98d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * <receiver android:name=".InputDeviceReceiver" 99d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * android:label="@string/keyboard_layouts_label"> 1009df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <intent-filter> 1019df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <action android:name="android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS" /> 1029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </intent-filter> 1039df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS" 1049df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:resource="@xml/keyboard_layouts" /> 1059df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </receiver> 1069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </code></pre> 1079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 1089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * In the above example, the <code>@xml/keyboard_layouts</code> resource refers to 1099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * an XML resource whose root element is <code><keyboard-layouts></code> that 1109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * contains zero or more <code><keyboard-layout></code> elements. 1119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Each <code><keyboard-layout></code> element specifies the name, label, and location 112d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * of a key character map for a particular keyboard layout. The label on the receiver 113d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * is used to name the collection of keyboard layouts provided by this receiver in the 114d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown * keyboard layout settings. 115112449ca2983898b14e5e4dfe5d9d50b66f803a5Michael Wright * <pre><code> 1169df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <?xml version="1.0" encoding="utf-8"?> 1179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layouts xmlns:android="http://schemas.android.com/apk/res/android"> 1189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <keyboard-layout android:name="keyboard_layout_english_us" 1199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * android:label="@string/keyboard_layout_english_us_label" 1202f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * android:keyboardLayout="@raw/keyboard_layout_english_us" /> 1219df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </keyboard-layouts> 122112449ca2983898b14e5e4dfe5d9d50b66f803a5Michael Wright * </pre></code> 1239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p><p> 1249df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:name</code> attribute specifies an identifier by which 1259df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * the keyboard layout will be known in the package. 1269df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The <code>android:label</code> attributes specifies a human-readable descriptive 1279df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * label to describe the keyboard layout in the user interface, such as "English (US)". 1282f0957607411b99810226ad38d59cf18718b86d0Jeff Brown * The <code>android:keyboardLayout</code> attribute refers to a 1299df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <a href="http://source.android.com/tech/input/key-character-map-files.html"> 1309df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * key character map</a> resource that defines the keyboard layout. 1319df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1329df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1339df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 1349df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String ACTION_QUERY_KEYBOARD_LAYOUTS = 1359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS"; 1369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 1379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 1389df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Metadata Key: Keyboard layout metadata associated with 1399df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS}. 1409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 1419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Specifies the resource id of a XML resource that describes the keyboard 1429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * layouts that are provided by the application. 1439df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 1449df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 1459df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public static final String META_DATA_KEYBOARD_LAYOUTS = 1469df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; 1479df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 148ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 149ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The minimum (slowest) pointer speed (-7). 150ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 151ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 152ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MIN_POINTER_SPEED = -7; 153ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 154ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 155ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The maximum (fastest) pointer speed (7). 156ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 157ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 158ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int MAX_POINTER_SPEED = 7; 159ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 160ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 161ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Pointer Speed: The default pointer speed (0). 162ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 163ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 164ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int DEFAULT_POINTER_SPEED = 0; 165ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 166ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 167ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: None. 168ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Never blocks. Injection is asynchronous and is assumed always to be successful. 169ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 170ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 171ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h 172ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 173ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 174ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for result. 175ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for previous events to be dispatched so that the input dispatcher can 176ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * determine whether input event injection will be permitted based on the current 177ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input focus. Does not wait for the input event to finish being handled 178ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * by the application. 179ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 180ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 181ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1; // see InputDispatcher.h 182ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 183ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 184ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Input Event Injection Synchronization Mode: Wait for finish. 185ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Waits for the event to be delivered to the application and handled. 186ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 187ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 188ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h 189ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1909209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright /** @hide */ 1919209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright @Retention(RetentionPolicy.SOURCE) 1929209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright @IntDef({SWITCH_STATE_UNKNOWN, SWITCH_STATE_OFF, SWITCH_STATE_ON}) 1939209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public @interface SwitchState {} 1949209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 1959209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright /** 1969209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * Switch State: Unknown. 1979209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * 1989209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * The system has yet to report a valid value for the switch. 1999209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * @hide 2009209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright */ 2019209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public static final int SWITCH_STATE_UNKNOWN = -1; 2029209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 2039209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright /** 2049209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * Switch State: Off. 2059209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * @hide 2069209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright */ 2079209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public static final int SWITCH_STATE_OFF = 0; 2089209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 2099209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright /** 2109209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * Switch State: On. 2119209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * @hide 2129209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright */ 2139209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public static final int SWITCH_STATE_ON = 1; 2149209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 2159f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private InputManager(IInputManager im) { 2169f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm = im; 217ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 218ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 2199f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown /** 2209f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Gets an instance of the input manager. 2219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 2229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @return The input manager instance. 2239f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 2249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @hide 2259f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown */ 2269f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public static InputManager getInstance() { 2279f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown synchronized (InputManager.class) { 2289f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (sInstance == null) { 2299f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown IBinder b = ServiceManager.getService(Context.INPUT_SERVICE); 2309f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown sInstance = new InputManager(IInputManager.Stub.asInterface(b)); 2319f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 2329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return sInstance; 2339f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 2349df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 2359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 2369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 237af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets information about the input device with the specified id. 238af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param id The device id. 239af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device or null if not found. 240af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 241af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDevice getInputDevice(int id) { 242af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 243af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 244af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 245af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(id); 246af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 247af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return null; 248af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 249af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 250af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDevice inputDevice = mInputDevices.valueAt(index); 251af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (inputDevice == null) { 252af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 253af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown inputDevice = mIm.getInputDevice(id); 254af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 255c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 256af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2578f124842dd16125062f048257889c85380879b68Jeff Brown if (inputDevice != null) { 2588f124842dd16125062f048257889c85380879b68Jeff Brown mInputDevices.setValueAt(index, inputDevice); 2598f124842dd16125062f048257889c85380879b68Jeff Brown } 260af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 261af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return inputDevice; 262af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 263af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 264af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 265af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 266cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Gets information about the input device with the specified descriptor. 267cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @param descriptor The input device descriptor. 268cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @return The input device or null if not found. 269cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 270cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 271cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown public InputDevice getInputDeviceByDescriptor(String descriptor) { 272cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (descriptor == null) { 273cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("descriptor must not be null."); 274cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 275cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 276cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mInputDevicesLock) { 277cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown populateInputDevicesLocked(); 278cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 279cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown int numDevices = mInputDevices.size(); 280cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown for (int i = 0; i < numDevices; i++) { 281cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown InputDevice inputDevice = mInputDevices.valueAt(i); 282cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (inputDevice == null) { 283cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown int id = mInputDevices.keyAt(i); 284cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 285cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown inputDevice = mIm.getInputDevice(id); 286cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 287c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 2888f124842dd16125062f048257889c85380879b68Jeff Brown } 2898f124842dd16125062f048257889c85380879b68Jeff Brown if (inputDevice == null) { 290cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown continue; 291cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 292cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mInputDevices.setValueAt(i, inputDevice); 293cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 294cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (descriptor.equals(inputDevice.getDescriptor())) { 295cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return inputDevice; 296cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 297cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 298cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return null; 299cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 300cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 301cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 302cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 303af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Gets the ids of all input devices in the system. 304af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @return The input device ids. 305af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 306af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public int[] getInputDeviceIds() { 307af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 308af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown populateInputDevicesLocked(); 309af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 310af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int count = mInputDevices.size(); 311af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids = new int[count]; 312af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < count; i++) { 313af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids[i] = mInputDevices.keyAt(i); 314af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 315af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return ids; 316af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 317af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 318af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 319af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 320af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Registers an input device listener to receive notifications about when 321af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * input devices are added, removed or changed. 322af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 323af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to register. 324af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param handler The handler on which the listener should be invoked, or null 325af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * if the listener should be invoked on the calling thread's looper. 326af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 327af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #unregisterInputDeviceListener 328af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 329af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void registerInputDeviceListener(InputDeviceListener listener, Handler handler) { 330af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 331af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 332af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 333af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 334af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 3359ddb864babab156428d5a001e9b14b1541d964edTim Kilbourn populateInputDevicesLocked(); 336af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 337af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index < 0) { 338af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.add(new InputDeviceListenerDelegate(listener, handler)); 339af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 340af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 341af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 342af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 343af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 344af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Unregisters an input device listener. 345af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 346af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param listener The listener to unregister. 347af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 348af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @see #registerInputDeviceListener 349af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 350af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void unregisterInputDeviceListener(InputDeviceListener listener) { 351af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 352af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 353af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 354af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 355af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 356af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = findInputDeviceListenerLocked(listener); 357af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 3589e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown InputDeviceListenerDelegate d = mInputDeviceListeners.get(index); 3599e6d4b035d4f012d23264d3d2bc946b1ca02dba1Jeff Brown d.removeCallbacksAndMessages(null); 360af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDeviceListeners.remove(index); 361af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 362af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 363af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 364af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 365af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private int findInputDeviceListenerLocked(InputDeviceListener listener) { 366af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 367af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 368af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDeviceListeners.get(i).mListener == listener) { 369af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return i; 370af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 371af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 372af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return -1; 373af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 374af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 375af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 3769209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * Queries whether the device is in tablet mode. 3779209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * 3789209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * @return The tablet switch state which is one of {@link #SWITCH_STATE_UNKNOWN}, 3799209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * {@link #SWITCH_STATE_OFF} or {@link #SWITCH_STATE_ON}. 3809209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright * @hide 3819209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright */ 3829209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright @SwitchState 3839209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public int isInTabletMode() { 3849209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright try { 3859209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright return mIm.isInTabletMode(); 3869209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright } catch (RemoteException ex) { 387c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 3889209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright } 3899209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright } 3909209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 3919209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright /** 39239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * Register a tablet mode changed listener. 39339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * 39439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @param listener The listener to register. 39539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @param handler The handler on which the listener should be invoked, or null 39639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * if the listener should be invoked on the calling thread's looper. 39739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @hide 39839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright */ 39939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void registerOnTabletModeChangedListener( 40039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright OnTabletModeChangedListener listener, Handler handler) { 40139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (listener == null) { 40239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new IllegalArgumentException("listener must not be null"); 40339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 40439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 40539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (mOnTabletModeChangedListeners == null) { 40639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright initializeTabletModeListenerLocked(); 40739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 40839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright int idx = findOnTabletModeChangedListenerLocked(listener); 40939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (idx < 0) { 41039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright OnTabletModeChangedListenerDelegate d = 41139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright new OnTabletModeChangedListenerDelegate(listener, handler); 41239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mOnTabletModeChangedListeners.add(d); 41339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 41439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 41539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 41639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 41739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright /** 41839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * Unregister a tablet mode changed listener. 41939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * 42039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @param listener The listener to unregister. 42139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @hide 42239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright */ 42339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void unregisterOnTabletModeChangedListener(OnTabletModeChangedListener listener) { 42439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (listener == null) { 42539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new IllegalArgumentException("listener must not be null"); 42639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 42739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 42839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright int idx = findOnTabletModeChangedListenerLocked(listener); 42939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (idx >= 0) { 43039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright OnTabletModeChangedListenerDelegate d = mOnTabletModeChangedListeners.remove(idx); 43139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright d.removeCallbacksAndMessages(null); 43239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 43339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 43439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 43539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 43639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private void initializeTabletModeListenerLocked() { 43739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright final TabletModeChangedListener listener = new TabletModeChangedListener(); 43839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright try { 43939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mIm.registerTabletModeChangedListener(listener); 44039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } catch (RemoteException ex) { 441c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 44239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 44339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTabletModeChangedListener = listener; 44439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mOnTabletModeChangedListeners = new ArrayList<>(); 44539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 44639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 44739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private int findOnTabletModeChangedListenerLocked(OnTabletModeChangedListener listener) { 44839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright final int N = mOnTabletModeChangedListeners.size(); 44939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright for (int i = 0; i < N; i++) { 45039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (mOnTabletModeChangedListeners.get(i).mListener == listener) { 45139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright return i; 45239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 45339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 45439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright return -1; 45539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 45639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 45739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright /** 4589df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets information about all supported keyboard layouts. 4599df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 4609df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * The input manager consults the built-in keyboard layouts as well 4619df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * as all keyboard layouts advertised by applications using a 4629df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver. 4639df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 4649df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 4659df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return A list of all supported keyboard layouts. 4669f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 4679df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 4689df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 4699f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout[] getKeyboardLayouts() { 4709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 4719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayouts(); 4729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 473c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 4749df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 4759df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 4769df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 4779df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 4780748342d2ed264c01384fbaa4446a702a8824813Michael Wright * Gets information about all supported keyboard layouts appropriate 4790748342d2ed264c01384fbaa4446a702a8824813Michael Wright * for a specific input device. 4800748342d2ed264c01384fbaa4446a702a8824813Michael Wright * <p> 4810748342d2ed264c01384fbaa4446a702a8824813Michael Wright * The input manager consults the built-in keyboard layouts as well 4820748342d2ed264c01384fbaa4446a702a8824813Michael Wright * as all keyboard layouts advertised by applications using a 4830748342d2ed264c01384fbaa4446a702a8824813Michael Wright * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver. 4840748342d2ed264c01384fbaa4446a702a8824813Michael Wright * </p> 4850748342d2ed264c01384fbaa4446a702a8824813Michael Wright * 4860748342d2ed264c01384fbaa4446a702a8824813Michael Wright * @return A list of all supported keyboard layouts for a specific 4870748342d2ed264c01384fbaa4446a702a8824813Michael Wright * input device. 4880748342d2ed264c01384fbaa4446a702a8824813Michael Wright * 4890748342d2ed264c01384fbaa4446a702a8824813Michael Wright * @hide 4900748342d2ed264c01384fbaa4446a702a8824813Michael Wright */ 4910748342d2ed264c01384fbaa4446a702a8824813Michael Wright public KeyboardLayout[] getKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { 4920748342d2ed264c01384fbaa4446a702a8824813Michael Wright try { 4930748342d2ed264c01384fbaa4446a702a8824813Michael Wright return mIm.getKeyboardLayoutsForInputDevice(identifier); 4940748342d2ed264c01384fbaa4446a702a8824813Michael Wright } catch (RemoteException ex) { 495c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 4960748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 4970748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 4980748342d2ed264c01384fbaa4446a702a8824813Michael Wright 4990748342d2ed264c01384fbaa4446a702a8824813Michael Wright /** 5009df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * Gets the keyboard layout with the specified descriptor. 5019df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 5029df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @param keyboardLayoutDescriptor The keyboard layout descriptor, as returned by 5039df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * {@link KeyboardLayout#getDescriptor()}. 5049df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @return The keyboard layout, or null if it could not be loaded. 5059df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 5069df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 5079df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 5089df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 5099df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown if (keyboardLayoutDescriptor == null) { 5109df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 5119df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5129df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 5139df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 5149f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.getKeyboardLayout(keyboardLayoutDescriptor); 5159f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 516c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 5179df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5189df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5199df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 5209df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 521fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Gets the current keyboard layout descriptor for the specified input 522fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * device. 5239df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 524fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier Identifier for the input device 525fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @return The keyboard layout descriptor, or null if no keyboard layout has 526fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * been set. 5279df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 5289df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 529fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) { 5309f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 531fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return mIm.getCurrentKeyboardLayoutForInputDevice(identifier); 5329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 533c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 5349f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 5359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 5369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 5379df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown /** 538fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Sets the current keyboard layout descriptor for the specified input 539fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * device. 5409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * <p> 541fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 542fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 5439df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * </p> 5449df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * 545fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 546fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The keyboard layout descriptor to use, 547fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * must not be null. 5489df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown * @hide 5499df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown */ 550fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 5519df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown String keyboardLayoutDescriptor) { 552fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 553fb290df3c9a6f37ec050163029e25844de2f8590RoboErik throw new IllegalArgumentException("identifier must not be null"); 5549df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 555cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 556cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 557cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 558cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 559cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 560fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.setCurrentKeyboardLayoutForInputDevice(identifier, 561cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown keyboardLayoutDescriptor); 562cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 563c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 564cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 565cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 566cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 567cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 568fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Gets all keyboard layout descriptors that are enabled for the specified 569fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * input device. 570cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 571fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 572cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @return The keyboard layout descriptors. 573cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 574cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 5750748342d2ed264c01384fbaa4446a702a8824813Michael Wright public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { 576fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 577cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 578cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 579cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 580cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 5810748342d2ed264c01384fbaa4446a702a8824813Michael Wright return mIm.getEnabledKeyboardLayoutsForInputDevice(identifier); 582cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 583c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 584cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 585cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 586cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 587cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 588cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Adds the keyboard layout descriptor for the specified input device. 589cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * <p> 590fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 591fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 592cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * </p> 593cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 594fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 595fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to 596fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * add. 597cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 598cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 599fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 600cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 601fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 602cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 603cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 604cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 605cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 606cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 607cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 608cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 609fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.addKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor); 610cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } catch (RemoteException ex) { 611c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 612cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 613cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 614cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 615cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown /** 616cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * Removes the keyboard layout descriptor for the specified input device. 617cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * <p> 618fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * This method may have the side-effect of causing the input device in 619fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * question to be reconfigured. 620cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * </p> 621cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * 622fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param identifier The identifier for the input device. 623fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to 624fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * remove. 625cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown * @hide 626cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown */ 627fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 628cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 629fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null) { 630cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 631cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 632cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 633cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 634cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 6359df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 6369df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown try { 637fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mIm.removeKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor); 6389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (RemoteException ex) { 639c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 6409df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 6419df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown } 6429df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown 643d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 644d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright /** 645d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * Gets the keyboard layout for the specified input device and IME subtype. 646d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * 647d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param identifier The identifier for the input device. 648d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param inputMethodInfo The input method. 649d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param inputMethodSubtype The input method subtype. 650d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * 651d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @return The associated {@link KeyboardLayout}, or null if one has not been set. 652d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * 653d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @hide 654d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright */ 655d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public KeyboardLayout getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 656d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodInfo inputMethodInfo, InputMethodSubtype inputMethodSubtype) { 657d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright try { 658d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return mIm.getKeyboardLayoutForInputDevice( 659d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright identifier, inputMethodInfo, inputMethodSubtype); 660d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } catch (RemoteException ex) { 661c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 662d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 663d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 664d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 665d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright /** 666d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * Sets the keyboard layout for the specified input device and IME subtype pair. 667d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * 668d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param identifier The identifier for the input device. 669d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param inputMethodInfo The input method with which to associate the keyboard layout. 670d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param inputMethodSubtype The input method subtype which which to associate the keyboard 671d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * layout. 672d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to set 673d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * 674d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright * @hide 675d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright */ 676d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 677d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodInfo inputMethodInfo, InputMethodSubtype inputMethodSubtype, 678d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String keyboardLayoutDescriptor) { 679d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright try { 680d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mIm.setKeyboardLayoutForInputDevice(identifier, inputMethodInfo, 681d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright inputMethodSubtype, keyboardLayoutDescriptor); 682d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } catch (RemoteException ex) { 683c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 684d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 685d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 686d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 687ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 688d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * Gets the TouchCalibration applied to the specified input device's coordinates. 689d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 690d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param inputDeviceDescriptor The input device descriptor. 691d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @return The TouchCalibration currently assigned for use with the given 692d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * input device. If none is set, an identity TouchCalibration is returned. 693d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 694d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @hide 695d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke */ 696d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) { 697d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke try { 698d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation); 699d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } catch (RemoteException ex) { 700c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 701d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 702d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 703d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 704d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke /** 705d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * Sets the TouchCalibration to apply to the specified input device's coordinates. 706d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * <p> 707d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * This method may have the side-effect of causing the input device in question 708d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * to be reconfigured. Requires {@link android.Manifest.permissions.SET_INPUT_CALIBRATION}. 709d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * </p> 710d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 711d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param inputDeviceDescriptor The input device descriptor. 712d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @param calibration The calibration to be applied 713d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * 714d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke * @hide 715d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke */ 716d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, 717d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke TouchCalibration calibration) { 718d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke try { 719d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration); 720d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } catch (RemoteException ex) { 721c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 722d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 723d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 724d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 725d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke /** 726ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Gets the mouse pointer speed. 727ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 728ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Only returns the permanent mouse pointer speed. Ignores any temporary pointer 729ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * speed set by {@link #tryPointerSpeed}. 730ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 731ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 7329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 733ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 734ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 735ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 736ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 737ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 7389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public int getPointerSpeed(Context context) { 739ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = DEFAULT_POINTER_SPEED; 740ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 7419f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown speed = Settings.System.getInt(context.getContentResolver(), 742ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED); 743ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (SettingNotFoundException snfe) { 744ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 745ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return speed; 746ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 747ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 748ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 749ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Sets the mouse pointer speed. 750ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 751ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}. 752ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 753ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 7549f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * @param context The application context. 755ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 756ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 757ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 758ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 759ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 7609f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public void setPointerSpeed(Context context, int speed) { 761ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 762ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 763ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 764ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 7659f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Settings.System.putInt(context.getContentResolver(), 766ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Settings.System.POINTER_SPEED, speed); 767ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 768ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 769ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 770ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Changes the mouse pointer speed temporarily, but does not save the setting. 771ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 772ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}. 773ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 774ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 775ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and 776ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}. 777ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 778ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 779ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 780ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public void tryPointerSpeed(int speed) { 781ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) { 782ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("speed out of range"); 783ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 784ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 785ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 7869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mIm.tryPointerSpeed(speed); 787ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 788c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 789ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 790ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 791ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 792ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 793ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Queries the framework about whether any physical keys exist on the 794ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * any keyboard attached to the device that are capable of producing the given 795ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * array of key codes. 796ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 797ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param keyCodes The array of key codes to query. 798ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return A new array of the same size as the key codes array whose elements 799ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * are set to true if at least one attached keyboard supports the corresponding key code 800ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * at the same index in the key codes array. 801ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 802ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 803ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 8049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean[] deviceHasKeys(int[] keyCodes) { 805b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright return deviceHasKeys(-1, keyCodes); 806b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright } 807b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright 808b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright /** 809b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * Queries the framework about whether any physical keys exist on the 810b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * any keyboard attached to the device that are capable of producing the given 811b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * array of key codes. 812b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * 813b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @param id The id of the device to query. 814b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @param keyCodes The array of key codes to query. 815b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @return A new array of the same size as the key codes array whose elements are set to true 816b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * if the given device could produce the corresponding key code at the same index in the key 817b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * codes array. 818b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * 819b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright * @hide 820b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright */ 821b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright public boolean[] deviceHasKeys(int id, int[] keyCodes) { 822ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown boolean[] ret = new boolean[keyCodes.length]; 823ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 824b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright mIm.hasKeys(id, InputDevice.SOURCE_ANY, keyCodes, ret); 825ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException e) { 826c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 827ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 828ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return ret; 829ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 830ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 831b7b2d4b490f5dd672e0b00ced579dc052e3637e9Michael Wright 832ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown /** 833ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Injects an input event into the event system on behalf of an application. 834ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * The synchronization mode determines whether the method blocks while waiting for 835ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * input injection to proceed. 836ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * <p> 837ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into 838ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * windows that are owned by other applications. 839ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p><p> 840ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * Make sure you correctly set the event time and input source of the event 841ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * before calling this method. 842ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * </p> 843ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 844ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param event The event to inject. 845ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @param mode The synchronization mode. One of: 846ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_ASYNC}, 847ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or 848ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}. 849ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @return True if input event injection succeeded. 850ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * 851ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown * @hide 852ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown */ 8539f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public boolean injectInputEvent(InputEvent event, int mode) { 854ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (event == null) { 855ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("event must not be null"); 856ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 857ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mode != INJECT_INPUT_EVENT_MODE_ASYNC 858ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH 859ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) { 860ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("mode is invalid"); 861ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 862ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 863ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 8649f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return mIm.injectInputEvent(event, mode); 865ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } catch (RemoteException ex) { 866c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 867ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 868ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 869af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 8701db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai /** 8711db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * Changes the mouse pointer's icon shape into the specified id. 8721db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * 8731db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * @param iconId The id of the pointer graphic, as a value between 8741db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * {@link PointerIcon.STYLE_ARROW} and {@link PointerIcon.STYLE_GRABBING}. 8751db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * 8761db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai * @hide 8771db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai */ 8781db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai public void setPointerIconShape(int iconId) { 8791db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai try { 8801db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai mIm.setPointerIconShape(iconId); 8811db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai } catch (RemoteException ex) { 882c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 8831db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai } 8841db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai } 8851db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 886d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai /** @hide */ 887d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai public void setCustomPointerIcon(PointerIcon icon) { 888d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai try { 889d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai mIm.setCustomPointerIcon(icon); 890d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai } catch (RemoteException ex) { 891c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 892d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai } 893d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai } 894d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai 895347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai /** 896347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * Update the pointer icon status. When detached, the pointer icon disappears, and further 897347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * mouse location will be stuck at the current point. Mouse movement events will still arrive, 898347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * and movement should be handled through {@link MotionEvent.AXIS_RELATIVE_X} and 899347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * {@link MotionEvent.AXIS_RELATIVE_Y}. 900347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * 901347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * @param detached true if the icon will be detached from the actual mouse movement. 902347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * 903347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai * @hide 904347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai */ 905347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai public void setPointerIconDetached(boolean detached) { 906347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai try { 907347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai mIm.setPointerIconDetached(detached); 908347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai } catch (RemoteException ex) { 909c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 910347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai } 911347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai } 912347e5d498f4c216d588e98776a386d8bdf93d05cJun Mukai 913af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void populateInputDevicesLocked() { 914af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevicesChangedListener == null) { 915af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevicesChangedListener listener = new InputDevicesChangedListener(); 916af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 917af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mIm.registerInputDevicesChangedListener(listener); 918af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 919c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 920af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 921af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListener = listener; 922af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 923af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 924af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevices == null) { 925af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] ids; 926af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 927af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids = mIm.getInputDeviceIds(); 928af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 929c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 930af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 931af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 932af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices = new SparseArray<InputDevice>(); 933af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < ids.length; i++) { 934af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(ids[i], null); 935af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 936af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 937af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 938af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 939af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void onInputDevicesChanged(int[] deviceIdAndGeneration) { 940af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 941af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Received input devices changed."); 942af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 943af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 944af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 945af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = mInputDevices.size(); --i > 0; ) { 946af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = mInputDevices.keyAt(i); 947af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!containsDeviceId(deviceIdAndGeneration, deviceId)) { 948af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 949af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device removed: " + deviceId); 950af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 951af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.removeAt(i); 952af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_REMOVED, deviceId); 953af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 954af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 955af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 956af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 957af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int deviceId = deviceIdAndGeneration[i]; 958af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int index = mInputDevices.indexOfKey(deviceId); 959af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (index >= 0) { 960af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice device = mInputDevices.valueAt(index); 961af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device != null) { 962af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int generation = deviceIdAndGeneration[i + 1]; 963af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (device.getGeneration() != generation) { 964af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 965af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device changed: " + deviceId); 966af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 967af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.setValueAt(index, null); 968af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_CHANGED, deviceId); 969af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 970af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 971af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } else { 972af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 973af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Log.d(TAG, "Device added: " + deviceId); 974af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 975af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevices.put(deviceId, null); 976af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown sendMessageToInputDeviceListenersLocked(MSG_DEVICE_ADDED, deviceId); 977af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 978af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 979af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 980af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 981af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 982af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void sendMessageToInputDeviceListenersLocked(int what, int deviceId) { 983af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners = mInputDeviceListeners.size(); 984af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 985af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDeviceListenerDelegate listener = mInputDeviceListeners.get(i); 986af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown listener.sendMessage(listener.obtainMessage(what, deviceId, 0)); 987af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 988af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 989af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 990af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static boolean containsDeviceId(int[] deviceIdAndGeneration, int deviceId) { 991af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < deviceIdAndGeneration.length; i += 2) { 992af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (deviceIdAndGeneration[i] == deviceId) { 993af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return true; 994af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 995af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 996af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return false; 997af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 998af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 99939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 100039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private void onTabletModeChanged(long whenNanos, boolean inTabletMode) { 100139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (DEBUG) { 100239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright Log.d(TAG, "Received tablet mode changed: " 100339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright + "whenNanos=" + whenNanos + ", inTabletMode=" + inTabletMode); 100439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 100539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 100639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright final int N = mOnTabletModeChangedListeners.size(); 100739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright for (int i = 0; i < N; i++) { 100839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright OnTabletModeChangedListenerDelegate listener = 100939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mOnTabletModeChangedListeners.get(i); 101039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright listener.sendTabletModeChanged(whenNanos, inTabletMode); 101139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 101239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 101339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 101439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 1015af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 1016a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * Gets a vibrator service associated with an input device, assuming it has one. 1017a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @return The vibrator, never null. 1018a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown * @hide 1019a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown */ 1020a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public Vibrator getInputDeviceVibrator(int deviceId) { 1021a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return new InputDeviceVibrator(deviceId); 1022a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1023a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1024a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown /** 1025af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Listens for changes in input devices. 1026af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 1027af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public interface InputDeviceListener { 1028af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 1029af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been added to the system. 1030af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Use {@link InputManager#getInputDevice} to get more information about the device. 1031af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 1032af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was added. 1033af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 1034af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceAdded(int deviceId); 1035af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1036af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 1037af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever an input device has been removed from the system. 1038af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 1039af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that was removed. 1040af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 1041af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceRemoved(int deviceId); 1042af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1043af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 1044af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Called whenever the properties of an input device have changed since they 1045af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * were last queried. Use {@link InputManager#getInputDevice} to get 1046af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * a fresh {@link InputDevice} object with the new properties. 1047af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * 1048af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * @param deviceId The id of the input device that changed. 1049af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 1050af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown void onInputDeviceChanged(int deviceId); 1051af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1052af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1053af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputDevicesChangedListener extends IInputDevicesChangedListener.Stub { 1054af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 1055af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void onInputDevicesChanged(int[] deviceIdAndGeneration) throws RemoteException { 1056af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputManager.this.onInputDevicesChanged(deviceIdAndGeneration); 1057af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1058af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1059af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1060af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final class InputDeviceListenerDelegate extends Handler { 1061af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public final InputDeviceListener mListener; 1062af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1063af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDeviceListenerDelegate(InputDeviceListener listener, Handler handler) { 1064af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown super(handler != null ? handler.getLooper() : Looper.myLooper()); 1065af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener = listener; 1066af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1067af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1068af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 1069af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void handleMessage(Message msg) { 1070af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown switch (msg.what) { 1071af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_ADDED: 1072af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceAdded(msg.arg1); 1073af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 1074af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_REMOVED: 1075af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceRemoved(msg.arg1); 1076af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 1077af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DEVICE_CHANGED: 1078af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDeviceChanged(msg.arg1); 1079af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 1080af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1081af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1082af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1083a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 108439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright /** @hide */ 108539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public interface OnTabletModeChangedListener { 108639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright /** 108739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * Called whenever the device goes into or comes out of tablet mode. 108839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * 108939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * @param whenNanos The time at which the device transitioned into or 109039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * out of tablet mode. This is given in nanoseconds in the 109139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * {@link SystemClock#uptimeMillis} time base. 109239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright */ 109339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright void onTabletModeChanged(long whenNanos, boolean inTabletMode); 109439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 109539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 109639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final class TabletModeChangedListener extends ITabletModeChangedListener.Stub { 109739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright @Override 109839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void onTabletModeChanged(long whenNanos, boolean inTabletMode) { 109939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright InputManager.this.onTabletModeChanged(whenNanos, inTabletMode); 110039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 110139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 110239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 110339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private static final class OnTabletModeChangedListenerDelegate extends Handler { 110439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private static final int MSG_TABLET_MODE_CHANGED = 0; 110539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 110639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public final OnTabletModeChangedListener mListener; 110739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 110839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public OnTabletModeChangedListenerDelegate( 110939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright OnTabletModeChangedListener listener, Handler handler) { 111039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright super(handler != null ? handler.getLooper() : Looper.myLooper()); 111139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mListener = listener; 111239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 111339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 111439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void sendTabletModeChanged(long whenNanos, boolean inTabletMode) { 111539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright SomeArgs args = SomeArgs.obtain(); 111639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.argi1 = (int) (whenNanos & 0xFFFFFFFF); 111739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.argi2 = (int) (whenNanos >> 32); 111839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.arg1 = (Boolean) inTabletMode; 111939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright obtainMessage(MSG_TABLET_MODE_CHANGED, args).sendToTarget(); 112039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 112139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 112239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright @Override 112339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void handleMessage(Message msg) { 112439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright switch (msg.what) { 112539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright case MSG_TABLET_MODE_CHANGED: 112639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright SomeArgs args = (SomeArgs) msg.obj; 112739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32); 112839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright boolean inTabletMode = (boolean) args.arg1; 112939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mListener.onTabletModeChanged(whenNanos, inTabletMode); 113039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright break; 113139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 113239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 113339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 113439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 1135a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final class InputDeviceVibrator extends Vibrator { 1136a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final int mDeviceId; 1137a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final Binder mToken; 1138a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1139a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public InputDeviceVibrator(int deviceId) { 1140a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mDeviceId = deviceId; 1141a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mToken = new Binder(); 1142a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1143a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1144a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 1145a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public boolean hasVibrator() { 1146a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return true; 1147a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1148a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 11491af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock /** 11501af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock * @hide 11511af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock */ 1152a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 11537b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock public void vibrate(int uid, String opPkg, long milliseconds, AudioAttributes attributes) { 1154a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown vibrate(new long[] { 0, milliseconds}, -1); 1155a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1156a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 11571af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock /** 11581af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock * @hide 11591af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock */ 1160a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 11618fd7f1ed7c11d35b3f2a97878e68ee38a551dd15Christoph Studer public void vibrate(int uid, String opPkg, long[] pattern, int repeat, 11627b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock AudioAttributes attributes) { 1163a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (repeat >= pattern.length) { 1164a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new ArrayIndexOutOfBoundsException(); 1165a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1166a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 1167a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.vibrate(mDeviceId, pattern, repeat, mToken); 1168a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 1169c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 1170a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1171a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1172a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1173a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 1174a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void cancel() { 1175a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 1176a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mIm.cancelVibrate(mDeviceId, mToken); 1177a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 1178c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw ex.rethrowFromSystemServer(); 1179a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1180a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1181a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 11829df6e7a926ce480baf70e97ee1b9ea387193f6adJeff Brown} 1183