146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/* 246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2010 The Android Open Source Project 346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License. 646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at 746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software 1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and 1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License. 1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */ 1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 174532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownpackage com.android.server.input; 1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 195660fad79808c6d1823a7135b283003b0947773aYohei Yukawaimport android.annotation.NonNull; 20b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawaimport android.annotation.Nullable; 2123cbe85610f780134cc77dd4a54732a22ed6e86eYohei Yukawaimport android.os.LocaleList; 22354736e196ff79962b3ddb52619a674044d773e2Dianne Hackbornimport android.os.ShellCallback; 239918234dcf9e115560144d0218682dd5050843bcAdrian Roosimport android.util.Log; 24ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brownimport android.view.Display; 25d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport com.android.internal.inputmethod.InputMethodSubtypeHandle; 26282cfefea0fbbd299839e353e6d30affdcd4a55cChris Wrenimport com.android.internal.messages.nano.SystemMessageProto.SystemMessage; 27af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitschimport com.android.internal.notification.SystemNotificationChannels; 2839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport com.android.internal.os.SomeArgs; 29cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport com.android.internal.R; 30fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport com.android.internal.util.DumpUtils; 31b004b5137e12bffae9a3d3ae97440c8c24bdc07aMichael Wrightimport com.android.internal.util.Preconditions; 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport com.android.internal.util.XmlUtils; 334ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport com.android.server.DisplayThread; 344ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport com.android.server.LocalServices; 3589ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brownimport com.android.server.Watchdog; 3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport org.xmlpull.v1.XmlPullParser; 3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 39a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brownimport android.Manifest; 40cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport android.app.Notification; 41cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport android.app.NotificationManager; 42cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport android.app.PendingIntent; 435bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brownimport android.bluetooth.BluetoothAdapter; 445bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brownimport android.bluetooth.BluetoothDevice; 456ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brownimport android.content.BroadcastReceiver; 469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.ComponentName; 4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.content.Context; 489f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.Intent; 496ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brownimport android.content.IntentFilter; 509f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.pm.ActivityInfo; 518ebac231966e27364e5d463b63540a0527d40c4bMichael Wrightimport android.content.pm.ApplicationInfo; 52349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brownimport android.content.pm.PackageManager; 539f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.pm.ResolveInfo; 549f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.pm.PackageManager.NameNotFoundException; 559f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.res.Resources; 566ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brownimport android.content.res.Resources.NotFoundException; 579f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.res.TypedArray; 589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.content.res.XmlResourceParser; 591a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brownimport android.database.ContentObserver; 604ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport android.hardware.display.DisplayViewport; 61af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.hardware.input.IInputDevicesChangedListener; 62c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.hardware.input.IInputManager; 63fb290df3c9a6f37ec050163029e25844de2f8590RoboErikimport android.hardware.input.InputDeviceIdentifier; 64ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.hardware.input.InputManager; 654ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport android.hardware.input.InputManagerInternal; 6639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport android.hardware.input.ITabletModeChangedListener; 679f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.hardware.input.KeyboardLayout; 68d6396d67201fb2b64d13070324bb115c9c23b08aJason Gereckeimport android.hardware.input.TouchCalibration; 694532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownimport android.os.Binder; 709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport android.os.Bundle; 7146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.os.Environment; 724532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownimport android.os.Handler; 73af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.IBinder; 74a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brownimport android.os.Looper; 75af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.Message; 7605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownimport android.os.MessageQueue; 77ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brownimport android.os.Process; 78af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.os.RemoteException; 79d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport android.os.ResultReceiver; 80d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wrightimport android.os.ShellCommand; 8150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackbornimport android.os.UserHandle; 821a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brownimport android.provider.Settings; 831a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brownimport android.provider.Settings.SettingNotFoundException; 840748342d2ed264c01384fbaa4446a702a8824813Michael Wrightimport android.text.TextUtils; 8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.util.Slog; 86af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownimport android.util.SparseArray; 8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.util.Xml; 88c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.IInputFilter; 89c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganovimport android.view.IInputFilterHost; 903787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheevimport android.view.IWindow; 9146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport android.view.InputChannel; 928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownimport android.view.InputDevice; 936ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brownimport android.view.InputEvent; 941f2451007c660091b7b090c1ea332f9044515d2dJeff Brownimport android.view.KeyEvent; 952352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brownimport android.view.PointerIcon; 96d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gereckeimport android.view.Surface; 97a454767b09ecb7d25d00beae0e5a1fdd48605c63Jeff Brownimport android.view.ViewConfiguration; 980029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownimport android.view.WindowManagerPolicy; 99b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawaimport android.view.inputmethod.InputMethodInfo; 100b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawaimport android.view.inputmethod.InputMethodSubtype; 10146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.File; 1034532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brownimport java.io.FileDescriptor; 10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.FileNotFoundException; 10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.FileReader; 1069918234dcf9e115560144d0218682dd5050843bcAdrian Roosimport java.io.FileWriter; 10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.IOException; 1086ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brownimport java.io.InputStreamReader; 10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.io.PrintWriter; 11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownimport java.util.ArrayList; 1110748342d2ed264c01384fbaa4446a702a8824813Michael Wrightimport java.util.Collections; 1129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownimport java.util.HashMap; 113cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brownimport java.util.HashSet; 11439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wrightimport java.util.List; 1150748342d2ed264c01384fbaa4446a702a8824813Michael Wrightimport java.util.Locale; 116a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown 1179918234dcf9e115560144d0218682dd5050843bcAdrian Roosimport libcore.io.IoUtils; 1186ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brownimport libcore.io.Streams; 119a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brownimport libcore.util.Objects; 12046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/* 12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Wraps the C++ InputManager and provides its callbacks. 12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */ 124d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brownpublic class InputManagerService extends IInputManager.Stub 1254ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown implements Watchdog.Monitor { 12646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown static final String TAG = "InputManager"; 1271b9ba578f1d2acf86c75110e89ae3d2e0434483aJeff Brown static final boolean DEBUG = false; 1284532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 1294532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; 1304532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 131af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1; 132cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2; 133cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3; 134cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4; 135cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private static final int MSG_RELOAD_DEVICE_ALIASES = 5; 13639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 6; 137b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa private static final int MSG_INPUT_METHOD_SUBTYPE_CHANGED = 7; 138af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1394532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Pointer to native input manager service object. 1407e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private final long mPtr; 141b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown 14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown private final Context mContext; 143af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final InputManagerHandler mHandler; 144a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown 1459918234dcf9e115560144d0218682dd5050843bcAdrian Roos private final File mDoubleTouchGestureEnableFile; 1469918234dcf9e115560144d0218682dd5050843bcAdrian Roos 147a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown private WindowManagerCallbacks mWindowManagerCallbacks; 1482f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner private WiredAccessoryCallbacks mWiredAccessoryCallbacks; 1496ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private boolean mSystemReady; 150cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private NotificationManager mNotificationManager; 151af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 15239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final Object mTabletModeLock = new Object(); 15339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright // List of currently registered tablet mode changed listeners by process id 15439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final SparseArray<TabletModeChangedListenerRecord> mTabletModeChangedListeners = 15539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright new SparseArray<>(); // guarded by mTabletModeLock 15639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final List<TabletModeChangedListenerRecord> mTempTabletModeChangedListenersToNotify = 15739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright new ArrayList<>(); 15839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 159a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown // Persistent data store. Must be locked each time during use. 160a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown private final PersistentDataStore mDataStore = new PersistentDataStore(); 161af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 162af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // List of currently registered input devices changed listeners by process id. 163af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private Object mInputDevicesLock = new Object(); 164af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private boolean mInputDevicesChangedPending; // guarded by mInputDevicesLock 165af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private InputDevice[] mInputDevices = new InputDevice[0]; 166af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final SparseArray<InputDevicesChangedListenerRecord> mInputDevicesChangedListeners = 167af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new SparseArray<InputDevicesChangedListenerRecord>(); // guarded by mInputDevicesLock 168af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final ArrayList<InputDevicesChangedListenerRecord> 169af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mTempInputDevicesChangedListenersToNotify = 170af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new ArrayList<InputDevicesChangedListenerRecord>(); // handler thread only 171cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private final ArrayList<InputDevice> 172cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempFullKeyboards = new ArrayList<InputDevice>(); // handler thread only 173cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private boolean mKeyboardLayoutNotificationShown; 174d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright private InputMethodSubtypeHandle mCurrentImeHandle; 175af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 176a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown // State for vibrator tokens. 177a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private Object mVibratorLock = new Object(); 178a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private HashMap<IBinder, VibratorToken> mVibratorTokens = 179a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown new HashMap<IBinder, VibratorToken>(); 180a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private int mNextVibratorTokenValue; 181a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 182af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // State for the currently installed input filter. 183af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final Object mInputFilterLock = new Object(); 184c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov IInputFilter mInputFilter; // guarded by mInputFilterLock 185af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputFilterHost mInputFilterHost; // guarded by mInputFilterLock 1864532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 1873787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev private IWindow mFocusedWindow; 1883787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev private boolean mFocusedWindowHasCapture; 1893787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev 1907e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native long nativeInit(InputManagerService service, 1914532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown Context context, MessageQueue messageQueue); 1927e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeStart(long ptr); 193b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon private static native void nativeSetVirtualDisplayViewports(long ptr, 194b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon DisplayViewport[] viewports); 195b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon private static native void nativeSetDisplayViewport(long ptr, int viewportType, 196d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown int displayId, int rotation, 197d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown int logicalLeft, int logicalTop, int logicalRight, int logicalBottom, 19883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown int physicalLeft, int physicalTop, int physicalRight, int physicalBottom, 199b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon int deviceWidth, int deviceHeight, String uniqueId); 200d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 2017e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native int nativeGetScanCodeState(long ptr, 2024532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown int deviceId, int sourceMask, int scanCode); 2037e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native int nativeGetKeyCodeState(long ptr, 2044532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown int deviceId, int sourceMask, int keyCode); 2057e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native int nativeGetSwitchState(long ptr, 2064532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown int deviceId, int sourceMask, int sw); 2077e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native boolean nativeHasKeys(long ptr, 2084532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); 2097e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel, 210928e054931d357326613c78e62f4d850b7c442ffJeff Brown InputWindowHandle inputWindowHandle, boolean monitor); 2117e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel); 2127e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetInputFilterEnabled(long ptr, boolean enable); 213ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId, 2140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown int injectorPid, int injectorUid, int syncMode, int timeoutMillis, 2150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown int policyFlags); 216112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian private static native void nativeToggleCapsLock(long ptr, int deviceId); 2177e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles); 2187e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen); 2197e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetSystemUiVisibility(long ptr, int visibility); 2207e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetFocusedApplication(long ptr, 2214532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown InputApplicationHandle application); 2227e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native boolean nativeTransferTouchFocus(long ptr, 2234532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown InputChannel fromChannel, InputChannel toChannel); 2247e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetPointerSpeed(long ptr, int speed); 2257e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeSetShowTouches(long ptr, boolean enabled); 226037c33eae74bee2774897d969d48947f9abe254fJeff Brown private static native void nativeSetInteractive(long ptr, boolean interactive); 227857aa7be880c53d78f72a9f227cbdf72ee68d587Jason Gerecke private static native void nativeReloadCalibration(long ptr); 2287e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeVibrate(long ptr, int deviceId, long[] pattern, 229a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown int repeat, int token); 2307e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeCancelVibrate(long ptr, int deviceId, int token); 2317e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeReloadKeyboardLayouts(long ptr); 2327e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeReloadDeviceAliases(long ptr); 2337e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native String nativeDump(long ptr); 2347e2a9dcf1a4044ed3f81c5b736b5027231395b73Ashok Bhat private static native void nativeMonitor(long ptr); 235f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright private static native void nativeSetPointerIconType(long ptr, int iconId); 23619a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai private static native void nativeReloadPointerIcons(long ptr); 237d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai private static native void nativeSetCustomPointerIcon(long ptr, PointerIcon icon); 2383787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev private static native void nativeSetPointerCapture(long ptr, boolean detached); 239ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 2407fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown // Input event injection constants defined in InputDispatcher.h. 241ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0; 242ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1; 243ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private static final int INPUT_EVENT_INJECTION_FAILED = 2; 244ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3; 245ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 246ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown // Maximum number of milliseconds to wait for input event injection. 247ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000; 248ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 2496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown // Key states (may be returned by queries about the current state of a 2506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown // particular key code, scan code or switch). 2512f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 2526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** The key state is unknown or the requested key itself is not supported. */ 2536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public static final int KEY_STATE_UNKNOWN = -1; 2546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 2556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** The key is up. /*/ 2566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public static final int KEY_STATE_UP = 0; 2576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 2586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** The key is down. */ 2596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public static final int KEY_STATE_DOWN = 1; 2606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 2616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** The key is down but is a virtual key press that is being emulated by the system. */ 2626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public static final int KEY_STATE_VIRTUAL = 2; 2636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown 264c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown /** Scan code: Mouse / trackball button. */ 265c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown public static final int BTN_MOUSE = 0x110; 266c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown 2672f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner // Switch code values must match bionic/libc/kernel/common/linux/input.h 268c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown /** Switch code: Lid switch. When set, lid is shut. */ 269c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown public static final int SW_LID = 0x00; 270c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown 27139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright /** Switch code: Tablet mode switch. 27239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright * When set, the device is in tablet mode (i.e. no keyboard is connected). 27339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright */ 27439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public static final int SW_TABLET_MODE = 0x01; 27539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 276c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown /** Switch code: Keypad slide. When set, keyboard is exposed. */ 277c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown public static final int SW_KEYPAD_SLIDE = 0x0a; 278c458ce98ce42c00b98afe00670f822814f3da572Jeff Brown 2792f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner /** Switch code: Headphone. When set, headphone is inserted. */ 2802f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_HEADPHONE_INSERT = 0x02; 2812f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 2822f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner /** Switch code: Microphone. When set, microphone is inserted. */ 2832f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_MICROPHONE_INSERT = 0x04; 2842f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 28543cc8bbbbd5e6418cdfa0fa4b26c9f5c3a28c029Jon Eklund /** Switch code: Line out. When set, Line out (hi-Z) is inserted. */ 28643cc8bbbbd5e6418cdfa0fa4b26c9f5c3a28c029Jon Eklund public static final int SW_LINEOUT_INSERT = 0x06; 28743cc8bbbbd5e6418cdfa0fa4b26c9f5c3a28c029Jon Eklund 2882f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner /** Switch code: Headphone/Microphone Jack. When set, something is inserted. */ 2892f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_JACK_PHYSICAL_INSERT = 0x07; 2902f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 2913818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright /** Switch code: Camera lens cover. When set the lens is covered. */ 2923818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright public static final int SW_CAMERA_LENS_COVER = 0x09; 2933818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright 294b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon // Viewport constants defined in InputReader.h. 295b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon public static final int VIEWPORT_DEFAULT = 1; 296b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon public static final int VIEWPORT_EXTERNAL = 2; 297b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon public static final int VIEWPORT_VIRTUAL = 3; 298b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon 2992f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_LID_BIT = 1 << SW_LID; 30039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public static final int SW_TABLET_MODE_BIT = 1 << SW_TABLET_MODE; 3012f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_KEYPAD_SLIDE_BIT = 1 << SW_KEYPAD_SLIDE; 3022f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_HEADPHONE_INSERT_BIT = 1 << SW_HEADPHONE_INSERT; 3032f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT; 30443cc8bbbbd5e6418cdfa0fa4b26c9f5c3a28c029Jon Eklund public static final int SW_LINEOUT_INSERT_BIT = 1 << SW_LINEOUT_INSERT; 3052f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_JACK_PHYSICAL_INSERT_BIT = 1 << SW_JACK_PHYSICAL_INSERT; 3062f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public static final int SW_JACK_BITS = 30743cc8bbbbd5e6418cdfa0fa4b26c9f5c3a28c029Jon Eklund SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT; 3083818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER; 3092f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 3102f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */ 3112f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner final boolean mUseDevInputEventForAudioJack; 3122f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 3134ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown public InputManagerService(Context context) { 31446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown this.mContext = context; 3154ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper()); 31605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 3172f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner mUseDevInputEventForAudioJack = 3182f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); 3192f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" 3202f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner + mUseDevInputEventForAudioJack); 3214532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); 3224ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown 3239918234dcf9e115560144d0218682dd5050843bcAdrian Roos String doubleTouchGestureEnablePath = context.getResources().getString( 3249918234dcf9e115560144d0218682dd5050843bcAdrian Roos R.string.config_doubleTouchGestureEnableFile); 3259918234dcf9e115560144d0218682dd5050843bcAdrian Roos mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null : 3269918234dcf9e115560144d0218682dd5050843bcAdrian Roos new File(doubleTouchGestureEnablePath); 3279918234dcf9e115560144d0218682dd5050843bcAdrian Roos 3284ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown LocalServices.addService(InputManagerInternal.class, new LocalService()); 32946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 3301a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 331a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) { 332a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown mWindowManagerCallbacks = callbacks; 333a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown } 334a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown 3352f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public void setWiredAccessoryCallbacks(WiredAccessoryCallbacks callbacks) { 3362f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner mWiredAccessoryCallbacks = callbacks; 3372f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner } 3382f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 33946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown public void start() { 34046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown Slog.i(TAG, "Starting input manager"); 3414532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeStart(mPtr); 3424532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 3434532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Add ourself to the Watchdog monitors. 3444532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown Watchdog.getInstance().addMonitor(this); 3451a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 3461a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown registerPointerSpeedSettingObserver(); 347daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown registerShowTouchesSettingObserver(); 34819a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai registerAccessibilityLargePointerSettingObserver(); 349daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown 350d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown mContext.registerReceiver(new BroadcastReceiver() { 351d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown @Override 352d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown public void onReceive(Context context, Intent intent) { 353d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown updatePointerSpeedFromSettings(); 354d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown updateShowTouchesFromSettings(); 355e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai updateAccessibilityLargePointerFromSettings(); 356d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown } 357d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); 358d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown 3591a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown updatePointerSpeedFromSettings(); 360daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown updateShowTouchesFromSettings(); 361e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai updateAccessibilityLargePointerFromSettings(); 36246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 3636ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 3649631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie // TODO(BT) Pass in paramter for bluetooth system 365a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void systemRunning() { 3666ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (DEBUG) { 3676ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown Slog.d(TAG, "System ready."); 3686ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 369cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mNotificationManager = (NotificationManager)mContext.getSystemService( 370cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Context.NOTIFICATION_SERVICE); 3716ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown mSystemReady = true; 3726ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 3736ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); 3746ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 3756ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 37669b07161bebdb2c726e3a826c2268866f1a94517Jeff Brown filter.addAction(Intent.ACTION_PACKAGE_REPLACED); 3776ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown filter.addDataScheme("package"); 3786ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown mContext.registerReceiver(new BroadcastReceiver() { 3796ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown @Override 3806ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown public void onReceive(Context context, Intent intent) { 381cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown updateKeyboardLayouts(); 3826ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 3836ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown }, filter, null, mHandler); 3845bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown 3855bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED); 3865bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown mContext.registerReceiver(new BroadcastReceiver() { 3875bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown @Override 3885bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown public void onReceive(Context context, Intent intent) { 3895bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown reloadDeviceAliases(); 3905bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown } 3915bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown }, filter, null, mHandler); 3925bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown 393cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.sendEmptyMessage(MSG_RELOAD_DEVICE_ALIASES); 394cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.sendEmptyMessage(MSG_UPDATE_KEYBOARD_LAYOUTS); 3954a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3Eric Laurent 3964a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3Eric Laurent if (mWiredAccessoryCallbacks != null) { 3974a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3Eric Laurent mWiredAccessoryCallbacks.systemReady(); 3984a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3Eric Laurent } 3996ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 4006ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 4016ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private void reloadKeyboardLayouts() { 402cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (DEBUG) { 403cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Slog.d(TAG, "Reloading keyboard layouts."); 404cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 4056ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown nativeReloadKeyboardLayouts(mPtr); 4066ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 4076ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 4085bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown private void reloadDeviceAliases() { 409cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (DEBUG) { 410cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Slog.d(TAG, "Reloading device names."); 411cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 4125bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown nativeReloadDeviceAliases(mPtr); 4135bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown } 4145bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown 4154ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown private void setDisplayViewportsInternal(DisplayViewport defaultViewport, 416b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon DisplayViewport externalTouchViewport, 417b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon List<DisplayViewport> virtualTouchViewports) { 418d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown if (defaultViewport.valid) { 419b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon setDisplayViewport(VIEWPORT_DEFAULT, defaultViewport); 42046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 421d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 422d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown if (externalTouchViewport.valid) { 423b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon setDisplayViewport(VIEWPORT_EXTERNAL, externalTouchViewport); 424d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown } else if (defaultViewport.valid) { 425b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon setDisplayViewport(VIEWPORT_EXTERNAL, defaultViewport); 426b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown } 427b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon 428b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon nativeSetVirtualDisplayViewports(mPtr, 429b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon virtualTouchViewports.toArray(new DisplayViewport[0])); 43046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 4314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 432b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon private void setDisplayViewport(int viewportType, DisplayViewport viewport) { 433b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon nativeSetDisplayViewport(mPtr, viewportType, 434d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown viewport.displayId, viewport.orientation, 435d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown viewport.logicalFrame.left, viewport.logicalFrame.top, 436d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown viewport.logicalFrame.right, viewport.logicalFrame.bottom, 437d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown viewport.physicalFrame.left, viewport.physicalFrame.top, 43883d616a9c7b9505153d258511eb5c16b552e268dJeff Brown viewport.physicalFrame.right, viewport.physicalFrame.bottom, 439b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon viewport.deviceWidth, viewport.deviceHeight, viewport.uniqueId); 44046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 441ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 4426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** 4436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * Gets the current state of a key or button by key code. 4446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param deviceId The input device id, or -1 to consult all devices. 4456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 4466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * consider all input sources. An input device is consulted if at least one of its 4476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * non-class input source bits matches the specified source mask. 4486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param keyCode The key code to check. 4496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @return The key state. 4506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown */ 4516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public int getKeyCodeState(int deviceId, int sourceMask, int keyCode) { 4524532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return nativeGetKeyCodeState(mPtr, deviceId, sourceMask, keyCode); 45346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 4542f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 4556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** 4566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * Gets the current state of a key or button by scan code. 4576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param deviceId The input device id, or -1 to consult all devices. 4586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 4596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * consider all input sources. An input device is consulted if at least one of its 4606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * non-class input source bits matches the specified source mask. 4616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param scanCode The scan code to check. 4626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @return The key state. 4636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown */ 4646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public int getScanCodeState(int deviceId, int sourceMask, int scanCode) { 4654532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return nativeGetScanCodeState(mPtr, deviceId, sourceMask, scanCode); 46646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 467fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 4686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** 4696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * Gets the current state of a switch by switch code. 4706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param deviceId The input device id, or -1 to consult all devices. 4716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 4726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * consider all input sources. An input device is consulted if at least one of its 4736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * non-class input source bits matches the specified source mask. 4746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param switchCode The switch code to check. 4756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @return The switch state. 4766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown */ 4776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public int getSwitchState(int deviceId, int sourceMask, int switchCode) { 4784532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return nativeGetSwitchState(mPtr, deviceId, sourceMask, switchCode); 47946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 48046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 4816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown /** 4826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * Determines whether the specified key codes are supported by a particular device. 4836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param deviceId The input device id, or -1 to consult all devices. 4846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param sourceMask The input sources to consult, or {@link InputDevice#SOURCE_ANY} to 4856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * consider all input sources. An input device is consulted if at least one of its 4866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * non-class input source bits matches the specified source mask. 4876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param keyCodes The array of key codes to check. 4886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @param keyExists An array at least as large as keyCodes whose entries will be set 4896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * to true or false based on the presence or absence of support for the corresponding 4906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * key codes. 4916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * @return True if the lookup was successful, false otherwise. 4926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown */ 4939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 4946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) { 49546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (keyCodes == null) { 49646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown throw new IllegalArgumentException("keyCodes must not be null."); 49746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 4986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown if (keyExists == null || keyExists.length < keyCodes.length) { 4996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown throw new IllegalArgumentException("keyExists must not be null and must be at " 5006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown + "least as large as keyCodes."); 50146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 502fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 5034532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists); 50446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 505fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 506a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** 507a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * Creates an input channel that will receive all input from the input dispatcher. 508a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * @param inputChannelName The input channel name. 509a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * @return The input channel. 510a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown */ 511a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown public InputChannel monitorInput(String inputChannelName) { 512a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown if (inputChannelName == null) { 513a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown throw new IllegalArgumentException("inputChannelName must not be null."); 514a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown } 515fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 516a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName); 5174532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeRegisterInputChannel(mPtr, inputChannels[0], null, true); 518a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown inputChannels[0].dispose(); // don't need to retain the Java object reference 519a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown return inputChannels[1]; 520a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown } 521a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown 522a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** 523a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * Registers an input channel so that it can be used as an input event target. 524a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * @param inputChannel The input channel to register. 525928e054931d357326613c78e62f4d850b7c442ffJeff Brown * @param inputWindowHandle The handle of the input window associated with the 526928e054931d357326613c78e62f4d850b7c442ffJeff Brown * input channel, or null if none. 527a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown */ 528928e054931d357326613c78e62f4d850b7c442ffJeff Brown public void registerInputChannel(InputChannel inputChannel, 529928e054931d357326613c78e62f4d850b7c442ffJeff Brown InputWindowHandle inputWindowHandle) { 53046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (inputChannel == null) { 53146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown throw new IllegalArgumentException("inputChannel must not be null."); 53246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 533fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 5344532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false); 53546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 536fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 537a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown /** 538a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * Unregisters an input channel. 539a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown * @param inputChannel The input channel to unregister. 540a41ca77fabe1c7ad12ebb9b69b9e786c07d49fa0Jeff Brown */ 54146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown public void unregisterInputChannel(InputChannel inputChannel) { 54246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown if (inputChannel == null) { 54346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown throw new IllegalArgumentException("inputChannel must not be null."); 54446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 545fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 5464532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeUnregisterInputChannel(mPtr, inputChannel); 54746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 5480029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 5490029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown /** 5500029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Sets an input filter that will receive all input events before they are dispatched. 5510029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * The input filter may then reinterpret input events or inject new ones. 5520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 5530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * To ensure consistency, the input dispatcher automatically drops all events 5540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * in progress whenever an input filter is installed or uninstalled. After an input 5550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * filter is uninstalled, it can no longer send input events unless it is reinstalled. 5560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * Any events it attempts to send after it has been uninstalled will be dropped. 5570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * 5580029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown * @param filter The input filter, or null to remove the current filter. 5590029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown */ 560c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov public void setInputFilter(IInputFilter filter) { 5610029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown synchronized (mInputFilterLock) { 562c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov final IInputFilter oldFilter = mInputFilter; 5630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (oldFilter == filter) { 5640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown return; // nothing to do 5650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 5660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 5670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (oldFilter != null) { 5680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mInputFilter = null; 5690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mInputFilterHost.disconnectLocked(); 5700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mInputFilterHost = null; 571c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 572c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov oldFilter.uninstall(); 573c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException re) { 574c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 575c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 5760029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 5770029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 5780029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown if (filter != null) { 5790029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mInputFilter = filter; 5800029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown mInputFilterHost = new InputFilterHost(); 581c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 582c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov filter.install(mInputFilterHost); 583c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException re) { 584c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 585c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 5860029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 5870029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 5884532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetInputFilterEnabled(mPtr, filter != null); 5890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 5900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 5910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 5929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 593ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public boolean injectInputEvent(InputEvent event, int mode) { 594ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode); 595ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown } 596ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown 597ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) { 5987fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown if (event == null) { 5997fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown throw new IllegalArgumentException("event must not be null"); 6007fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown } 601ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC 602ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH 603ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) { 604ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new IllegalArgumentException("mode is invalid"); 6057fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown } 6066ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown 607ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown final int pid = Binder.getCallingPid(); 608ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown final int uid = Binder.getCallingUid(); 609ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown final long ident = Binder.clearCallingIdentity(); 610ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown final int result; 611ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown try { 612ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode, 613ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); 614ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } finally { 615ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Binder.restoreCallingIdentity(ident); 616ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 617ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown switch (result) { 618ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown case INPUT_EVENT_INJECTION_PERMISSION_DENIED: 619ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Slog.w(TAG, "Input event injection from pid " + pid + " permission denied."); 620ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new SecurityException( 621ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown "Injecting to another application requires INJECT_EVENTS permission"); 622ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown case INPUT_EVENT_INJECTION_SUCCEEDED: 623ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return true; 624ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown case INPUT_EVENT_INJECTION_TIMED_OUT: 625ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Slog.w(TAG, "Input event injection from pid " + pid + " timed out."); 626ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 627ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown case INPUT_EVENT_INJECTION_FAILED: 628ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown default: 629ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Slog.w(TAG, "Input event injection from pid " + pid + " failed."); 630ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 631ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 63246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 6330029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 6348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown /** 6358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown * Gets information about the input device with the specified id. 6362f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner * @param deviceId The device id. 6378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown * @return The input device or null if not found. 6388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown */ 6399f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 6408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown public InputDevice getInputDevice(int deviceId) { 641af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 642af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int count = mInputDevices.length; 643af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < count; i++) { 644af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice inputDevice = mInputDevices[i]; 645af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (inputDevice.getId() == deviceId) { 646af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return inputDevice; 647af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 648af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 649af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 650af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return null; 6518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown } 652af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 6538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown /** 6548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown * Gets the ids of all input devices in the system. 6558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown * @return The input device ids. 6568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown */ 6579f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 6588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown public int[] getInputDeviceIds() { 659af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 660af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int count = mInputDevices.length; 661af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int[] ids = new int[count]; 662af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < count; i++) { 663af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown ids[i] = mInputDevices[i].getId(); 664af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 665af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return ids; 666af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 667af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 668af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 669daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown /** 670daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown * Gets all input devices in the system. 671daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown * @return The array of input devices. 672daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown */ 673daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown public InputDevice[] getInputDevices() { 674daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown synchronized (mInputDevicesLock) { 675daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown return mInputDevices; 676daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown } 677daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown } 678daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown 679af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override // Binder call 680af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void registerInputDevicesChangedListener(IInputDevicesChangedListener listener) { 681af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (listener == null) { 682af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new IllegalArgumentException("listener must not be null"); 683af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 684af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 685af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 686af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown int callingPid = Binder.getCallingPid(); 687af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (mInputDevicesChangedListeners.get(callingPid) != null) { 688af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new SecurityException("The calling process has already " 689af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown + "registered an InputDevicesChangedListener."); 690af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 691af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 692af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown InputDevicesChangedListenerRecord record = 693af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown new InputDevicesChangedListenerRecord(callingPid, listener); 694af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 695af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown IBinder binder = listener.asBinder(); 696af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown binder.linkToDeath(record, 0); 697af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 698af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // give up 699af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown throw new RuntimeException(ex); 700af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 701af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 702af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListeners.put(callingPid, record); 703af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 704af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 705af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 706af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void onInputDevicesChangedListenerDied(int pid) { 707af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 708af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListeners.remove(pid); 709af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 710af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 711af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 712af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // Must be called on handler. 713cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private void deliverInputDevicesChanged(InputDevice[] oldInputDevices) { 714cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Scan for changes. 715cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown int numFullKeyboardsAdded = 0; 716af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mTempInputDevicesChangedListenersToNotify.clear(); 717cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempFullKeyboards.clear(); 718af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numListeners; 719af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int[] deviceIdAndGeneration; 720af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 721af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!mInputDevicesChangedPending) { 722af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown return; 723af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 724af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedPending = false; 725af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 726af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown numListeners = mInputDevicesChangedListeners.size(); 727af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 728af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mTempInputDevicesChangedListenersToNotify.add( 729af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedListeners.valueAt(i)); 730af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 731af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 732af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final int numDevices = mInputDevices.length; 733af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown deviceIdAndGeneration = new int[numDevices * 2]; 734af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numDevices; i++) { 735af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown final InputDevice inputDevice = mInputDevices[i]; 736af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown deviceIdAndGeneration[i * 2] = inputDevice.getId(); 737af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown deviceIdAndGeneration[i * 2 + 1] = inputDevice.getGeneration(); 738cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 7397e4ff4b986d626493afb676dd4824d2b3663260aJeff Brown if (!inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { 740cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (!containsInputDeviceWithDescriptor(oldInputDevices, 741cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown inputDevice.getDescriptor())) { 742cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempFullKeyboards.add(numFullKeyboardsAdded++, inputDevice); 743cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } else { 744cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempFullKeyboards.add(inputDevice); 745cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 746cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 747af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 748af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 749af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 750cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Notify listeners. 751af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown for (int i = 0; i < numListeners; i++) { 752af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mTempInputDevicesChangedListenersToNotify.get(i).notifyInputDevicesChanged( 753af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown deviceIdAndGeneration); 754af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 755cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempInputDevicesChangedListenersToNotify.clear(); 756cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 757cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Check for missing keyboard layouts. 7580748342d2ed264c01384fbaa4446a702a8824813Michael Wright List<InputDevice> keyboardsMissingLayout = new ArrayList<>(); 7590748342d2ed264c01384fbaa4446a702a8824813Michael Wright final int numFullKeyboards = mTempFullKeyboards.size(); 7600748342d2ed264c01384fbaa4446a702a8824813Michael Wright synchronized (mDataStore) { 7610748342d2ed264c01384fbaa4446a702a8824813Michael Wright for (int i = 0; i < numFullKeyboards; i++) { 7620748342d2ed264c01384fbaa4446a702a8824813Michael Wright final InputDevice inputDevice = mTempFullKeyboards.get(i); 7630748342d2ed264c01384fbaa4446a702a8824813Michael Wright String layout = 7640748342d2ed264c01384fbaa4446a702a8824813Michael Wright getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier()); 7650748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layout == null) { 7660748342d2ed264c01384fbaa4446a702a8824813Michael Wright layout = getDefaultKeyboardLayout(inputDevice); 7670748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layout != null) { 7680748342d2ed264c01384fbaa4446a702a8824813Michael Wright setCurrentKeyboardLayoutForInputDevice( 7690748342d2ed264c01384fbaa4446a702a8824813Michael Wright inputDevice.getIdentifier(), layout); 770cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 771cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 7720748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layout == null) { 7730748342d2ed264c01384fbaa4446a702a8824813Michael Wright keyboardsMissingLayout.add(inputDevice); 7740748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 775cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 7760748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 7770748342d2ed264c01384fbaa4446a702a8824813Michael Wright 7780748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (mNotificationManager != null) { 7790748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (!keyboardsMissingLayout.isEmpty()) { 7800748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (keyboardsMissingLayout.size() > 1) { 7810748342d2ed264c01384fbaa4446a702a8824813Michael Wright // We have more than one keyboard missing a layout, so drop the 7820748342d2ed264c01384fbaa4446a702a8824813Michael Wright // user at the generic input methods page so they can pick which 7830748342d2ed264c01384fbaa4446a702a8824813Michael Wright // one to set. 7840748342d2ed264c01384fbaa4446a702a8824813Michael Wright showMissingKeyboardLayoutNotification(null); 7850748342d2ed264c01384fbaa4446a702a8824813Michael Wright } else { 7860748342d2ed264c01384fbaa4446a702a8824813Michael Wright showMissingKeyboardLayoutNotification(keyboardsMissingLayout.get(0)); 787cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 788cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } else if (mKeyboardLayoutNotificationShown) { 789cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown hideMissingKeyboardLayoutNotification(); 790cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 791cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 792cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mTempFullKeyboards.clear(); 793cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 794cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 7950748342d2ed264c01384fbaa4446a702a8824813Michael Wright private String getDefaultKeyboardLayout(final InputDevice d) { 7960748342d2ed264c01384fbaa4446a702a8824813Michael Wright final Locale systemLocale = mContext.getResources().getConfiguration().locale; 7970748342d2ed264c01384fbaa4446a702a8824813Michael Wright // If our locale doesn't have a language for some reason, then we don't really have a 7980748342d2ed264c01384fbaa4446a702a8824813Michael Wright // reasonable default. 7990748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (TextUtils.isEmpty(systemLocale.getLanguage())) { 8000748342d2ed264c01384fbaa4446a702a8824813Michael Wright return null; 8010748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8020748342d2ed264c01384fbaa4446a702a8824813Michael Wright final List<KeyboardLayout> layouts = new ArrayList<>(); 8030748342d2ed264c01384fbaa4446a702a8824813Michael Wright visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { 8040748342d2ed264c01384fbaa4446a702a8824813Michael Wright @Override 8050748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 8060748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 8070748342d2ed264c01384fbaa4446a702a8824813Michael Wright // Only select a default when we know the layout is appropriate. For now, this 8080748342d2ed264c01384fbaa4446a702a8824813Michael Wright // means its a custom layout for a specific keyboard. 8090748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layout.getVendorId() != d.getVendorId() 8100748342d2ed264c01384fbaa4446a702a8824813Michael Wright || layout.getProductId() != d.getProductId()) { 8110748342d2ed264c01384fbaa4446a702a8824813Michael Wright return; 8120748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8135660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final LocaleList locales = layout.getLocales(); 8145660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final int numLocales = locales.size(); 8155660fad79808c6d1823a7135b283003b0947773aYohei Yukawa for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { 8165660fad79808c6d1823a7135b283003b0947773aYohei Yukawa if (isCompatibleLocale(systemLocale, locales.get(localeIndex))) { 8170748342d2ed264c01384fbaa4446a702a8824813Michael Wright layouts.add(layout); 8180748342d2ed264c01384fbaa4446a702a8824813Michael Wright break; 8190748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8200748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8210748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8220748342d2ed264c01384fbaa4446a702a8824813Michael Wright }); 8230748342d2ed264c01384fbaa4446a702a8824813Michael Wright 8240748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layouts.isEmpty()) { 8250748342d2ed264c01384fbaa4446a702a8824813Michael Wright return null; 8260748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8270748342d2ed264c01384fbaa4446a702a8824813Michael Wright 8280748342d2ed264c01384fbaa4446a702a8824813Michael Wright // First sort so that ones with higher priority are listed at the top 8290748342d2ed264c01384fbaa4446a702a8824813Michael Wright Collections.sort(layouts); 8300748342d2ed264c01384fbaa4446a702a8824813Michael Wright // Next we want to try to find an exact match of language, country and variant. 8310748342d2ed264c01384fbaa4446a702a8824813Michael Wright final int N = layouts.size(); 8320748342d2ed264c01384fbaa4446a702a8824813Michael Wright for (int i = 0; i < N; i++) { 8330748342d2ed264c01384fbaa4446a702a8824813Michael Wright KeyboardLayout layout = layouts.get(i); 8345660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final LocaleList locales = layout.getLocales(); 8355660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final int numLocales = locales.size(); 8365660fad79808c6d1823a7135b283003b0947773aYohei Yukawa for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { 8375660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final Locale locale = locales.get(localeIndex); 8385660fad79808c6d1823a7135b283003b0947773aYohei Yukawa if (locale.getCountry().equals(systemLocale.getCountry()) 8395660fad79808c6d1823a7135b283003b0947773aYohei Yukawa && locale.getVariant().equals(systemLocale.getVariant())) { 8400748342d2ed264c01384fbaa4446a702a8824813Michael Wright return layout.getDescriptor(); 8410748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8420748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8430748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8440748342d2ed264c01384fbaa4446a702a8824813Michael Wright // Then try an exact match of language and country 8450748342d2ed264c01384fbaa4446a702a8824813Michael Wright for (int i = 0; i < N; i++) { 8460748342d2ed264c01384fbaa4446a702a8824813Michael Wright KeyboardLayout layout = layouts.get(i); 8475660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final LocaleList locales = layout.getLocales(); 8485660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final int numLocales = locales.size(); 8495660fad79808c6d1823a7135b283003b0947773aYohei Yukawa for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) { 8505660fad79808c6d1823a7135b283003b0947773aYohei Yukawa final Locale locale = locales.get(localeIndex); 8515660fad79808c6d1823a7135b283003b0947773aYohei Yukawa if (locale.getCountry().equals(systemLocale.getCountry())) { 8520748342d2ed264c01384fbaa4446a702a8824813Michael Wright return layout.getDescriptor(); 8530748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8540748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8550748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8560748342d2ed264c01384fbaa4446a702a8824813Michael Wright 8570748342d2ed264c01384fbaa4446a702a8824813Michael Wright // Give up and just use the highest priority layout with matching language 8580748342d2ed264c01384fbaa4446a702a8824813Michael Wright return layouts.get(0).getDescriptor(); 8590748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8600748342d2ed264c01384fbaa4446a702a8824813Michael Wright 8610748342d2ed264c01384fbaa4446a702a8824813Michael Wright private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) { 8620748342d2ed264c01384fbaa4446a702a8824813Michael Wright // Different languages are never compatible 8630748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) { 8640748342d2ed264c01384fbaa4446a702a8824813Michael Wright return false; 8650748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8660748342d2ed264c01384fbaa4446a702a8824813Michael Wright // If both the system and the keyboard layout have a country specifier, they must be equal. 8670748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (!TextUtils.isEmpty(systemLocale.getCountry()) 8680748342d2ed264c01384fbaa4446a702a8824813Michael Wright && !TextUtils.isEmpty(keyboardLocale.getCountry()) 8690748342d2ed264c01384fbaa4446a702a8824813Michael Wright && !systemLocale.getCountry().equals(keyboardLocale.getCountry())) { 8700748342d2ed264c01384fbaa4446a702a8824813Michael Wright return false; 8710748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8720748342d2ed264c01384fbaa4446a702a8824813Michael Wright return true; 8730748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 8740748342d2ed264c01384fbaa4446a702a8824813Michael Wright 875857aa7be880c53d78f72a9f227cbdf72ee68d587Jason Gerecke @Override // Binder call & native callback 876d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, 877d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke int surfaceRotation) { 878d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke if (inputDeviceDescriptor == null) { 879d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 880d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 881d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 882d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke synchronized (mDataStore) { 883d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke return mDataStore.getTouchCalibration(inputDeviceDescriptor, surfaceRotation); 884d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 885d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 886d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 887d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke @Override // Binder call 888d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation, 889d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke TouchCalibration calibration) { 890d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION, 891d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke "setTouchCalibrationForInputDevice()")) { 892d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke throw new SecurityException("Requires SET_INPUT_CALIBRATION permission"); 893d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 894d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke if (inputDeviceDescriptor == null) { 895d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke throw new IllegalArgumentException("inputDeviceDescriptor must not be null"); 896d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 897d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke if (calibration == null) { 898d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke throw new IllegalArgumentException("calibration must not be null"); 899d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 900d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke if (surfaceRotation < Surface.ROTATION_0 || surfaceRotation > Surface.ROTATION_270) { 901d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke throw new IllegalArgumentException("surfaceRotation value out of bounds"); 902d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke } 903d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 904d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke synchronized (mDataStore) { 905d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke try { 906d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation, 907d52207423225bcd99e94276e9d0fc2cb5f905602Jason Gerecke calibration)) { 908857aa7be880c53d78f72a9f227cbdf72ee68d587Jason Gerecke nativeReloadCalibration(mPtr); 909857aa7be880c53d78f72a9f227cbdf72ee68d587Jason Gerecke } 910d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } finally { 911d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke mDataStore.saveIfNeeded(); 912d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 913d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 914d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke } 915d6396d67201fb2b64d13070324bb115c9c23b08aJason Gerecke 91639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright @Override // Binder call 9179209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright public int isInTabletMode() { 9189209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, 9199209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright "isInTabletMode()")) { 9209209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright throw new SecurityException("Requires TABLET_MODE permission"); 9219209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright } 9229209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright return getSwitchState(-1, InputDevice.SOURCE_ANY, SW_TABLET_MODE); 9239209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright } 9249209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright 9259209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright @Override // Binder call 92639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void registerTabletModeChangedListener(ITabletModeChangedListener listener) { 9279209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright if (!checkCallingPermission(android.Manifest.permission.TABLET_MODE, 92839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright "registerTabletModeChangedListener()")) { 92939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new SecurityException("Requires TABLET_MODE_LISTENER permission"); 93039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 93139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (listener == null) { 93239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new IllegalArgumentException("listener must not be null"); 93339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 93439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 93539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 93639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright final int callingPid = Binder.getCallingPid(); 93739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (mTabletModeChangedListeners.get(callingPid) != null) { 93839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new IllegalStateException("The calling process has already registered " 93939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright + "a TabletModeChangedListener."); 94039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 94139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright TabletModeChangedListenerRecord record = 94239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright new TabletModeChangedListenerRecord(callingPid, listener); 94339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright try { 94439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright IBinder binder = listener.asBinder(); 94539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright binder.linkToDeath(record, 0); 94639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } catch (RemoteException ex) { 94739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright throw new RuntimeException(ex); 94839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 94939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTabletModeChangedListeners.put(callingPid, record); 95039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 95139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 95239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 95339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private void onTabletModeChangedListenerDied(int pid) { 95439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 95539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTabletModeChangedListeners.remove(pid); 95639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 95739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 95839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 95939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright // Must be called on handler 96039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private void deliverTabletModeChanged(long whenNanos, boolean inTabletMode) { 96139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTempTabletModeChangedListenersToNotify.clear(); 96239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright final int numListeners; 96339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright synchronized (mTabletModeLock) { 96439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright numListeners = mTabletModeChangedListeners.size(); 96539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright for (int i = 0; i < numListeners; i++) { 96639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTempTabletModeChangedListenersToNotify.add( 96739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTabletModeChangedListeners.valueAt(i)); 96839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 96939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 97039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright for (int i = 0; i < numListeners; i++) { 97139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mTempTabletModeChangedListenersToNotify.get(i).notifyTabletModeChanged( 97239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright whenNanos, inTabletMode); 97339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 97439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 97539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 976cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Must be called on handler. 977c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright private void showMissingKeyboardLayoutNotification(InputDevice device) { 978cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (!mKeyboardLayoutNotificationShown) { 9792bff4902929037cc7135a0769c43721a1322cb98Yohei Yukawa final Intent intent = new Intent(Settings.ACTION_HARD_KEYBOARD_SETTINGS); 980c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright if (device != null) { 981c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier()); 982cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 983c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 984c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 985c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright | Intent.FLAG_ACTIVITY_CLEAR_TOP); 986c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0, 987c93fbd1fae3d461f2f8a7c039b15f953ed6a8b50Michael Wright intent, 0, null, UserHandle.CURRENT); 988cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 989cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown Resources r = mContext.getResources(); 990af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch Notification notification = 991af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD) 992af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .setContentTitle(r.getString( 993af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch R.string.select_keyboard_layout_notification_title)) 994af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .setContentText(r.getString( 995af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch R.string.select_keyboard_layout_notification_message)) 996af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .setContentIntent(keyboardLayoutIntent) 997af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .setSmallIcon(R.drawable.ic_settings_language) 998af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .setColor(mContext.getColor( 999af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch com.android.internal.R.color.system_notification_accent_color)) 1000af759c52ce01fe6b5144957e38da956af01a217bGeoffrey Pitsch .build(); 100150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.notifyAsUser(null, 1002282cfefea0fbbd299839e353e6d30affdcd4a55cChris Wren SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, 100350cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn notification, UserHandle.ALL); 1004cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mKeyboardLayoutNotificationShown = true; 1005cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1006cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1007cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1008cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Must be called on handler. 1009cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private void hideMissingKeyboardLayoutNotification() { 1010cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (mKeyboardLayoutNotificationShown) { 1011cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mKeyboardLayoutNotificationShown = false; 101250cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn mNotificationManager.cancelAsUser(null, 1013282cfefea0fbbd299839e353e6d30affdcd4a55cChris Wren SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT, 101450cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn UserHandle.ALL); 1015cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1016cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1017cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1018cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Must be called on handler. 1019cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private void updateKeyboardLayouts() { 1020cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Scan all input devices state for keyboard layouts that have been uninstalled. 1021cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown final HashSet<String> availableKeyboardLayouts = new HashSet<String>(); 1022cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { 1023cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown @Override 10240748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 10250748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 10260748342d2ed264c01384fbaa4446a702a8824813Michael Wright availableKeyboardLayouts.add(layout.getDescriptor()); 1027cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1028cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown }); 1029cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mDataStore) { 1030cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 1031cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mDataStore.removeUninstalledKeyboardLayouts(availableKeyboardLayouts); 1032cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } finally { 1033cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mDataStore.saveIfNeeded(); 1034cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1035cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1036cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1037cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Reload keyboard layouts. 1038cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown reloadKeyboardLayouts(); 1039cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1040cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1041cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown private static boolean containsInputDeviceWithDescriptor(InputDevice[] inputDevices, 1042cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String descriptor) { 1043cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown final int numDevices = inputDevices.length; 1044cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown for (int i = 0; i < numDevices; i++) { 1045cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown final InputDevice inputDevice = inputDevices[i]; 1046cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (inputDevice.getDescriptor().equals(descriptor)) { 1047cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return true; 1048cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1049cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1050cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown return false; 10518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown } 10529f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 10539f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 10549f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout[] getKeyboardLayouts() { 10556ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown final ArrayList<KeyboardLayout> list = new ArrayList<KeyboardLayout>(); 10566ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { 10576ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown @Override 10580748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 10590748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 10600748342d2ed264c01384fbaa4446a702a8824813Michael Wright list.add(layout); 10610748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 10620748342d2ed264c01384fbaa4446a702a8824813Michael Wright }); 10630748342d2ed264c01384fbaa4446a702a8824813Michael Wright return list.toArray(new KeyboardLayout[list.size()]); 10640748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 10650748342d2ed264c01384fbaa4446a702a8824813Michael Wright 1066b0e804a303272655ec7c2cece66d69f39b488955Michael Wright @Override // Binder call 10670748342d2ed264c01384fbaa4446a702a8824813Michael Wright public KeyboardLayout[] getKeyboardLayoutsForInputDevice( 10680748342d2ed264c01384fbaa4446a702a8824813Michael Wright final InputDeviceIdentifier identifier) { 1069b0e804a303272655ec7c2cece66d69f39b488955Michael Wright final String[] enabledLayoutDescriptors = 1070b0e804a303272655ec7c2cece66d69f39b488955Michael Wright getEnabledKeyboardLayoutsForInputDevice(identifier); 1071b0e804a303272655ec7c2cece66d69f39b488955Michael Wright final ArrayList<KeyboardLayout> enabledLayouts = 1072b0e804a303272655ec7c2cece66d69f39b488955Michael Wright new ArrayList<KeyboardLayout>(enabledLayoutDescriptors.length); 1073b0e804a303272655ec7c2cece66d69f39b488955Michael Wright final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<KeyboardLayout>(); 10740748342d2ed264c01384fbaa4446a702a8824813Michael Wright visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { 10750748342d2ed264c01384fbaa4446a702a8824813Michael Wright boolean mHasSeenDeviceSpecificLayout; 10760748342d2ed264c01384fbaa4446a702a8824813Michael Wright 10770748342d2ed264c01384fbaa4446a702a8824813Michael Wright @Override 10780748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 10790748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 1080b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // First check if it's enabled. If the keyboard layout is enabled then we always 1081b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // want to return it as a possible layout for the device. 1082b0e804a303272655ec7c2cece66d69f39b488955Michael Wright for (String s : enabledLayoutDescriptors) { 1083b0e804a303272655ec7c2cece66d69f39b488955Michael Wright if (s != null && s.equals(layout.getDescriptor())) { 1084b0e804a303272655ec7c2cece66d69f39b488955Michael Wright enabledLayouts.add(layout); 1085b0e804a303272655ec7c2cece66d69f39b488955Michael Wright return; 1086b0e804a303272655ec7c2cece66d69f39b488955Michael Wright } 1087b0e804a303272655ec7c2cece66d69f39b488955Michael Wright } 1088b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // Next find any potential layouts that aren't yet enabled for the device. For 1089b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // devices that have special layouts we assume there's a reason that the generic 1090b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // layouts don't work for them so we don't want to return them since it's likely 1091b0e804a303272655ec7c2cece66d69f39b488955Michael Wright // to result in a poor user experience. 10920748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (layout.getVendorId() == identifier.getVendorId() 10930748342d2ed264c01384fbaa4446a702a8824813Michael Wright && layout.getProductId() == identifier.getProductId()) { 10940748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (!mHasSeenDeviceSpecificLayout) { 10950748342d2ed264c01384fbaa4446a702a8824813Michael Wright mHasSeenDeviceSpecificLayout = true; 1096b0e804a303272655ec7c2cece66d69f39b488955Michael Wright potentialLayouts.clear(); 10970748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 1098b0e804a303272655ec7c2cece66d69f39b488955Michael Wright potentialLayouts.add(layout); 10990748342d2ed264c01384fbaa4446a702a8824813Michael Wright } else if (layout.getVendorId() == -1 && layout.getProductId() == -1 11000748342d2ed264c01384fbaa4446a702a8824813Michael Wright && !mHasSeenDeviceSpecificLayout) { 1101b0e804a303272655ec7c2cece66d69f39b488955Michael Wright potentialLayouts.add(layout); 11020748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 11036ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11046ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown }); 1105b0e804a303272655ec7c2cece66d69f39b488955Michael Wright final int enabledLayoutSize = enabledLayouts.size(); 1106b0e804a303272655ec7c2cece66d69f39b488955Michael Wright final int potentialLayoutSize = potentialLayouts.size(); 1107b0e804a303272655ec7c2cece66d69f39b488955Michael Wright KeyboardLayout[] layouts = new KeyboardLayout[enabledLayoutSize + potentialLayoutSize]; 1108b0e804a303272655ec7c2cece66d69f39b488955Michael Wright enabledLayouts.toArray(layouts); 1109b0e804a303272655ec7c2cece66d69f39b488955Michael Wright for (int i = 0; i < potentialLayoutSize; i++) { 1110b0e804a303272655ec7c2cece66d69f39b488955Michael Wright layouts[enabledLayoutSize + i] = potentialLayouts.get(i); 1111b0e804a303272655ec7c2cece66d69f39b488955Michael Wright } 1112b0e804a303272655ec7c2cece66d69f39b488955Michael Wright return layouts; 11139f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11149f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11159f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 11169f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) { 11179f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (keyboardLayoutDescriptor == null) { 11189f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 11199f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11209f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11216ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown final KeyboardLayout[] result = new KeyboardLayout[1]; 11226ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() { 11236ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown @Override 11240748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 11250748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 11260748342d2ed264c01384fbaa4446a702a8824813Michael Wright result[0] = layout; 11276ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11286ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown }); 11296ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (result[0] == null) { 11300748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Could not get keyboard layout with descriptor '" 11316ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown + keyboardLayoutDescriptor + "'."); 11329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11336ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return result[0]; 11346ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11359f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11366ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private void visitAllKeyboardLayouts(KeyboardLayoutVisitor visitor) { 11379f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown final PackageManager pm = mContext.getPackageManager(); 11386ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_LAYOUTS); 11396ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown for (ResolveInfo resolveInfo : pm.queryBroadcastReceivers(intent, 11408a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE 11418a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE)) { 11428ebac231966e27364e5d463b63540a0527d40c4bMichael Wright final ActivityInfo activityInfo = resolveInfo.activityInfo; 11438ebac231966e27364e5d463b63540a0527d40c4bMichael Wright final int priority = resolveInfo.priority; 11448ebac231966e27364e5d463b63540a0527d40c4bMichael Wright visitKeyboardLayoutsInPackage(pm, activityInfo, null, priority, visitor); 11456ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11466ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11476ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 11486ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private void visitKeyboardLayout(String keyboardLayoutDescriptor, 11496ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown KeyboardLayoutVisitor visitor) { 11506ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown KeyboardLayoutDescriptor d = KeyboardLayoutDescriptor.parse(keyboardLayoutDescriptor); 11516ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (d != null) { 11526ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown final PackageManager pm = mContext.getPackageManager(); 11536ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown try { 11546ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown ActivityInfo receiver = pm.getReceiverInfo( 11556ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown new ComponentName(d.packageName, d.receiverName), 11565217cacbd9f382068bb9e176cd5a0b15388a335cJeff Sharkey PackageManager.GET_META_DATA 11578a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_AWARE 11588a372a0a280127743ce9a7ce4b6198c7a02d2a4fJeff Sharkey | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 11598ebac231966e27364e5d463b63540a0527d40c4bMichael Wright visitKeyboardLayoutsInPackage(pm, receiver, d.keyboardLayoutName, 0, visitor); 11606ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } catch (NameNotFoundException ex) { 11616ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 11629f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11639f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11649f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11656ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private void visitKeyboardLayoutsInPackage(PackageManager pm, ActivityInfo receiver, 11668ebac231966e27364e5d463b63540a0527d40c4bMichael Wright String keyboardName, int requestedPriority, KeyboardLayoutVisitor visitor) { 11679f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Bundle metaData = receiver.metaData; 11689f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (metaData == null) { 11696ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return; 11709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_LAYOUTS); 11739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (configResId == 0) { 11740748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_LAYOUTS 11759f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + "' on receiver " + receiver.packageName + "/" + receiver.name); 11766ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return; 11779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 11789f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1179d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown CharSequence receiverLabel = receiver.loadLabel(pm); 1180d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown String collection = receiverLabel != null ? receiverLabel.toString() : ""; 11818ebac231966e27364e5d463b63540a0527d40c4bMichael Wright int priority; 11828ebac231966e27364e5d463b63540a0527d40c4bMichael Wright if ((receiver.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11838ebac231966e27364e5d463b63540a0527d40c4bMichael Wright priority = requestedPriority; 11848ebac231966e27364e5d463b63540a0527d40c4bMichael Wright } else { 11858ebac231966e27364e5d463b63540a0527d40c4bMichael Wright priority = 0; 11868ebac231966e27364e5d463b63540a0527d40c4bMichael Wright } 1187d9fec5d317c09da6bcc7a54df4e0190a76d21eaeJeff Brown 11889f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 11899f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); 11909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown XmlResourceParser parser = resources.getXml(configResId); 11919f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 11929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown XmlUtils.beginDocument(parser, "keyboard-layouts"); 11939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 11949f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown for (;;) { 11959f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown XmlUtils.nextElement(parser); 11969f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String element = parser.getName(); 11979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (element == null) { 11989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown break; 11999f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (element.equals("keyboard-layout")) { 12019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown TypedArray a = resources.obtainAttributes( 12029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown parser, com.android.internal.R.styleable.KeyboardLayout); 12039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown try { 12049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String name = a.getString( 12059f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown com.android.internal.R.styleable.KeyboardLayout_name); 12069f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String label = a.getString( 12079f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown com.android.internal.R.styleable.KeyboardLayout_label); 12082f0957607411b99810226ad38d59cf18718b86d0Jeff Brown int keyboardLayoutResId = a.getResourceId( 12092f0957607411b99810226ad38d59cf18718b86d0Jeff Brown com.android.internal.R.styleable.KeyboardLayout_keyboardLayout, 12102f0957607411b99810226ad38d59cf18718b86d0Jeff Brown 0); 12110748342d2ed264c01384fbaa4446a702a8824813Michael Wright String languageTags = a.getString( 12120748342d2ed264c01384fbaa4446a702a8824813Michael Wright com.android.internal.R.styleable.KeyboardLayout_locale); 12135660fad79808c6d1823a7135b283003b0947773aYohei Yukawa LocaleList locales = getLocalesFromLanguageTags(languageTags); 12140748342d2ed264c01384fbaa4446a702a8824813Michael Wright int vid = a.getInt( 12150748342d2ed264c01384fbaa4446a702a8824813Michael Wright com.android.internal.R.styleable.KeyboardLayout_vendorId, -1); 12160748342d2ed264c01384fbaa4446a702a8824813Michael Wright int pid = a.getInt( 12170748342d2ed264c01384fbaa4446a702a8824813Michael Wright com.android.internal.R.styleable.KeyboardLayout_productId, -1); 12180748342d2ed264c01384fbaa4446a702a8824813Michael Wright 12192f0957607411b99810226ad38d59cf18718b86d0Jeff Brown if (name == null || label == null || keyboardLayoutResId == 0) { 12200748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Missing required 'name', 'label' or 'keyboardLayout' " 12219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + "attributes in keyboard layout " 12229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + "resource from receiver " 12239f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + receiver.packageName + "/" + receiver.name); 12249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } else { 12259f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String descriptor = KeyboardLayoutDescriptor.format( 12269f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown receiver.packageName, receiver.name, name); 12276ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (keyboardName == null || name.equals(keyboardName)) { 12280748342d2ed264c01384fbaa4446a702a8824813Michael Wright KeyboardLayout layout = new KeyboardLayout( 12290748342d2ed264c01384fbaa4446a702a8824813Michael Wright descriptor, label, collection, priority, 12300748342d2ed264c01384fbaa4446a702a8824813Michael Wright locales, vid, pid); 12310748342d2ed264c01384fbaa4446a702a8824813Michael Wright visitor.visitKeyboardLayout( 12320748342d2ed264c01384fbaa4446a702a8824813Michael Wright resources, keyboardLayoutResId, layout); 12339f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12349f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12359f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } finally { 12369f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown a.recycle(); 12379f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } else { 12390748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Skipping unrecognized element '" + element 12409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + "' in keyboard layout resource from receiver " 12419f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + receiver.packageName + "/" + receiver.name); 12429f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12439f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12449f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } finally { 12459f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown parser.close(); 12469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } catch (Exception ex) { 12480748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Could not parse keyboard layout resource from receiver " 12499f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown + receiver.packageName + "/" + receiver.name, ex); 12509f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12519f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12529f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 12535660fad79808c6d1823a7135b283003b0947773aYohei Yukawa @NonNull 12545660fad79808c6d1823a7135b283003b0947773aYohei Yukawa private static LocaleList getLocalesFromLanguageTags(String languageTags) { 12550748342d2ed264c01384fbaa4446a702a8824813Michael Wright if (TextUtils.isEmpty(languageTags)) { 12565660fad79808c6d1823a7135b283003b0947773aYohei Yukawa return LocaleList.getEmptyLocaleList(); 12570748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 12585660fad79808c6d1823a7135b283003b0947773aYohei Yukawa return LocaleList.forLanguageTags(languageTags.replace('|', ',')); 12590748342d2ed264c01384fbaa4446a702a8824813Michael Wright } 12600748342d2ed264c01384fbaa4446a702a8824813Michael Wright 1261fb290df3c9a6f37ec050163029e25844de2f8590RoboErik /** 1262fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * Builds a layout descriptor for the vendor/product. This returns the 1263fb290df3c9a6f37ec050163029e25844de2f8590RoboErik * descriptor for ids that aren't useful (such as the default 0, 0). 1264fb290df3c9a6f37ec050163029e25844de2f8590RoboErik */ 1265fb290df3c9a6f37ec050163029e25844de2f8590RoboErik private String getLayoutDescriptor(InputDeviceIdentifier identifier) { 1266fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier == null || identifier.getDescriptor() == null) { 1267fb290df3c9a6f37ec050163029e25844de2f8590RoboErik throw new IllegalArgumentException("identifier and descriptor must not be null"); 1268fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1269fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 1270fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (identifier.getVendorId() == 0 && identifier.getProductId() == 0) { 1271fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return identifier.getDescriptor(); 12729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1273fb290df3c9a6f37ec050163029e25844de2f8590RoboErik StringBuilder bob = new StringBuilder(); 1274fb290df3c9a6f37ec050163029e25844de2f8590RoboErik bob.append("vendor:").append(identifier.getVendorId()); 1275fb290df3c9a6f37ec050163029e25844de2f8590RoboErik bob.append(",product:").append(identifier.getProductId()); 1276fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return bob.toString(); 1277fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1278fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 1279fb290df3c9a6f37ec050163029e25844de2f8590RoboErik @Override // Binder call 1280fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) { 12819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1282fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String key = getLayoutDescriptor(identifier); 1283a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown synchronized (mDataStore) { 1284fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String layout = null; 1285fb290df3c9a6f37ec050163029e25844de2f8590RoboErik // try loading it using the layout descriptor if we have it 1286fb290df3c9a6f37ec050163029e25844de2f8590RoboErik layout = mDataStore.getCurrentKeyboardLayout(key); 1287fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (layout == null && !key.equals(identifier.getDescriptor())) { 1288fb290df3c9a6f37ec050163029e25844de2f8590RoboErik // if it doesn't exist fall back to the device descriptor 1289fb290df3c9a6f37ec050163029e25844de2f8590RoboErik layout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); 1290fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1291fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (DEBUG) { 1292fb290df3c9a6f37ec050163029e25844de2f8590RoboErik Slog.d(TAG, "Loaded keyboard layout id for " + key + " and got " 1293fb290df3c9a6f37ec050163029e25844de2f8590RoboErik + layout); 1294fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1295fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return layout; 1296a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown } 12979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 12989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 12999f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 1300fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 13019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String keyboardLayoutDescriptor) { 13029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, 1303cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown "setCurrentKeyboardLayoutForInputDevice()")) { 13049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); 13059f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1306cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 1307cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 1308cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1309cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1310fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String key = getLayoutDescriptor(identifier); 1311cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mDataStore) { 1312cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 1313fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (mDataStore.setCurrentKeyboardLayout(key, keyboardLayoutDescriptor)) { 1314fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (DEBUG) { 1315fb290df3c9a6f37ec050163029e25844de2f8590RoboErik Slog.d(TAG, "Saved keyboard layout using " + key); 1316fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1317cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); 1318cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1319cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } finally { 1320cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mDataStore.saveIfNeeded(); 1321cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1322cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1323cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 13249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1325cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown @Override // Binder call 13260748342d2ed264c01384fbaa4446a702a8824813Michael Wright public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) { 1327fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String key = getLayoutDescriptor(identifier); 1328cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mDataStore) { 1329fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String[] layouts = mDataStore.getKeyboardLayouts(key); 1330fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if ((layouts == null || layouts.length == 0) 1331fb290df3c9a6f37ec050163029e25844de2f8590RoboErik && !key.equals(identifier.getDescriptor())) { 1332fb290df3c9a6f37ec050163029e25844de2f8590RoboErik layouts = mDataStore.getKeyboardLayouts(identifier.getDescriptor()); 1333fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1334fb290df3c9a6f37ec050163029e25844de2f8590RoboErik return layouts; 1335cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1336cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1337cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1338cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown @Override // Binder call 1339d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Nullable 1340d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public KeyboardLayout getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 1341d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodInfo imeInfo, InputMethodSubtype imeSubtype) { 1342d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(imeInfo, imeSubtype); 1343d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String key = getLayoutDescriptor(identifier); 1344d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright final String keyboardLayoutDescriptor; 1345d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright synchronized (mDataStore) { 1346d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright keyboardLayoutDescriptor = mDataStore.getKeyboardLayout(key, handle); 1347d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1348d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1349d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (keyboardLayoutDescriptor == null) { 1350d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return null; 1351d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1352d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1353d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright final KeyboardLayout[] result = new KeyboardLayout[1]; 1354d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() { 1355d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 1356d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void visitKeyboardLayout(Resources resources, 1357d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 1358d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright result[0] = layout; 1359d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1360d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright }); 1361d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (result[0] == null) { 1362d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright Slog.w(TAG, "Could not get keyboard layout with descriptor '" 1363d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright + keyboardLayoutDescriptor + "'."); 1364d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1365d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return result[0]; 1366d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1367d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1368d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 1369d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 1370d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodInfo imeInfo, InputMethodSubtype imeSubtype, 1371d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String keyboardLayoutDescriptor) { 1372d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, 1373d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright "setKeyboardLayoutForInputDevice()")) { 1374d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); 1375d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1376d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (keyboardLayoutDescriptor == null) { 1377d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 1378d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 137946ac35d09b0a1ba7af7eb4c14293a7978edcd2abYohei Yukawa if (imeInfo == null) { 138046ac35d09b0a1ba7af7eb4c14293a7978edcd2abYohei Yukawa throw new IllegalArgumentException("imeInfo must not be null"); 1381d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1382d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(imeInfo, imeSubtype); 1383d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright setKeyboardLayoutForInputDeviceInner(identifier, handle, keyboardLayoutDescriptor); 1384d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1385d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1386d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright private void setKeyboardLayoutForInputDeviceInner(InputDeviceIdentifier identifier, 1387d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle imeHandle, String keyboardLayoutDescriptor) { 1388d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String key = getLayoutDescriptor(identifier); 1389d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright synchronized (mDataStore) { 1390d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright try { 1391d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (mDataStore.setKeyboardLayout(key, imeHandle, keyboardLayoutDescriptor)) { 1392d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (DEBUG) { 1393d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright Slog.d(TAG, "Set keyboard layout " + keyboardLayoutDescriptor + 1394d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright " for subtype " + imeHandle + " and device " + identifier + 1395d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright " using key " + key); 1396d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1397d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (imeHandle.equals(mCurrentImeHandle)) { 1398d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (DEBUG) { 1399d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright Slog.d(TAG, "Layout for current subtype changed, switching layout"); 1400d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1401d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright SomeArgs args = SomeArgs.obtain(); 1402d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright args.arg1 = identifier; 1403d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright args.arg2 = imeHandle; 1404d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, args).sendToTarget(); 1405d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1406d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); 1407d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1408d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } finally { 1409d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mDataStore.saveIfNeeded(); 1410d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1411d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1412d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1413d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1414d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override // Binder call 1415fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 1416cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 1417cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, 1418cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown "addKeyboardLayoutForInputDevice()")) { 1419cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); 1420cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1421cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 1422cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 1423cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1424cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1425fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String key = getLayoutDescriptor(identifier); 1426a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown synchronized (mDataStore) { 1427a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown try { 1428fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String oldLayout = mDataStore.getCurrentKeyboardLayout(key); 1429fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (oldLayout == null && !key.equals(identifier.getDescriptor())) { 1430fb290df3c9a6f37ec050163029e25844de2f8590RoboErik oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); 1431fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1432fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (mDataStore.addKeyboardLayout(key, keyboardLayoutDescriptor) 1433d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright && !Objects.equal(oldLayout, mDataStore.getCurrentKeyboardLayout(key))) { 1434cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); 1435cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1436a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown } finally { 1437a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown mDataStore.saveIfNeeded(); 1438a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown } 1439a3bc565882dd3984e995363642b1295fe3d24d10Jeff Brown } 1440cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 14419f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1442cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown @Override // Binder call 1443fb290df3c9a6f37ec050163029e25844de2f8590RoboErik public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier, 1444cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown String keyboardLayoutDescriptor) { 1445cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, 1446cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown "removeKeyboardLayoutForInputDevice()")) { 1447cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); 1448cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1449cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown if (keyboardLayoutDescriptor == null) { 1450cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null"); 1451cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1452cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1453fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String key = getLayoutDescriptor(identifier); 1454cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown synchronized (mDataStore) { 1455cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown try { 1456fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String oldLayout = mDataStore.getCurrentKeyboardLayout(key); 1457fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (oldLayout == null && !key.equals(identifier.getDescriptor())) { 1458fb290df3c9a6f37ec050163029e25844de2f8590RoboErik oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor()); 1459fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1460fb290df3c9a6f37ec050163029e25844de2f8590RoboErik boolean removed = mDataStore.removeKeyboardLayout(key, keyboardLayoutDescriptor); 1461fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (!key.equals(identifier.getDescriptor())) { 1462fb290df3c9a6f37ec050163029e25844de2f8590RoboErik // We need to remove from both places to ensure it is gone 1463fb290df3c9a6f37ec050163029e25844de2f8590RoboErik removed |= mDataStore.removeKeyboardLayout(identifier.getDescriptor(), 1464fb290df3c9a6f37ec050163029e25844de2f8590RoboErik keyboardLayoutDescriptor); 1465fb290df3c9a6f37ec050163029e25844de2f8590RoboErik } 1466fb290df3c9a6f37ec050163029e25844de2f8590RoboErik if (removed && !Objects.equal(oldLayout, 1467fb290df3c9a6f37ec050163029e25844de2f8590RoboErik mDataStore.getCurrentKeyboardLayout(key))) { 1468cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS); 1469cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1470cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } finally { 1471cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mDataStore.saveIfNeeded(); 1472cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1473cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1474cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1475cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1476b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa // Must be called on handler. 1477b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa private void handleSwitchInputMethodSubtype(int userId, 1478b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa @Nullable InputMethodInfo inputMethodInfo, @Nullable InputMethodSubtype subtype) { 1479b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa if (DEBUG) { 1480b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa Slog.i(TAG, "InputMethodSubtype changed: userId=" + userId 1481b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa + " ime=" + inputMethodInfo + " subtype=" + subtype); 1482b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa } 1483d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (inputMethodInfo == null) { 1484d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright Slog.d(TAG, "No InputMethod is running, ignoring change"); 1485d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return; 1486d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1487d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (subtype != null && !"keyboard".equals(subtype.getMode())) { 1488d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright Slog.d(TAG, "InputMethodSubtype changed to non-keyboard subtype, ignoring change"); 1489d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return; 1490d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1491d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(inputMethodInfo, subtype); 1492d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (!handle.equals(mCurrentImeHandle)) { 1493d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mCurrentImeHandle = handle; 1494d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright handleSwitchKeyboardLayout(null, handle); 1495d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1496cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1497cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1498cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown // Must be called on handler. 1499d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright private void handleSwitchKeyboardLayout(@Nullable InputDeviceIdentifier identifier, 1500d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle handle) { 1501d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright synchronized (mInputDevicesLock) { 1502d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright for (InputDevice device : mInputDevices) { 1503d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (identifier != null && !device.getIdentifier().equals(identifier) || 1504d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright !device.isFullKeyboard()) { 1505d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright continue; 1506cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1507d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String key = getLayoutDescriptor(device.getIdentifier()); 1508d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright boolean changed = false; 1509d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright synchronized (mDataStore) { 1510d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright try { 1511d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (mDataStore.switchKeyboardLayout(key, handle)) { 1512d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright changed = true; 1513d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1514d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } finally { 1515d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mDataStore.saveIfNeeded(); 1516cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1517cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown } 1518d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (changed) { 1519d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright reloadKeyboardLayouts(); 1520d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 15219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 15229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 15236ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 15249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 15253787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev public void setInputWindows(InputWindowHandle[] windowHandles, 15263787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev InputWindowHandle focusedWindowHandle) { 15273787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev final IWindow newFocusedWindow = 15283787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev focusedWindowHandle != null ? focusedWindowHandle.clientWindow : null; 15293787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev if (mFocusedWindow != newFocusedWindow) { 15303787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev mFocusedWindow = newFocusedWindow; 15313787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev if (mFocusedWindowHasCapture) { 15323787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev setPointerCapture(false); 15333787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15343787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15354532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetInputWindows(mPtr, windowHandles); 1536349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown } 1537fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 15389302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown public void setFocusedApplication(InputApplicationHandle application) { 15394532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetFocusedApplication(mPtr, application); 1540349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown } 1541fb290df3c9a6f37ec050163029e25844de2f8590RoboErik 15423787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev @Override 15433787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev public void requestPointerCapture(IBinder windowToken, boolean enabled) { 15443787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev if (mFocusedWindow == null || mFocusedWindow.asBinder() != windowToken) { 15453787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev Slog.e(TAG, "requestPointerCapture called for a window that has no focus: " 15463787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev + windowToken); 15473787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev return; 15483787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15493787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev if (mFocusedWindowHasCapture == enabled) { 15503787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev Slog.i(TAG, "requestPointerCapture: already " + (enabled ? "enabled" : "disabled")); 15513787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev return; 15523787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15533787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev setPointerCapture(enabled); 15543787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev try { 15553787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev mFocusedWindow.dispatchPointerCaptureChanged(enabled); 15563787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } catch (RemoteException ex) { 15573787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev /* ignore */ 15583787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15593787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15603787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev 15613787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev private void setPointerCapture(boolean enabled) { 15623787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev mFocusedWindowHasCapture = enabled; 15633787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev nativeSetPointerCapture(mPtr, enabled); 15643787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev } 15653787de16d24001eeb452e1c711d4290a396e67c9Vladislav Kaznacheev 1566349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown public void setInputDispatchMode(boolean enabled, boolean frozen) { 15674532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetInputDispatchMode(mPtr, enabled, frozen); 1568349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown } 156905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 157005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown public void setSystemUiVisibility(int visibility) { 15714532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetSystemUiVisibility(mPtr, visibility); 157205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 157305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 1574e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown /** 1575e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * Atomically transfers touch focus from one window to another as identified by 1576e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * their input channels. It is possible for multiple windows to have 1577e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * touch focus if they support split touch dispatch 1578e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * {@link android.view.WindowManager.LayoutParams#FLAG_SPLIT_TOUCH} but this 1579e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * method only transfers touch focus of the specified window without affecting 1580e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * other windows that may also have touch focus at the same time. 1581e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * @param fromChannel The channel of a window that currently has touch focus. 1582e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * @param toChannel The channel of the window that should receive touch focus in 1583e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * place of the first. 1584e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * @return True if the transfer was successful. False if the window with the 1585e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown * specified channel did not actually have touch focus at the time of the request. 1586e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown */ 1587e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown public boolean transferTouchFocus(InputChannel fromChannel, InputChannel toChannel) { 1588e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown if (fromChannel == null) { 1589e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown throw new IllegalArgumentException("fromChannel must not be null."); 1590e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown } 1591e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown if (toChannel == null) { 1592e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown throw new IllegalArgumentException("toChannel must not be null."); 1593e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown } 15944532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return nativeTransferTouchFocus(mPtr, fromChannel, toChannel); 1595e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown } 159605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 15979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown @Override // Binder call 1598ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown public void tryPointerSpeed(int speed) { 1599ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED, 1600ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown "tryPointerSpeed()")) { 1601ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown throw new SecurityException("Requires SET_POINTER_SPEED permission"); 1602ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 1603ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 16049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (speed < InputManager.MIN_POINTER_SPEED || speed > InputManager.MAX_POINTER_SPEED) { 16059f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown throw new IllegalArgumentException("speed out of range"); 16069f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 16079f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1608ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown setPointerSpeedUnchecked(speed); 16091a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 16101a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 16111a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown public void updatePointerSpeedFromSettings() { 1612ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = getPointerSpeedSetting(); 1613ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown setPointerSpeedUnchecked(speed); 1614ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 1615ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1616ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private void setPointerSpeedUnchecked(int speed) { 1617ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED), 1618ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown InputManager.MAX_POINTER_SPEED); 1619ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown nativeSetPointerSpeed(mPtr, speed); 16201a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 16211a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 16221a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown private void registerPointerSpeedSettingObserver() { 16231a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown mContext.getContentResolver().registerContentObserver( 16241a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown Settings.System.getUriFor(Settings.System.POINTER_SPEED), true, 16254532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown new ContentObserver(mHandler) { 16261a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown @Override 16271a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown public void onChange(boolean selfChange) { 16281a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown updatePointerSpeedFromSettings(); 16291a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 1630d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown }, UserHandle.USER_ALL); 16311a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 16321a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 1633ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private int getPointerSpeedSetting() { 1634ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown int speed = InputManager.DEFAULT_POINTER_SPEED; 16351a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown try { 1636d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown speed = Settings.System.getIntForUser(mContext.getContentResolver(), 1637d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown Settings.System.POINTER_SPEED, UserHandle.USER_CURRENT); 16381a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } catch (SettingNotFoundException snfe) { 16391a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 16401a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown return speed; 16411a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown } 16421a84fd1fb7a51f3fe4f8865e1cdd09f3490f696cJeff Brown 1643daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown public void updateShowTouchesFromSettings() { 1644daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown int setting = getShowTouchesSetting(0); 16454532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeSetShowTouches(mPtr, setting != 0); 1646daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } 1647daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown 1648daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown private void registerShowTouchesSettingObserver() { 1649daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown mContext.getContentResolver().registerContentObserver( 1650daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown Settings.System.getUriFor(Settings.System.SHOW_TOUCHES), true, 16514532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown new ContentObserver(mHandler) { 1652daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown @Override 1653daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown public void onChange(boolean selfChange) { 1654daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown updateShowTouchesFromSettings(); 1655daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } 1656d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown }, UserHandle.USER_ALL); 1657daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } 1658daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown 1659e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai public void updateAccessibilityLargePointerFromSettings() { 1660e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai final int accessibilityConfig = Settings.Secure.getIntForUser( 1661e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1662e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai 0, UserHandle.USER_CURRENT); 16631f3dbffa0c521d89bce9b43220b279760911bcb7Jun Mukai PointerIcon.setUseLargeIcons(accessibilityConfig == 1); 1664e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai nativeReloadPointerIcons(mPtr); 1665e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai } 1666e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai 166719a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai private void registerAccessibilityLargePointerSettingObserver() { 166819a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai mContext.getContentResolver().registerContentObserver( 166919a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON), true, 167019a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai new ContentObserver(mHandler) { 167119a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai @Override 167219a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai public void onChange(boolean selfChange) { 1673e4e75daa655c862a7d5ee62da4104b13e3f45bbdJun Mukai updateAccessibilityLargePointerFromSettings(); 167419a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai } 167519a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai }, UserHandle.USER_ALL); 167619a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai } 167719a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai 1678daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown private int getShowTouchesSetting(int defaultValue) { 1679daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown int result = defaultValue; 1680daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown try { 1681d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown result = Settings.System.getIntForUser(mContext.getContentResolver(), 1682d49359631bc2642be73dc162a8a73207df1e0bafJeff Brown Settings.System.SHOW_TOUCHES, UserHandle.USER_CURRENT); 1683daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } catch (SettingNotFoundException snfe) { 1684daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } 1685daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown return result; 1686daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown } 1687daf4a127ba2af82a3fb477044b872719a0ab1827Jeff Brown 1688a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown // Binder call 1689a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 1690a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void vibrate(int deviceId, long[] pattern, int repeat, IBinder token) { 1691a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (repeat >= pattern.length) { 1692a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new ArrayIndexOutOfBoundsException(); 1693a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1694a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1695a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown VibratorToken v; 1696a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown synchronized (mVibratorLock) { 1697a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown v = mVibratorTokens.get(token); 1698a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (v == null) { 1699a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown v = new VibratorToken(deviceId, token, mNextVibratorTokenValue++); 1700a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown try { 1701a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown token.linkToDeath(v, 0); 1702a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } catch (RemoteException ex) { 1703a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown // give up 1704a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown throw new RuntimeException(ex); 1705a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1706a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mVibratorTokens.put(token, v); 1707a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1708a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1709a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1710a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown synchronized (v) { 1711a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown v.mVibrating = true; 1712a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown nativeVibrate(mPtr, deviceId, pattern, repeat, v.mTokenValue); 1713a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1714a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1715a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1716a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown // Binder call 1717a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 1718a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void cancelVibrate(int deviceId, IBinder token) { 1719a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown VibratorToken v; 1720a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown synchronized (mVibratorLock) { 1721a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown v = mVibratorTokens.get(token); 1722a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (v == null || v.mDeviceId != deviceId) { 1723a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown return; // nothing to cancel 1724a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1725a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1726a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1727a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown cancelVibrateIfNeeded(v); 1728a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1729a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1730a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown void onVibratorTokenDied(VibratorToken v) { 1731a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown synchronized (mVibratorLock) { 1732a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mVibratorTokens.remove(v.mToken); 1733a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1734a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1735a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown cancelVibrateIfNeeded(v); 1736a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1737a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 1738a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private void cancelVibrateIfNeeded(VibratorToken v) { 1739a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown synchronized (v) { 1740a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (v.mVibrating) { 1741a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown nativeCancelVibrate(mPtr, v.mDeviceId, v.mTokenValue); 1742a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown v.mVibrating = false; 1743a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1744a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1745a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 1746a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 174719a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai // Binder call 174819a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai @Override 1749f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright public void setPointerIconType(int iconId) { 1750f9d9ce7705475874c82af04eb9b208a7fb556792Michael Wright nativeSetPointerIconType(mPtr, iconId); 175119a560197950425f7e1856d5bd1216fbc680bf70Jun Mukai } 17521db5397d88e722b1ab82ccb2b429ceec1179ccd8Jun Mukai 1753d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai // Binder call 1754d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai @Override 1755d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai public void setCustomPointerIcon(PointerIcon icon) { 1756b004b5137e12bffae9a3d3ae97440c8c24bdc07aMichael Wright Preconditions.checkNotNull(icon); 1757d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai nativeSetCustomPointerIcon(mPtr, icon); 1758d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai } 1759d4eaef7f4c5a5d281de4fff272cd33e892e26264Jun Mukai 17604532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown @Override 1761d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 1762fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkey if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 17634532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 17644532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown pw.println("INPUT MANAGER (dumpsys input)\n"); 17654532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown String dumpStr = nativeDump(mPtr); 1766e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown if (dumpStr != null) { 1767e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown pw.println(dumpStr); 1768e33348ba54cd68d6936cffd4507037c14d4b10c2Jeff Brown } 1769d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" Keyboard Layouts:"); 1770d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright visitAllKeyboardLayouts(new KeyboardLayoutVisitor() { 1771d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 1772d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void visitKeyboardLayout(Resources resources, 1773d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 1774d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" \"" + layout + "\": " + layout.getDescriptor()); 1775d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1776d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright }); 1777d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(); 1778d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright synchronized(mDataStore) { 1779d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright mDataStore.dump(pw, " "); 1780d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1781d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1782d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1783d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 1784d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void onShellCommand(FileDescriptor in, FileDescriptor out, 1785354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn FileDescriptor err, String[] args, ShellCallback callback, 1786354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn ResultReceiver resultReceiver) { 1787354736e196ff79962b3ddb52619a674044d773e2Dianne Hackborn (new Shell()).exec(this, in, out, err, args, callback, resultReceiver); 1788d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1789d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1790d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public int onShellCommand(Shell shell, String cmd) { 1791d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (TextUtils.isEmpty(cmd)) { 1792d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright shell.onHelp(); 1793d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return 1; 1794d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1795d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (cmd.equals("setlayout")) { 1796d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT, 1797d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright "onShellCommand()")) { 1798d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission"); 1799d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1800d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle( 1801d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright shell.getNextArgRequired(), Integer.parseInt(shell.getNextArgRequired())); 1802d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright String descriptor = shell.getNextArgRequired(); 1803d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright int vid = Integer.decode(shell.getNextArgRequired()); 1804d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright int pid = Integer.decode(shell.getNextArgRequired()); 1805d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright InputDeviceIdentifier id = new InputDeviceIdentifier(descriptor, vid, pid); 1806d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright setKeyboardLayoutForInputDeviceInner(id, handle, shell.getNextArgRequired()); 1807d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 1808d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return 0; 180946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 1810b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown 1811d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 1812ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown private boolean checkCallingPermission(String permission, String func) { 1813ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown // Quick check: if the calling permission is me, it's all okay. 1814ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (Binder.getCallingPid() == Process.myPid()) { 1815ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return true; 1816ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 1817ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 1818ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 1819ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return true; 1820ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 1821ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown String msg = "Permission Denial: " + func + " from pid=" 1822ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown + Binder.getCallingPid() 1823ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown + ", uid=" + Binder.getCallingUid() 1824ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown + " requires " + permission; 1825ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown Slog.w(TAG, msg); 1826ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown return false; 1827ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown } 1828ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown 18294532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection). 18302f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner @Override 183189ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown public void monitor() { 183289ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown synchronized (mInputFilterLock) { } 18334532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown nativeMonitor(mPtr); 183489ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown } 183589ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown 18364532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 18374532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private void notifyConfigurationChanged(long whenNanos) { 1838a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown mWindowManagerCallbacks.notifyConfigurationChanged(); 18394532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 18400029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 18414532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 1842af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private void notifyInputDevicesChanged(InputDevice[] inputDevices) { 1843af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown synchronized (mInputDevicesLock) { 1844af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (!mInputDevicesChangedPending) { 1845af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mInputDevicesChangedPending = true; 1846cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mHandler.obtainMessage(MSG_DELIVER_INPUT_DEVICES_CHANGED, 1847cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mInputDevices).sendToTarget(); 1848af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1849cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown 1850cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown mInputDevices = inputDevices; 1851af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1852af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 1853af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 1854af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown // Native callback. 1855bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown private void notifySwitch(long whenNanos, int switchValues, int switchMask) { 1856bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown if (DEBUG) { 1857bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown Slog.d(TAG, "notifySwitch: values=" + Integer.toHexString(switchValues) 1858bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown + ", mask=" + Integer.toHexString(switchMask)); 1859bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown } 1860bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown 18612f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner if ((switchMask & SW_LID_BIT) != 0) { 18622f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner final boolean lidOpen = ((switchValues & SW_LID_BIT) == 0); 1863bcc046af4ef171aa3aa3c6b64efb5cafc1e46cd3Jeff Brown mWindowManagerCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen); 18645338428ddbe662283bf88171c7ca361d51d78da8Jeff Brown } 18652f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 18663818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright if ((switchMask & SW_CAMERA_LENS_COVER_BIT) != 0) { 18679e10d25732518f3d5740b5ede88f43cb28f51a14Michael Wright final boolean lensCovered = ((switchValues & SW_CAMERA_LENS_COVER_BIT) != 0); 18683818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright mWindowManagerCallbacks.notifyCameraLensCoverSwitchChanged(whenNanos, lensCovered); 18693818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright } 18703818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright 18712f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner if (mUseDevInputEventForAudioJack && (switchMask & SW_JACK_BITS) != 0) { 18722f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner mWiredAccessoryCallbacks.notifyWiredAccessoryChanged(whenNanos, switchValues, 18732f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner switchMask); 18742f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner } 187539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 18769209c9cd9a6f779d0d9d86f9b2e368df564fa6bbMichael Wright if ((switchMask & SW_TABLET_MODE_BIT) != 0) { 187739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright SomeArgs args = SomeArgs.obtain(); 187839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.argi1 = (int) (whenNanos & 0xFFFFFFFF); 187939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.argi2 = (int) (whenNanos >> 32); 188039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args.arg1 = Boolean.valueOf((switchValues & SW_TABLET_MODE_BIT) != 0); 188139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mHandler.obtainMessage(MSG_DELIVER_TABLET_MODE_CHANGED, 188239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright args).sendToTarget(); 188339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 18844532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 18850029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 18864532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 18874532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) { 1888a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown mWindowManagerCallbacks.notifyInputChannelBroken(inputWindowHandle); 18894532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 18900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 18914532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 18924532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private long notifyANR(InputApplicationHandle inputApplicationHandle, 1893bd181bb83282571eb793d2e4a48b4d19585de7f2Jeff Brown InputWindowHandle inputWindowHandle, String reason) { 1894bd181bb83282571eb793d2e4a48b4d19585de7f2Jeff Brown return mWindowManagerCallbacks.notifyANR( 1895bd181bb83282571eb793d2e4a48b4d19585de7f2Jeff Brown inputApplicationHandle, inputWindowHandle, reason); 18964532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 18974532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 18984532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 18994532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown final boolean filterInputEvent(InputEvent event, int policyFlags) { 19004532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown synchronized (mInputFilterLock) { 19014532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown if (mInputFilter != null) { 1902c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov try { 1903c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov mInputFilter.filterInputEvent(event, policyFlags); 1904c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } catch (RemoteException e) { 1905c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov /* ignore */ 1906c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov } 19074532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return false; 19080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 19090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 19104532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown event.recycle(); 19114532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return true; 19120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown } 19130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 19144532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 1915037c33eae74bee2774897d969d48947f9abe254fJeff Brown private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { 1916037c33eae74bee2774897d969d48947f9abe254fJeff Brown return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags); 19174532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 19180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 19194532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 192070af00abf73160235d4efe114fcf4753007a8ff3Michael Wright private int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { 192170af00abf73160235d4efe114fcf4753007a8ff3Michael Wright return mWindowManagerCallbacks.interceptMotionBeforeQueueingNonInteractive( 19222687550272ba061448f5d5b914700dc335299ee7Jeff Brown whenNanos, policyFlags); 19234532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 19240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown 19254532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19264532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private long interceptKeyBeforeDispatching(InputWindowHandle focus, 19274532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown KeyEvent event, int policyFlags) { 1928a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags); 19294532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 193056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown 19314532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19324532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private KeyEvent dispatchUnhandledKey(InputWindowHandle focus, 19334532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown KeyEvent event, int policyFlags) { 1934a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown return mWindowManagerCallbacks.dispatchUnhandledKey(focus, event, policyFlags); 19354532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 193656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown 19374532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19384532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private boolean checkInjectEventsPermission(int injectorPid, int injectorUid) { 19394532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return mContext.checkPermission(android.Manifest.permission.INJECT_EVENTS, 19404532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown injectorPid, injectorUid) == PackageManager.PERMISSION_GRANTED; 19414532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1942fe50892af3b365806a767298dfd8e86447682581Jeff Brown 19434532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19444532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getVirtualKeyQuietTimeMillis() { 19454532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return mContext.getResources().getInteger( 19464532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown com.android.internal.R.integer.config_virtualKeyQuietTimeMillis); 19474532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1948fe50892af3b365806a767298dfd8e86447682581Jeff Brown 19494532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19504532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private String[] getExcludedDeviceNames() { 19514532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown ArrayList<String> names = new ArrayList<String>(); 19524532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 19534532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Read partner-provided list of excluded input devices 19544532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown XmlPullParser parser = null; 19554532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system". 19564532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown File confFile = new File(Environment.getRootDirectory(), EXCLUDED_DEVICES_PATH); 19574532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown FileReader confreader = null; 19584532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown try { 19594532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown confreader = new FileReader(confFile); 19604532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown parser = Xml.newPullParser(); 19614532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown parser.setInput(confreader); 19624532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown XmlUtils.beginDocument(parser, "devices"); 19634532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 19644532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown while (true) { 19654532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown XmlUtils.nextElement(parser); 19664532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown if (!"device".equals(parser.getName())) { 19674532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown break; 19684532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 19694532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown String name = parser.getAttributeValue(null, "name"); 19704532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown if (name != null) { 19714532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown names.add(name); 197246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 197346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 19744532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } catch (FileNotFoundException e) { 19754532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // It's ok if the file does not exist. 19764532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } catch (Exception e) { 19774532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown Slog.e(TAG, "Exception while parsing '" + confFile.getAbsolutePath() + "'", e); 19784532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } finally { 19794532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown try { if (confreader != null) confreader.close(); } catch (IOException e) { } 198046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 1981a454767b09ecb7d25d00beae0e5a1fdd48605c63Jeff Brown 19824532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return names.toArray(new String[names.size()]); 19834532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1984a454767b09ecb7d25d00beae0e5a1fdd48605c63Jeff Brown 19854532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19864532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getKeyRepeatTimeout() { 19874532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getKeyRepeatTimeout(); 19884532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1989a454767b09ecb7d25d00beae0e5a1fdd48605c63Jeff Brown 19904532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19914532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getKeyRepeatDelay() { 19924532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getKeyRepeatDelay(); 19934532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1994bb3fcba0caf697f1d238a2cbefdf1efe06eded99Jeff Brown 19954532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 19964532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getHoverTapTimeout() { 19974532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getHoverTapTimeout(); 19984532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 1999214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown 20004532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 20014532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getHoverTapSlop() { 20024532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getHoverTapSlop(); 20034532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 2004214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown 20054532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 20064532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getDoubleTapTimeout() { 20074532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getDoubleTapTimeout(); 20084532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 2009214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown 20104532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 20114532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getLongPressTimeout() { 20124532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return ViewConfiguration.getLongPressTimeout(); 20134532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 20144532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20154532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 20164532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private int getPointerLayer() { 2017a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown return mWindowManagerCallbacks.getPointerLayer(); 20184532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 20194532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20204532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown // Native callback. 20214532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private PointerIcon getPointerIcon() { 20224532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown return PointerIcon.getDefaultIcon(mContext); 20234532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 20244532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20256ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown // Native callback. 2026fb290df3c9a6f37ec050163029e25844de2f8590RoboErik private String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier) { 20276ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (!mSystemReady) { 20286ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return null; 20296ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20306ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 2031fb290df3c9a6f37ec050163029e25844de2f8590RoboErik String keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier); 20326ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (keyboardLayoutDescriptor == null) { 20336ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return null; 20346ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20356ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 20366ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown final String[] result = new String[2]; 20376ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() { 20386ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown @Override 20390748342d2ed264c01384fbaa4446a702a8824813Michael Wright public void visitKeyboardLayout(Resources resources, 20400748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout) { 20416ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown try { 20420748342d2ed264c01384fbaa4446a702a8824813Michael Wright result[0] = layout.getDescriptor(); 20436ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown result[1] = Streams.readFully(new InputStreamReader( 20442f0957607411b99810226ad38d59cf18718b86d0Jeff Brown resources.openRawResource(keyboardLayoutResId))); 20456ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } catch (IOException ex) { 20466ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } catch (NotFoundException ex) { 20476ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20486ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20496ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown }); 20506ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown if (result[0] == null) { 20510748342d2ed264c01384fbaa4446a702a8824813Michael Wright Slog.w(TAG, "Could not get keyboard layout with descriptor '" 20526ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown + keyboardLayoutDescriptor + "'."); 20536ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return null; 20546ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20556ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown return result; 20566ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 20576ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 20585bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown // Native callback. 20595bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown private String getDeviceAlias(String uniqueId) { 20609631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie if (BluetoothAdapter.checkBluetoothAddress(uniqueId)) { 20619631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie // TODO(BT) mBluetoothService.getRemoteAlias(uniqueId) 20629631314e3d28b6e96ef0b7cc777f1a7747a0ac39Matthew Xie return null; 20635bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown } 20645bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown return null; 20655bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown } 20665bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown 20674532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown /** 20684532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * Callback interface implemented by the Window Manager. 20694532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown */ 2070a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown public interface WindowManagerCallbacks { 20714532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public void notifyConfigurationChanged(); 20724532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20734532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen); 20744532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20753818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered); 20763818c9261ceaa3a700ff984fbcd245faeede38d7Michael Wright 20774532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle); 20784532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20794532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public long notifyANR(InputApplicationHandle inputApplicationHandle, 2080bd181bb83282571eb793d2e4a48b4d19585de7f2Jeff Brown InputWindowHandle inputWindowHandle, String reason); 20814532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 2082037c33eae74bee2774897d969d48947f9abe254fJeff Brown public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags); 20834532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 208470af00abf73160235d4efe114fcf4753007a8ff3Michael Wright public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags); 20854532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20864532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public long interceptKeyBeforeDispatching(InputWindowHandle focus, 20874532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown KeyEvent event, int policyFlags); 20884532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20894532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public KeyEvent dispatchUnhandledKey(InputWindowHandle focus, 20904532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown KeyEvent event, int policyFlags); 20914532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20924532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public int getPointerLayer(); 20934532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 20944532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 20954532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown /** 20962f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner * Callback interface implemented by WiredAccessoryObserver. 20972f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner */ 20982f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public interface WiredAccessoryCallbacks { 20992f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask); 21004a5eeb9c727d77bb57fef87a70c8c9cc23dbfee3Eric Laurent public void systemReady(); 21012f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner } 21022f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner 21032f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner /** 2104af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown * Private handler for the input manager. 2105af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown */ 2106af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputManagerHandler extends Handler { 2107a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown public InputManagerHandler(Looper looper) { 2108a9d131c30878cacdaeacb4f43a82a7cc5b872453Jeff Brown super(looper, null, true /*async*/); 2109a2910d0abbbe18ba1710dfd4a31af45769632255Jeff Brown } 2110a2910d0abbbe18ba1710dfd4a31af45769632255Jeff Brown 2111af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 2112af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void handleMessage(Message msg) { 2113af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown switch (msg.what) { 2114af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown case MSG_DELIVER_INPUT_DEVICES_CHANGED: 2115cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown deliverInputDevicesChanged((InputDevice[])msg.obj); 2116cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown break; 2117d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright case MSG_SWITCH_KEYBOARD_LAYOUT: { 2118d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright SomeArgs args = (SomeArgs)msg.obj; 2119d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright handleSwitchKeyboardLayout((InputDeviceIdentifier)args.arg1, 2120d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright (InputMethodSubtypeHandle)args.arg2); 2121cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown break; 2122d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 2123cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown case MSG_RELOAD_KEYBOARD_LAYOUTS: 2124cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown reloadKeyboardLayouts(); 2125cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown break; 2126cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown case MSG_UPDATE_KEYBOARD_LAYOUTS: 2127cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown updateKeyboardLayouts(); 2128cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown break; 2129cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown case MSG_RELOAD_DEVICE_ALIASES: 2130cf39bdf3dff5e29447f6ce734b76dc3490385e58Jeff Brown reloadDeviceAliases(); 2131af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown break; 2132b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa case MSG_DELIVER_TABLET_MODE_CHANGED: { 213339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright SomeArgs args = (SomeArgs) msg.obj; 213439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright long whenNanos = (args.argi1 & 0xFFFFFFFFl) | ((long) args.argi2 << 32); 213539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright boolean inTabletMode = (boolean) args.arg1; 213639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright deliverTabletModeChanged(whenNanos, inTabletMode); 213739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright break; 2138b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa } 2139b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa case MSG_INPUT_METHOD_SUBTYPE_CHANGED: { 2140b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa final int userId = msg.arg1; 2141b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa final SomeArgs args = (SomeArgs) msg.obj; 2142b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa final InputMethodInfo inputMethodInfo = (InputMethodInfo) args.arg1; 2143b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa final InputMethodSubtype subtype = (InputMethodSubtype) args.arg2; 2144b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa args.recycle(); 2145b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa handleSwitchInputMethodSubtype(userId, inputMethodInfo, subtype); 2146b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa break; 2147b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa } 2148af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2149af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2150af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2151af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 2152af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown /** 21534532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown * Hosting interface for input filters to call back into the input manager. 21544532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown */ 2155c9c9a48e7bafae63cb35a9aa69255e80aba83988Svetoslav Ganov private final class InputFilterHost extends IInputFilterHost.Stub { 21564532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown private boolean mDisconnected; 21574532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 21584532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public void disconnectLocked() { 21594532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown mDisconnected = true; 216083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown } 2161b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown 21622f39e9f8333183312b7f7d423c2ea60a93a25e32Craig Mautner @Override 21634532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown public void sendInputEvent(InputEvent event, int policyFlags) { 21644532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown if (event == null) { 21654532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown throw new IllegalArgumentException("event must not be null"); 21664532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 21674532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown 21684532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown synchronized (mInputFilterLock) { 21694532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown if (!mDisconnected) { 2170ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown nativeInjectInputEvent(mPtr, event, Display.DEFAULT_DISPLAY, 0, 0, 2171ac14351e16e1258f1cb54e2bf772b8be004eb2b8Jeff Brown InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0, 21724532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown policyFlags | WindowManagerPolicy.FLAG_FILTERED); 21734532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 21744532e6158474a263d9d26c2b42240bcf7ce9b172Jeff Brown } 2175b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown } 217646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown } 21779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 21789f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown private static final class KeyboardLayoutDescriptor { 21799f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public String packageName; 21809f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public String receiverName; 21819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public String keyboardLayoutName; 21829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 21839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public static String format(String packageName, 21849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String receiverName, String keyboardName) { 21859f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return packageName + "/" + receiverName + "/" + keyboardName; 21869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 21879f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 21889f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown public static KeyboardLayoutDescriptor parse(String descriptor) { 21899f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown int pos = descriptor.indexOf('/'); 21909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (pos < 0 || pos + 1 == descriptor.length()) { 21919f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return null; 21929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 21939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown int pos2 = descriptor.indexOf('/', pos + 1); 21949f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (pos2 < pos + 2 || pos2 + 1 == descriptor.length()) { 21959f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return null; 21969f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 21979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 21989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown KeyboardLayoutDescriptor result = new KeyboardLayoutDescriptor(); 21999f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown result.packageName = descriptor.substring(0, pos); 22009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown result.receiverName = descriptor.substring(pos + 1, pos2); 22019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown result.keyboardLayoutName = descriptor.substring(pos2 + 1); 22029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return result; 22039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 22049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 2205af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 22066ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown private interface KeyboardLayoutVisitor { 22070748342d2ed264c01384fbaa4446a702a8824813Michael Wright void visitKeyboardLayout(Resources resources, 22080748342d2ed264c01384fbaa4446a702a8824813Michael Wright int keyboardLayoutResId, KeyboardLayout layout); 22096ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown } 22106ec6f79e1ac1714e3b837796e99f07ff88f66601Jeff Brown 2211af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final class InputDevicesChangedListenerRecord implements DeathRecipient { 2212af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final int mPid; 2213af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown private final IInputDevicesChangedListener mListener; 2214af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 2215af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public InputDevicesChangedListenerRecord(int pid, IInputDevicesChangedListener listener) { 2216af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mPid = pid; 2217af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener = listener; 2218af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2219af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 2220af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown @Override 2221af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void binderDied() { 2222af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown if (DEBUG) { 2223af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Slog.d(TAG, "Input devices changed listener for pid " + mPid + " died."); 2224af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2225af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown onInputDevicesChangedListenerDied(mPid); 2226af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2227af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown 2228af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown public void notifyInputDevicesChanged(int[] info) { 2229af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown try { 2230af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mListener.onInputDevicesChanged(info); 2231af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } catch (RemoteException ex) { 2232af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown Slog.w(TAG, "Failed to notify process " 2233af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown + mPid + " that input devices changed, assuming it died.", ex); 2234af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown binderDied(); 2235af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2236af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2237af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown } 2238a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 223939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final class TabletModeChangedListenerRecord implements DeathRecipient { 224039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final int mPid; 224139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright private final ITabletModeChangedListener mListener; 224239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 224339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public TabletModeChangedListenerRecord(int pid, ITabletModeChangedListener listener) { 224439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mPid = pid; 224539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mListener = listener; 224639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 224739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 224839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright @Override 224939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void binderDied() { 225039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright if (DEBUG) { 225139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright Slog.d(TAG, "Tablet mode changed listener for pid " + mPid + " died."); 225239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 225339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright onTabletModeChangedListenerDied(mPid); 225439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 225539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 225639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright public void notifyTabletModeChanged(long whenNanos, boolean inTabletMode) { 225739e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright try { 225839e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright mListener.onTabletModeChanged(whenNanos, inTabletMode); 225939e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } catch (RemoteException ex) { 226039e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright Slog.w(TAG, "Failed to notify process " + mPid + 226139e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright " that tablet mode changed, assuming it died.", ex); 226239e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright binderDied(); 226339e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 226439e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 226539e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright } 226639e5e947447bc611205404ae6a4690656f1aa0f9Michael Wright 2267a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown private final class VibratorToken implements DeathRecipient { 2268a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public final int mDeviceId; 2269a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public final IBinder mToken; 2270a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public final int mTokenValue; 2271a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 2272a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public boolean mVibrating; 2273a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 2274a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public VibratorToken(int deviceId, IBinder token, int tokenValue) { 2275a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mDeviceId = deviceId; 2276a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mToken = token; 2277a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mTokenValue = tokenValue; 2278a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 2279a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown 2280a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown @Override 2281a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown public void binderDied() { 2282a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown if (DEBUG) { 2283a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown Slog.d(TAG, "Vibrator token died."); 2284a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 2285a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown onVibratorTokenDied(this); 2286a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 2287a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown } 22884ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown 2289d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright private class Shell extends ShellCommand { 2290d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 2291d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public int onCommand(String cmd) { 2292d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright return onShellCommand(this, cmd); 2293d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 2294d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 2295d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright @Override 2296d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright public void onHelp() { 2297d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright final PrintWriter pw = getOutPrintWriter(); 2298d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println("Input manager commands:"); 2299d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" help"); 2300d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" Print this help text."); 2301d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(""); 2302d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" setlayout IME_ID IME_SUPTYPE_HASH_CODE" 2303d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright + " DEVICE_DESCRIPTOR VENDOR_ID PRODUCT_ID KEYBOARD_DESCRIPTOR"); 2304d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright pw.println(" Sets a keyboard layout for a given IME subtype and input device pair"); 2305d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 2306d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright } 2307d5f7ed9fe9dc3590f6ef9cb7470e29e836a95907Michael Wright 23084ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown private final class LocalService extends InputManagerInternal { 23094ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown @Override 2310b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon public void setDisplayViewports(DisplayViewport defaultViewport, 2311b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon DisplayViewport externalTouchViewport, 2312b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon List<DisplayViewport> virtualTouchViewports) { 2313b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon setDisplayViewportsInternal(defaultViewport, externalTouchViewport, 2314b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon virtualTouchViewports); 23154ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown } 2316ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown 2317ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown @Override 2318ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown public boolean injectInputEvent(InputEvent event, int displayId, int mode) { 2319ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown return injectInputEventInternal(event, displayId, mode); 2320ca9bc702df5c14a89c9b8b0109a05894bf74962eJeff Brown } 2321037c33eae74bee2774897d969d48947f9abe254fJeff Brown 2322037c33eae74bee2774897d969d48947f9abe254fJeff Brown @Override 2323037c33eae74bee2774897d969d48947f9abe254fJeff Brown public void setInteractive(boolean interactive) { 2324037c33eae74bee2774897d969d48947f9abe254fJeff Brown nativeSetInteractive(mPtr, interactive); 2325037c33eae74bee2774897d969d48947f9abe254fJeff Brown } 2326b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa 2327b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa @Override 2328b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa public void onInputMethodSubtypeChanged(int userId, 2329b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa @Nullable InputMethodInfo inputMethodInfo, @Nullable InputMethodSubtype subtype) { 2330b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa final SomeArgs someArgs = SomeArgs.obtain(); 2331b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa someArgs.arg1 = inputMethodInfo; 2332b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa someArgs.arg2 = subtype; 2333b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa mHandler.obtainMessage(MSG_INPUT_METHOD_SUBTYPE_CHANGED, userId, 0, someArgs) 2334b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa .sendToTarget(); 2335b097b8262ba22040d46d6e212a31b758b7023307Yohei Yukawa } 2336112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian 2337112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian @Override 2338112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian public void toggleCapsLock(int deviceId) { 2339112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian nativeToggleCapsLock(mPtr, deviceId); 2340112d05678b7de53da8948f62dd2e968274f62244Andrii Kulian } 23419918234dcf9e115560144d0218682dd5050843bcAdrian Roos 23429918234dcf9e115560144d0218682dd5050843bcAdrian Roos @Override 23439918234dcf9e115560144d0218682dd5050843bcAdrian Roos public void setPulseGestureEnabled(boolean enabled) { 23449918234dcf9e115560144d0218682dd5050843bcAdrian Roos if (mDoubleTouchGestureEnableFile != null) { 23459918234dcf9e115560144d0218682dd5050843bcAdrian Roos FileWriter writer = null; 23469918234dcf9e115560144d0218682dd5050843bcAdrian Roos try { 23479918234dcf9e115560144d0218682dd5050843bcAdrian Roos writer = new FileWriter(mDoubleTouchGestureEnableFile); 23489918234dcf9e115560144d0218682dd5050843bcAdrian Roos writer.write(enabled ? "1" : "0"); 23499918234dcf9e115560144d0218682dd5050843bcAdrian Roos } catch (IOException e) { 23509918234dcf9e115560144d0218682dd5050843bcAdrian Roos Log.wtf(TAG, "Unable to setPulseGestureEnabled", e); 23519918234dcf9e115560144d0218682dd5050843bcAdrian Roos } finally { 23529918234dcf9e115560144d0218682dd5050843bcAdrian Roos IoUtils.closeQuietly(writer); 23539918234dcf9e115560144d0218682dd5050843bcAdrian Roos } 23549918234dcf9e115560144d0218682dd5050843bcAdrian Roos } 23559918234dcf9e115560144d0218682dd5050843bcAdrian Roos } 23564ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown } 235746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 2358