diff options
-rw-r--r-- | core/java/android/bluetooth/BluetoothDevice.java | 12 | ||||
-rw-r--r-- | core/java/android/server/BluetoothEventLoop.java | 4 | ||||
-rw-r--r-- | core/jni/android_view_InputDevice.cpp | 4 | ||||
-rw-r--r-- | include/androidfw/InputDevice.h | 15 | ||||
-rw-r--r-- | libs/androidfw/InputDevice.cpp | 11 | ||||
-rw-r--r-- | services/input/InputReader.cpp | 14 | ||||
-rw-r--r-- | services/input/InputReader.h | 7 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 12 | ||||
-rw-r--r-- | services/java/com/android/server/SystemServer.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/input/InputManagerService.java | 36 | ||||
-rw-r--r-- | services/jni/com_android_server_input_InputManagerService.cpp | 39 |
11 files changed, 127 insertions, 30 deletions
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java index 04af5f7..56e1735 100644 --- a/core/java/android/bluetooth/BluetoothDevice.java +++ b/core/java/android/bluetooth/BluetoothDevice.java @@ -160,6 +160,18 @@ public final class BluetoothDevice implements Parcelable { "android.bluetooth.device.action.NAME_CHANGED"; /** + * Broadcast Action: Indicates the alias of a remote device has been + * changed. + * <p>Always contains the extra field {@link #EXTRA_DEVICE}. + * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive. + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ALIAS_CHANGED = + "android.bluetooth.device.action.ALIAS_CHANGED"; + + /** * Broadcast Action: Indicates a change in the bond state of a remote * device. For example, if a device is bonded (paired). * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java index a2038c9..9c887a1 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -405,6 +405,10 @@ class BluetoothEventLoop { mContext.sendBroadcast(intent, BLUETOOTH_PERM); } else if (name.equals("Alias")) { mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]); + Intent intent = new Intent(BluetoothDevice.ACTION_ALIAS_CHANGED); + intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mContext.sendBroadcast(intent, BLUETOOTH_PERM); } else if (name.equals("Class")) { mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]); Intent intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED); diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp index 5cb172b..d1f0a6a 100644 --- a/core/jni/android_view_InputDevice.cpp +++ b/core/jni/android_view_InputDevice.cpp @@ -35,13 +35,13 @@ static struct { } gInputDeviceClassInfo; jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& deviceInfo) { - ScopedLocalRef<jstring> nameObj(env, env->NewStringUTF(deviceInfo.getName().string())); + ScopedLocalRef<jstring> nameObj(env, env->NewStringUTF(deviceInfo.getDisplayName().string())); if (!nameObj.get()) { return NULL; } ScopedLocalRef<jstring> descriptorObj(env, - env->NewStringUTF(deviceInfo.getDescriptor().string())); + env->NewStringUTF(deviceInfo.getIdentifier().descriptor.string())); if (!descriptorObj.get()) { return NULL; } diff --git a/include/androidfw/InputDevice.h b/include/androidfw/InputDevice.h index 38203af..d6ecbf0 100644 --- a/include/androidfw/InputDevice.h +++ b/include/androidfw/InputDevice.h @@ -66,13 +66,16 @@ public: float fuzz; }; - void initialize(int32_t id, int32_t generation, - const String8& name, const String8& descriptor); + void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier, + const String8& alias); inline int32_t getId() const { return mId; } inline int32_t getGeneration() const { return mGeneration; } - inline const String8 getName() const { return mName; } - inline const String8 getDescriptor() const { return mDescriptor; } + inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; } + inline const String8& getAlias() const { return mAlias; } + inline const String8& getDisplayName() const { + return mAlias.isEmpty() ? mIdentifier.name : mAlias; + } inline uint32_t getSources() const { return mSources; } const MotionRange* getMotionRange(int32_t axis, uint32_t source) const; @@ -103,8 +106,8 @@ public: private: int32_t mId; int32_t mGeneration; - String8 mName; - String8 mDescriptor; + InputDeviceIdentifier mIdentifier; + String8 mAlias; uint32_t mSources; int32_t mKeyboardType; sp<KeyCharacterMap> mKeyCharacterMap; diff --git a/libs/androidfw/InputDevice.cpp b/libs/androidfw/InputDevice.cpp index d6c49f7..5237063 100644 --- a/libs/androidfw/InputDevice.cpp +++ b/libs/androidfw/InputDevice.cpp @@ -127,12 +127,11 @@ String8 getInputDeviceConfigurationFilePathByName( // --- InputDeviceInfo --- InputDeviceInfo::InputDeviceInfo() { - initialize(-1, -1, String8("uninitialized device info"), String8("unknown")); + initialize(-1, -1, InputDeviceIdentifier(), String8()); } InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : - mId(other.mId), mGeneration(other.mGeneration), - mName(other.mName), mDescriptor(other.mDescriptor), + mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier), mSources(other.mSources), mKeyboardType(other.mKeyboardType), mKeyCharacterMap(other.mKeyCharacterMap), @@ -144,11 +143,11 @@ InputDeviceInfo::~InputDeviceInfo() { } void InputDeviceInfo::initialize(int32_t id, int32_t generation, - const String8& name, const String8& descriptor) { + const InputDeviceIdentifier& identifier, const String8& alias) { mId = id; mGeneration = generation; - mName = name; - mDescriptor = descriptor; + mIdentifier = identifier; + mAlias = alias; mSources = 0; mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; mHasVibrator = false; diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 3a48b16..6022f10 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -918,7 +918,7 @@ void InputDevice::dump(String8& dump) { getDeviceInfo(& deviceInfo); dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(), - deviceInfo.getName().string()); + deviceInfo.getDisplayName().string()); dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration); dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); @@ -972,6 +972,16 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config } } + if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) { + if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) { + String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier); + if (mAlias != alias) { + mAlias = alias; + bumpGeneration(); + } + } + } + size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { InputMapper* mapper = mMappers[i]; @@ -1039,7 +1049,7 @@ void InputDevice::timeoutExpired(nsecs_t when) { } void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { - outDeviceInfo->initialize(mId, mGeneration, mIdentifier.name, mIdentifier.descriptor); + outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias); size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { diff --git a/services/input/InputReader.h b/services/input/InputReader.h index acdec85..8257dbc 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -70,6 +70,9 @@ struct InputReaderConfiguration { // The keyboard layouts must be reloaded. CHANGE_KEYBOARD_LAYOUTS = 1 << 4, + // The device name alias supplied by the may have changed for some devices. + CHANGE_DEVICE_ALIAS = 1 << 5, + // All devices must be reopened. CHANGE_MUST_REOPEN = 1 << 31, }; @@ -228,6 +231,9 @@ public: /* Gets the keyboard layout for a particular input device. */ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) = 0; + + /* Gets a user-supplied alias for a particular input device, or an empty string if none. */ + virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0; }; @@ -528,6 +534,7 @@ private: int32_t mId; int32_t mGeneration; InputDeviceIdentifier mIdentifier; + String8 mAlias; uint32_t mClasses; Vector<InputMapper*> mMappers; diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index a4b7585..0f755ae 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -174,6 +174,10 @@ private: virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) { return NULL; } + + virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) { + return String8::empty(); + } }; @@ -1081,7 +1085,7 @@ TEST_F(InputReaderTest, GetInputDevices) { ASSERT_EQ(1U, inputDevices.size()); ASSERT_EQ(1, inputDevices[0].getId()); - ASSERT_STREQ("keyboard", inputDevices[0].getName().string()); + ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string()); ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType()); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources()); ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size()); @@ -1090,7 +1094,7 @@ TEST_F(InputReaderTest, GetInputDevices) { inputDevices = mFakePolicy->getInputDevices(); ASSERT_EQ(1U, inputDevices.size()); ASSERT_EQ(1, inputDevices[0].getId()); - ASSERT_STREQ("keyboard", inputDevices[0].getName().string()); + ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string()); ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType()); ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources()); ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size()); @@ -1311,7 +1315,7 @@ TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) { InputDeviceInfo info; mDevice->getDeviceInfo(&info); ASSERT_EQ(DEVICE_ID, info.getId()); - ASSERT_STREQ(DEVICE_NAME, info.getName().string()); + ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string()); ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType()); ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources()); @@ -1381,7 +1385,7 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe InputDeviceInfo info; mDevice->getDeviceInfo(&info); ASSERT_EQ(DEVICE_ID, info.getId()); - ASSERT_STREQ(DEVICE_NAME, info.getName().string()); + ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string()); ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType()); ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources()); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 02c4d5a..729c3f3 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -726,6 +726,7 @@ class ServerThread extends Thread { final StatusBarManagerService statusBarF = statusBar; final DreamManagerService dreamyF = dreamy; final InputManagerService inputManagerF = inputManager; + final BluetoothService bluetoothF = bluetooth; // We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state @@ -838,7 +839,7 @@ class ServerThread extends Thread { reportWtf("making DreamManagerService ready", e); } try { - if (inputManagerF != null) inputManagerF.systemReady(); + if (inputManagerF != null) inputManagerF.systemReady(bluetoothF); } catch (Throwable e) { reportWtf("making InputManagerService ready", e); } diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java index a4ed31c..189a9c7 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/java/com/android/server/input/InputManagerService.java @@ -26,6 +26,8 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import android.Manifest; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -56,6 +58,7 @@ import android.os.Process; import android.os.RemoteException; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; +import android.server.BluetoothService; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -106,6 +109,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. private final Callbacks mCallbacks; private final InputManagerHandler mHandler; private boolean mSystemReady; + private BluetoothService mBluetoothService; // Persistent data store. Must be locked each time during use. private final PersistentDataStore mDataStore = new PersistentDataStore(); @@ -167,6 +171,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. int repeat, int token); private static native void nativeCancelVibrate(int ptr, int deviceId, int token); private static native void nativeReloadKeyboardLayouts(int ptr); + private static native void nativeReloadDeviceAliases(int ptr); private static native String nativeDump(int ptr); private static native void nativeMonitor(int ptr); @@ -217,12 +222,12 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. updateShowTouchesFromSettings(); } - public void systemReady() { + public void systemReady(BluetoothService bluetoothService) { if (DEBUG) { Slog.d(TAG, "System ready."); } + mBluetoothService = bluetoothService; mSystemReady = true; - reloadKeyboardLayouts(); IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); filter.addAction(Intent.ACTION_PACKAGE_REMOVED); @@ -237,12 +242,30 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. reloadKeyboardLayouts(); } }, filter, null, mHandler); + + filter = new IntentFilter(BluetoothDevice.ACTION_ALIAS_CHANGED); + mContext.registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (DEBUG) { + Slog.d(TAG, "Bluetooth alias changed, reloading device names."); + } + reloadDeviceAliases(); + } + }, filter, null, mHandler); + + reloadKeyboardLayouts(); + reloadDeviceAliases(); } private void reloadKeyboardLayouts() { nativeReloadKeyboardLayouts(mPtr); } + private void reloadDeviceAliases() { + nativeReloadDeviceAliases(mPtr); + } + public void setDisplaySize(int displayId, int width, int height, int externalWidth, int externalHeight) { if (width <= 0 || height <= 0 || externalWidth <= 0 || externalHeight <= 0) { @@ -1121,6 +1144,15 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog. return result; } + // Native callback. + private String getDeviceAlias(String uniqueId) { + if (mBluetoothService != null && + BluetoothAdapter.checkBluetoothAddress(uniqueId)) { + return mBluetoothService.getRemoteAlias(uniqueId); + } + return null; + } + /** * Callback interface implemented by the Window Manager. diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp index b361a26..b2a2429 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/jni/com_android_server_input_InputManagerService.cpp @@ -83,6 +83,7 @@ static struct { jmethodID getPointerLayer; jmethodID getPointerIcon; jmethodID getKeyboardLayoutOverlay; + jmethodID getDeviceAlias; } gServiceClassInfo; static struct { @@ -183,7 +184,6 @@ public: void setSystemUiVisibility(int32_t visibility); void setPointerSpeed(int32_t speed); void setShowTouches(bool enabled); - void reloadKeyboardLayouts(); /* --- InputReaderPolicyInterface implementation --- */ @@ -191,6 +191,7 @@ public: virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId); virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices); virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor); + virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier); /* --- InputDispatcherPolicyInterface implementation --- */ @@ -551,6 +552,21 @@ sp<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay( return result; } +String8 NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) { + JNIEnv* env = jniEnv(); + + ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.string())); + ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj, + gServiceClassInfo.getDeviceAlias, uniqueIdObj.get()))); + String8 result; + if (aliasObj.get()) { + ScopedUtfChars aliasChars(env, aliasObj.get()); + result.setTo(aliasChars.c_str()); + } + checkAndClearExceptionFromCallback(env, "getDeviceAlias"); + return result; +} + void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue, uint32_t policyFlags) { #if DEBUG_INPUT_DISPATCHER_POLICY @@ -757,11 +773,6 @@ void NativeInputManager::setShowTouches(bool enabled) { InputReaderConfiguration::CHANGE_SHOW_TOUCHES); } -void NativeInputManager::reloadKeyboardLayouts() { - mInputManager->getReader()->requestRefreshConfiguration( - InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS); -} - bool NativeInputManager::isScreenOn() { return android_server_PowerManagerService_isScreenOn(); } @@ -1296,7 +1307,16 @@ static void nativeReloadKeyboardLayouts(JNIEnv* env, jclass clazz, jint ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); - im->reloadKeyboardLayouts(); + im->getInputManager()->getReader()->requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS); +} + +static void nativeReloadDeviceAliases(JNIEnv* env, + jclass clazz, jint ptr) { + NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + + im->getInputManager()->getReader()->requestRefreshConfiguration( + InputReaderConfiguration::CHANGE_DEVICE_ALIAS); } static jstring nativeDump(JNIEnv* env, jclass clazz, jint ptr) { @@ -1366,6 +1386,8 @@ static JNINativeMethod gInputManagerMethods[] = { (void*) nativeCancelVibrate }, { "nativeReloadKeyboardLayouts", "(I)V", (void*) nativeReloadKeyboardLayouts }, + { "nativeReloadDeviceAliases", "(I)V", + (void*) nativeReloadDeviceAliases }, { "nativeDump", "(I)Ljava/lang/String;", (void*) nativeDump }, { "nativeMonitor", "(I)V", @@ -1464,6 +1486,9 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz, "getKeyboardLayoutOverlay", "(Ljava/lang/String;)[Ljava/lang/String;"); + GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz, + "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;"); + // InputDevice FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice"); |