diff options
author | Jeff Brown <jeffbrown@google.com> | 2010-11-29 17:37:49 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2010-11-30 17:15:49 -0800 |
commit | 47e6b1b5eef8ee99872f278f66bc498c4fcca0d8 (patch) | |
tree | ef5a7c87b8dca433ea9707c1289ae7c8d2ba3787 | |
parent | 735206f121cb2a11b3397870e6565178627e0aa3 (diff) | |
download | frameworks_base-47e6b1b5eef8ee99872f278f66bc498c4fcca0d8.zip frameworks_base-47e6b1b5eef8ee99872f278f66bc498c4fcca0d8.tar.gz frameworks_base-47e6b1b5eef8ee99872f278f66bc498c4fcca0d8.tar.bz2 |
Support non-orientation aware keyboards and other devices.
Fixed a bug with dpad keys on external keyboards being rotated
according to the display orientation by adding a new input device
configuration property called "keyboard.orientationAware".
Added a mechanism for overriding the key layout and key character
map in the input device configuration file using the new
"keyboard.layout" and "keyboard.characterMap" properties.
Also added "trackball.orientationAware", "touch.orientationAware" and
"touch.deviceType" configuration properties.
Rewrote the configuration property reading code in native code
so that it can be used by EventHub and other components.
Added basic support for installable idc, kl, and kcm files
in /data/system/devices. However, there is no provision for
copying files there yet.
Disabled long-press character pickers on full keyboards so that
key repeating works as expected.
Change-Id: I1bd9f0c3d344421db444e7d271eb09bc8bab4791
-rw-r--r-- | api/current.xml | 17 | ||||
-rw-r--r-- | core/java/android/text/method/QwertyKeyListener.java | 52 | ||||
-rw-r--r-- | core/java/android/text/method/TextKeyListener.java | 7 | ||||
-rw-r--r-- | data/keyboards/Apple_Wireless_Keyboard.kl | 2 | ||||
-rw-r--r-- | data/keyboards/Logitech_USB_Receiver.kl | 2 | ||||
-rw-r--r-- | data/keyboards/qwerty.kcm | 4 | ||||
-rw-r--r-- | include/ui/EventHub.h | 8 | ||||
-rw-r--r-- | include/ui/Input.h | 18 | ||||
-rw-r--r-- | include/ui/InputReader.h | 72 | ||||
-rw-r--r-- | include/ui/Keyboard.h | 9 | ||||
-rw-r--r-- | include/utils/PropertyMap.h | 100 | ||||
-rw-r--r-- | libs/ui/EventHub.cpp | 47 | ||||
-rw-r--r-- | libs/ui/Input.cpp | 79 | ||||
-rw-r--r-- | libs/ui/InputReader.cpp | 229 | ||||
-rw-r--r-- | libs/ui/Keyboard.cpp | 137 | ||||
-rw-r--r-- | libs/ui/tests/InputReader_test.cpp | 213 | ||||
-rw-r--r-- | libs/utils/Android.mk | 1 | ||||
-rw-r--r-- | libs/utils/PropertyMap.cpp | 212 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java | 7 | ||||
-rw-r--r-- | services/java/com/android/server/InputManager.java | 33 | ||||
-rw-r--r-- | services/jni/com_android_server_InputManager.cpp | 67 |
21 files changed, 878 insertions, 438 deletions
diff --git a/api/current.xml b/api/current.xml index a8193d7..a98c8b6 100644 --- a/api/current.xml +++ b/api/current.xml @@ -185610,7 +185610,7 @@ > <parameter name="cap" type="android.text.method.TextKeyListener.Capitalize"> </parameter> -<parameter name="autotext" type="boolean"> +<parameter name="autoText" type="boolean"> </parameter> </constructor> <method name="getInputType" @@ -185634,11 +185634,22 @@ deprecated="not deprecated" visibility="public" > -<parameter name="autotext" type="boolean"> +<parameter name="autoText" type="boolean"> </parameter> <parameter name="cap" type="android.text.method.TextKeyListener.Capitalize"> </parameter> </method> +<method name="getInstanceForFullKeyboard" + return="android.text.method.QwertyKeyListener" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="markAsReplaced" return="void" abstract="false" @@ -249324,7 +249335,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="t" type="T"> +<parameter name="arg0" type="T"> </parameter> </method> </interface> diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java index 3308172..09388c0 100644 --- a/core/java/android/text/method/QwertyKeyListener.java +++ b/core/java/android/text/method/QwertyKeyListener.java @@ -31,27 +31,48 @@ import android.view.View; public class QwertyKeyListener extends BaseKeyListener { private static QwertyKeyListener[] sInstance = new QwertyKeyListener[Capitalize.values().length * 2]; + private static QwertyKeyListener sFullKeyboardInstance; - public QwertyKeyListener(Capitalize cap, boolean autotext) { + private Capitalize mAutoCap; + private boolean mAutoText; + private boolean mFullKeyboard; + + private QwertyKeyListener(Capitalize cap, boolean autoText, boolean fullKeyboard) { mAutoCap = cap; - mAutoText = autotext; + mAutoText = autoText; + mFullKeyboard = fullKeyboard; + } + + public QwertyKeyListener(Capitalize cap, boolean autoText) { + this(cap, autoText, false); } /** * Returns a new or existing instance with the specified capitalization * and correction properties. */ - public static QwertyKeyListener getInstance(boolean autotext, - Capitalize cap) { - int off = cap.ordinal() * 2 + (autotext ? 1 : 0); + public static QwertyKeyListener getInstance(boolean autoText, Capitalize cap) { + int off = cap.ordinal() * 2 + (autoText ? 1 : 0); if (sInstance[off] == null) { - sInstance[off] = new QwertyKeyListener(cap, autotext); + sInstance[off] = new QwertyKeyListener(cap, autoText); } return sInstance[off]; } + /** + * Gets an instance of the listener suitable for use with full keyboards. + * Disables auto-capitalization, auto-text and long-press initiated on-screen + * character pickers. + */ + public static QwertyKeyListener getInstanceForFullKeyboard() { + if (sFullKeyboardInstance == null) { + sFullKeyboardInstance = new QwertyKeyListener(Capitalize.NONE, false, true); + } + return sFullKeyboardInstance; + } + public int getInputType() { return makeTextContentType(mAutoCap, mAutoText); } @@ -85,14 +106,16 @@ public class QwertyKeyListener extends BaseKeyListener { int i = event.getUnicodeChar(event.getMetaState() | getMetaState(content)); - int count = event.getRepeatCount(); - if (count > 0 && selStart == selEnd && selStart > 0) { - char c = content.charAt(selStart - 1); + if (!mFullKeyboard) { + int count = event.getRepeatCount(); + if (count > 0 && selStart == selEnd && selStart > 0) { + char c = content.charAt(selStart - 1); - if (c == i || c == Character.toUpperCase(i) && view != null) { - if (showCharacterPicker(view, content, c, false, count)) { - resetMetaState(content); - return true; + if (c == i || c == Character.toUpperCase(i) && view != null) { + if (showCharacterPicker(view, content, c, false, count)) { + resetMetaState(content); + return true; + } } } } @@ -490,8 +513,5 @@ public class QwertyKeyListener extends BaseKeyListener { private char[] mText; } - - private Capitalize mAutoCap; - private boolean mAutoText; } diff --git a/core/java/android/text/method/TextKeyListener.java b/core/java/android/text/method/TextKeyListener.java index 8ad6f50..8312fe1 100644 --- a/core/java/android/text/method/TextKeyListener.java +++ b/core/java/android/text/method/TextKeyListener.java @@ -189,7 +189,12 @@ public class TextKeyListener extends BaseKeyListener implements SpanWatcher { return MultiTapKeyListener.getInstance(mAutoText, mAutoCap); } else if (kind == KeyCharacterMap.FULL || kind == KeyCharacterMap.SPECIAL_FUNCTION) { - return QwertyKeyListener.getInstance(false, Capitalize.NONE); + // We consider special function keyboards full keyboards as a workaround for + // devices that do not have built-in keyboards. Applications may try to inject + // key events using the built-in keyboard device id which may be configured as + // a special function keyboard using a default key map. Ideally, as of Honeycomb, + // these applications should be modified to use KeyCharacterMap.VIRTUAL_KEYBOARD. + return QwertyKeyListener.getInstanceForFullKeyboard(); } return NullKeyListener.getInstance(); diff --git a/data/keyboards/Apple_Wireless_Keyboard.kl b/data/keyboards/Apple_Wireless_Keyboard.kl index 9262a03..5234d58 100644 --- a/data/keyboards/Apple_Wireless_Keyboard.kl +++ b/data/keyboards/Apple_Wireless_Keyboard.kl @@ -101,7 +101,7 @@ key 108 DPAD_DOWN key 109 PAGE_DOWN key 110 NUMPAD_ENTER key 111 FORWARD_DEL -key 113 VALUME_MUTE +key 113 VOLUME_MUTE key 114 VOLUME_DOWN key 115 VOLUME_UP # key 120 switch applications diff --git a/data/keyboards/Logitech_USB_Receiver.kl b/data/keyboards/Logitech_USB_Receiver.kl index 23a8f54..aa7c0ee 100644 --- a/data/keyboards/Logitech_USB_Receiver.kl +++ b/data/keyboards/Logitech_USB_Receiver.kl @@ -105,7 +105,7 @@ key 108 DPAD_DOWN key 109 PAGE_DOWN key 110 NUMPAD_ENTER key 111 FORWARD_DEL -key 113 VALUME_MUTE +key 113 VOLUME_MUTE key 114 VOLUME_DOWN key 115 VOLUME_UP key 119 MEDIA_PAUSE diff --git a/data/keyboards/qwerty.kcm b/data/keyboards/qwerty.kcm index f31333e..f3e1524 100644 --- a/data/keyboards/qwerty.kcm +++ b/data/keyboards/qwerty.kcm @@ -259,9 +259,9 @@ key COMMA { label: ',' number: ',' base: ',' - shift, capslock: ';' + shift: ';' alt: ';' - shift+alt, capslock+alt: '|' + shift+alt: '|' } key PERIOD { diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h index f4dc536..6c798a6 100644 --- a/include/ui/EventHub.h +++ b/include/ui/EventHub.h @@ -26,6 +26,7 @@ #include <utils/threads.h> #include <utils/List.h> #include <utils/Errors.h> +#include <utils/PropertyMap.h> #include <linux/input.h> @@ -156,6 +157,8 @@ public: virtual String8 getDeviceName(int32_t deviceId) const = 0; + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0; + virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, RawAbsoluteAxisInfo* outAxisInfo) const = 0; @@ -205,6 +208,8 @@ public: virtual String8 getDeviceName(int32_t deviceId) const; + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const; + virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, RawAbsoluteAxisInfo* outAxisInfo) const; @@ -247,6 +252,8 @@ private: uint32_t classes; uint8_t* keyBitmask; KeyLayoutMap* layoutMap; + String8 configurationFile; + PropertyMap* configuration; KeyMapInfo keyMapInfo; int fd; device_t* next; @@ -264,6 +271,7 @@ private: bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const; + void loadConfiguration(device_t* device); void configureKeyMap(device_t* device); void setKeyboardProperties(device_t* device, bool firstKeyboard); void clearKeyboardProperties(device_t* device, bool firstKeyboard); diff --git a/include/ui/Input.h b/include/ui/Input.h index 1355bab..11b798f 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -497,6 +497,24 @@ private: KeyedVector<int32_t, MotionRange> mMotionRanges; }; +/* Types of input device configuration files. */ +enum InputDeviceConfigurationFileType { + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */ + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */ +}; + +/* + * Get the path of an input device configuration file, if one is available. + * Spaces in the name are replaced with underscores. + * + * Looks in: <system-root>/usr/<type-specific-directory>/<name><extension>. + * + * TODO Also look in a user installable location. + * Returns an empty string if not found. + */ +extern String8 getInputDeviceConfigurationFilePath( + const String8& name, InputDeviceConfigurationFileType type); } // namespace android diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h index f3a2dd2..cfceaab 100644 --- a/include/ui/InputReader.h +++ b/include/ui/InputReader.h @@ -47,23 +47,6 @@ struct VirtualKeyDefinition { }; -/* Specifies input device calibration settings. */ -class InputDeviceCalibration { -public: - InputDeviceCalibration(); - - void clear(); - void addProperty(const String8& key, const String8& value); - - bool tryGetProperty(const String8& key, String8& outValue) const; - bool tryGetProperty(const String8& key, int32_t& outValue) const; - bool tryGetProperty(const String8& key, float& outValue) const; - -private: - KeyedVector<String8, String8> mProperties; -}; - - /* * Input reader policy interface. * @@ -107,10 +90,6 @@ public: virtual void getVirtualKeyDefinitions(const String8& deviceName, Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0; - /* Gets the calibration for an input device. */ - virtual void getInputDeviceCalibration(const String8& deviceName, - InputDeviceCalibration& outCalibration) = 0; - /* Gets the excluded device names for the platform. */ virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0; }; @@ -314,8 +293,8 @@ public: int32_t getMetaState(); - inline const InputDeviceCalibration& getCalibration() { - return mCalibration; + inline const PropertyMap& getConfiguration() { + return mConfiguration; } private: @@ -330,7 +309,7 @@ private: typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code); int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc); - InputDeviceCalibration mCalibration; + PropertyMap mConfiguration; }; @@ -389,13 +368,13 @@ private: class KeyboardInputMapper : public InputMapper { public: - KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources, - int32_t keyboardType); + KeyboardInputMapper(InputDevice* device, uint32_t sources, int32_t keyboardType); virtual ~KeyboardInputMapper(); virtual uint32_t getSources(); virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); virtual void dump(String8& dump); + virtual void configure(); virtual void reset(); virtual void process(const RawEvent* rawEvent); @@ -414,10 +393,15 @@ private: int32_t scanCode; }; - int32_t mAssociatedDisplayId; uint32_t mSources; int32_t mKeyboardType; + // Immutable configuration parameters. + struct Parameters { + int32_t associatedDisplayId; + bool orientationAware; + } mParameters; + struct LockedState { Vector<KeyDown> keyDowns; // keys that are down int32_t metaState; @@ -435,6 +419,9 @@ private: void initializeLocked(); void initializeLedStateLocked(LockedState::LedState& ledState, int32_t led); + void configureParameters(); + void dumpParameters(String8& dump); + bool isKeyboardOrGamepadKey(int32_t scanCode); void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode, @@ -450,12 +437,13 @@ private: class TrackballInputMapper : public InputMapper { public: - TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId); + TrackballInputMapper(InputDevice* device); virtual ~TrackballInputMapper(); virtual uint32_t getSources(); virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo); virtual void dump(String8& dump); + virtual void configure(); virtual void reset(); virtual void process(const RawEvent* rawEvent); @@ -467,7 +455,11 @@ private: Mutex mLock; - int32_t mAssociatedDisplayId; + // Immutable configuration parameters. + struct Parameters { + int32_t associatedDisplayId; + bool orientationAware; + } mParameters; struct Accumulator { enum { @@ -499,13 +491,16 @@ private: void initializeLocked(); + void configureParameters(); + void dumpParameters(String8& dump); + void sync(nsecs_t when); }; class TouchInputMapper : public InputMapper { public: - TouchInputMapper(InputDevice* device, int32_t associatedDisplayId); + TouchInputMapper(InputDevice* device); virtual ~TouchInputMapper(); virtual uint32_t getSources(); @@ -591,10 +586,17 @@ protected: } }; - int32_t mAssociatedDisplayId; - // Immutable configuration parameters. struct Parameters { + enum DeviceType { + DEVICE_TYPE_TOUCH_SCREEN, + DEVICE_TYPE_TOUCH_PAD, + }; + + DeviceType deviceType; + int32_t associatedDisplayId; + bool orientationAware; + bool useBadTouchFilter; bool useJumpyTouchFilter; bool useAveragingTouchFilter; @@ -641,7 +643,7 @@ protected: bool haveToolSizeAreaBias; float toolSizeAreaBias; bool haveToolSizeIsSummed; - int32_t toolSizeIsSummed; + bool toolSizeIsSummed; // Pressure enum PressureCalibration { @@ -846,7 +848,7 @@ private: class SingleTouchInputMapper : public TouchInputMapper { public: - SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId); + SingleTouchInputMapper(InputDevice* device); virtual ~SingleTouchInputMapper(); virtual void reset(); @@ -892,7 +894,7 @@ private: class MultiTouchInputMapper : public TouchInputMapper { public: - MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId); + MultiTouchInputMapper(InputDevice* device); virtual ~MultiTouchInputMapper(); virtual void reset(); diff --git a/include/ui/Keyboard.h b/include/ui/Keyboard.h index 3b477c7..689607d 100644 --- a/include/ui/Keyboard.h +++ b/include/ui/Keyboard.h @@ -20,6 +20,7 @@ #include <ui/Input.h> #include <utils/Errors.h> #include <utils/String8.h> +#include <utils/PropertyMap.h> namespace android { @@ -33,19 +34,23 @@ enum { }; struct KeyMapInfo { - String8 keyMapName; String8 keyLayoutFile; String8 keyCharacterMapFile; bool isDefaultKeyMap; KeyMapInfo() : isDefaultKeyMap(false) { } + + bool isComplete() { + return !keyLayoutFile.isEmpty() && !keyCharacterMapFile.isEmpty(); + } }; /** * Resolves the key map to use for a particular keyboard device. */ -extern status_t resolveKeyMap(const String8& deviceName, KeyMapInfo& outKeyMapInfo); +extern status_t resolveKeyMap(const String8& deviceName, + const PropertyMap* deviceConfiguration, KeyMapInfo& outKeyMapInfo); /** * Sets keyboard system properties. diff --git a/include/utils/PropertyMap.h b/include/utils/PropertyMap.h new file mode 100644 index 0000000..a54f819 --- /dev/null +++ b/include/utils/PropertyMap.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UTILS_PROPERTY_MAP_H +#define _UTILS_PROPERTY_MAP_H + +#include <utils/KeyedVector.h> +#include <utils/String8.h> +#include <utils/Errors.h> +#include <utils/Tokenizer.h> + +namespace android { + +/* + * Provides a mechanism for passing around string-based property key / value pairs + * and loading them from property files. + * + * The property files have the following simple structure: + * + * # Comment + * key = value + * + * Keys and values are any sequence of printable ASCII characters. + * The '=' separates the key from the value. + * The key and value may not contain whitespace. + * + * The '\' character is reserved for escape sequences and is not currently supported. + * The '"" character is reserved for quoting and is not currently supported. + * Files that contain the '\' or '"' character will fail to parse. + * + * The file must not contain duplicate keys. + * + * TODO Support escape sequences and quoted values when needed. + */ +class PropertyMap { +public: + /* Creates an empty property map. */ + PropertyMap(); + ~PropertyMap(); + + /* Clears the property map. */ + void clear(); + + /* Adds a property. + * Replaces the property with the same key if it is already present. + */ + void addProperty(const String8& key, const String8& value); + + /* Returns true if the property map contains the specified key. */ + bool hasProperty(const String8& key) const; + + /* Gets the value of a property and parses it. + * Returns true and sets outValue if the key was found and its value was parsed successfully. + * Otherwise returns false and does not modify outValue. (Also logs a warning.) + */ + bool tryGetProperty(const String8& key, String8& outValue) const; + bool tryGetProperty(const String8& key, bool& outValue) const; + bool tryGetProperty(const String8& key, int32_t& outValue) const; + bool tryGetProperty(const String8& key, float& outValue) const; + + /* Loads a property map from a file. */ + static status_t load(const String8& filename, PropertyMap** outMap); + +private: + class Parser { + PropertyMap* mMap; + Tokenizer* mTokenizer; + + public: + Parser(PropertyMap* map, Tokenizer* tokenizer); + ~Parser(); + status_t parse(); + + private: + status_t parseType(); + status_t parseKey(); + status_t parseKeyProperty(); + status_t parseModifier(const String8& token, int32_t* outMetaState); + status_t parseCharacterLiteral(char16_t* outCharacter); + }; + + KeyedVector<String8, String8> mProperties; +}; + +} // namespace android + +#endif // _UTILS_PROPERTY_MAP_H diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index f468217..f831086 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -93,12 +93,13 @@ static inline const char* toString(bool value) { EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name) : id(_id), path(_path), name(name), classes(0) - , keyBitmask(NULL), layoutMap(NULL), fd(-1), next(NULL) { + , keyBitmask(NULL), layoutMap(NULL), configuration(NULL), fd(-1), next(NULL) { } EventHub::device_t::~device_t() { delete [] keyBitmask; delete layoutMap; + delete configuration; } EventHub::EventHub(void) @@ -144,6 +145,16 @@ uint32_t EventHub::getDeviceClasses(int32_t deviceId) const return device->classes; } +void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { + outConfiguration->clear(); + + AutoMutex _l(mLock); + device_t* device = getDeviceLocked(deviceId); + if (device && device->configuration) { + *outConfiguration = *device->configuration; + } +} + status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, RawAbsoluteAxisInfo* outAxisInfo) const { outAxisInfo->clear(); @@ -716,6 +727,9 @@ int EventHub::openDevice(const char *deviceName) { mFDs[mFDCount].events = POLLIN; mFDs[mFDCount].revents = 0; + // Load the configuration file for the device. + loadConfiguration(device); + // Figure out the kinds of events the device reports. uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)]; @@ -803,7 +817,6 @@ int EventHub::openDevice(const char *deviceName) { device->name = name; // Configure the keymap for the device. - configureKeyMap(device); // Tell the world about the devname (the descriptive name) @@ -868,9 +881,11 @@ int EventHub::openDevice(const char *deviceName) { return -1; } - LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n", - deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes); - + LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x " + "configuration='%s'\n", + deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes, + device->configurationFile.string()); + LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n", deviceName, device, mFDCount, devid, device->classes); @@ -883,8 +898,24 @@ int EventHub::openDevice(const char *deviceName) { return 0; } +void EventHub::loadConfiguration(device_t* device) { + device->configurationFile = getInputDeviceConfigurationFilePath(device->name, + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION); + if (device->configurationFile.isEmpty()) { + LOGI("No input device configuration file found for device '%s'.", + device->name.string()); + } else { + status_t status = PropertyMap::load(device->configurationFile, + &device->configuration); + if (status) { + LOGE("Error loading input device configuration file for device '%s'.", + device->name.string()); + } + } +} + void EventHub::configureKeyMap(device_t* device) { - android::resolveKeyMap(device->name, device->keyMapInfo); + android::resolveKeyMap(device->name, device->configuration, device->keyMapInfo); } void EventHub::setKeyboardProperties(device_t* device, bool firstKeyboard) { @@ -1058,12 +1089,12 @@ void EventHub::dump(String8& dump) { dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); dump.appendFormat(INDENT3 "IsDefaultKeyMap: %s\n", toString(device->keyMapInfo.isDefaultKeyMap)); - dump.appendFormat(INDENT3 "KeyMapName: %s\n", - device->keyMapInfo.keyMapName.string()); dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", device->keyMapInfo.keyLayoutFile.string()); dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n", device->keyMapInfo.keyCharacterMapFile.string()); + dump.appendFormat(INDENT3 "ConfigurationFile: %s\n", + device->configurationFile.string()); } } } // release lock diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp index 944a79b..9e697db 100644 --- a/libs/ui/Input.cpp +++ b/libs/ui/Input.cpp @@ -7,11 +7,82 @@ //#define LOG_NDEBUG 0 +#define DEBUG_PROBE 0 + +#include <stdlib.h> +#include <unistd.h> + #include <ui/Input.h> namespace android { -// class InputEvent +static const char* CONFIGURATION_FILE_DIR[] = { + "idc/", + "keylayout/", + "keychars/", +}; + +static const char* CONFIGURATION_FILE_EXTENSION[] = { + ".idc", + ".kl", + ".kcm", +}; + +static void appendInputDeviceConfigurationFileRelativePath(String8& path, + const String8& name, InputDeviceConfigurationFileType type) { + path.append(CONFIGURATION_FILE_DIR[type]); + for (size_t i = 0; i < name.length(); i++) { + char ch = name[i]; + if (ch == ' ') { + ch = '_'; + } + path.append(&ch, 1); + } + path.append(CONFIGURATION_FILE_EXTENSION[type]); +} + +extern String8 getInputDeviceConfigurationFilePath( + const String8& name, InputDeviceConfigurationFileType type) { + // Search system repository. + String8 path; + path.setTo(getenv("ANDROID_ROOT")); + path.append("/usr/"); + appendInputDeviceConfigurationFileRelativePath(path, name, type); +#if DEBUG_PROBE + LOGD("Probing for system provided input device configuration file: path='%s'", path.string()); +#endif + if (!access(path.string(), R_OK)) { +#if DEBUG_PROBE + LOGD("Found"); +#endif + return path; + } + + // Search user repository. + // TODO Should only look here if not in safe mode. + path.setTo(getenv("ANDROID_DATA")); + path.append("/system/devices/"); + appendInputDeviceConfigurationFileRelativePath(path, name, type); +#if DEBUG_PROBE + LOGD("Probing for system user input device configuration file: path='%s'", path.string()); +#endif + if (!access(path.string(), R_OK)) { +#if DEBUG_PROBE + LOGD("Found"); +#endif + return path; + } + + // Not found. +#if DEBUG_PROBE + LOGD("Probe failed to find input device configuration file: name='%s', type=%d", + name.string(), type); +#endif + return String8(); +} + + +// --- InputEvent --- void InputEvent::initialize(int32_t deviceId, int32_t source) { mDeviceId = deviceId; @@ -23,7 +94,7 @@ void InputEvent::initialize(const InputEvent& from) { mSource = from.mSource; } -// class KeyEvent +// --- KeyEvent --- bool KeyEvent::hasDefaultAction(int32_t keyCode) { switch (keyCode) { @@ -131,7 +202,7 @@ void KeyEvent::initialize(const KeyEvent& from) { mEventTime = from.mEventTime; } -// class MotionEvent +// --- MotionEvent --- void MotionEvent::initialize( int32_t deviceId, @@ -178,7 +249,7 @@ void MotionEvent::offsetLocation(float xOffset, float yOffset) { mYOffset += yOffset; } -// class InputDeviceInfo +// --- InputDeviceInfo --- InputDeviceInfo::InputDeviceInfo() { initialize(-1, String8("uninitialized device info")); diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index daff2d0..dc9085b 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -98,64 +98,6 @@ static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { } -// --- InputDeviceCalibration --- - -InputDeviceCalibration::InputDeviceCalibration() { -} - -void InputDeviceCalibration::clear() { - mProperties.clear(); -} - -void InputDeviceCalibration::addProperty(const String8& key, const String8& value) { - mProperties.add(key, value); -} - -bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const { - ssize_t index = mProperties.indexOfKey(key); - if (index < 0) { - return false; - } - - outValue = mProperties.valueAt(index); - return true; -} - -bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const { - String8 stringValue; - if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { - return false; - } - - char* end; - int value = strtol(stringValue.string(), & end, 10); - if (*end != '\0') { - LOGW("Input device calibration key '%s' has invalid value '%s'. Expected an integer.", - key.string(), stringValue.string()); - return false; - } - outValue = value; - return true; -} - -bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const { - String8 stringValue; - if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { - return false; - } - - char* end; - float value = strtof(stringValue.string(), & end); - if (*end != '\0') { - LOGW("Input device calibration key '%s' has invalid value '%s'. Expected a float.", - key.string(), stringValue.string()); - return false; - } - outValue = value; - return true; -} - - // --- InputReader --- InputReader::InputReader(const sp<EventHubInterface>& eventHub, @@ -274,8 +216,6 @@ void InputReader::removeDevice(int32_t deviceId) { InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) { InputDevice* device = new InputDevice(this, deviceId, name); - const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices - // Switch-like devices. if (classes & INPUT_DEVICE_CLASS_SWITCH) { device->addMapper(new SwitchInputMapper(device)); @@ -295,20 +235,19 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui } if (keyboardSources != 0) { - device->addMapper(new KeyboardInputMapper(device, - associatedDisplayId, keyboardSources, keyboardType)); + device->addMapper(new KeyboardInputMapper(device, keyboardSources, keyboardType)); } // Trackball-like devices. if (classes & INPUT_DEVICE_CLASS_TRACKBALL) { - device->addMapper(new TrackballInputMapper(device, associatedDisplayId)); + device->addMapper(new TrackballInputMapper(device)); } // Touchscreen-like devices. if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) { - device->addMapper(new MultiTouchInputMapper(device, associatedDisplayId)); + device->addMapper(new MultiTouchInputMapper(device)); } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) { - device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId)); + device->addMapper(new SingleTouchInputMapper(device)); } return device; @@ -626,7 +565,7 @@ void InputDevice::addMapper(InputMapper* mapper) { void InputDevice::configure() { if (! isIgnored()) { - mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration); + mContext->getEventHub()->getConfiguration(mId, &mConfiguration); } mSources = 0; @@ -792,9 +731,9 @@ int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCod // --- KeyboardInputMapper --- -KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, +KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, uint32_t sources, int32_t keyboardType) : - InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources), + InputMapper(device), mSources(sources), mKeyboardType(keyboardType) { initializeLocked(); } @@ -832,7 +771,7 @@ void KeyboardInputMapper::dump(String8& dump) { { // acquire lock AutoMutex _l(mLock); dump.append(INDENT2 "Keyboard Input Mapper:\n"); - dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dumpParameters(dump); dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); @@ -840,6 +779,30 @@ void KeyboardInputMapper::dump(String8& dump) { } // release lock } + +void KeyboardInputMapper::configure() { + InputMapper::configure(); + + // Configure basic parameters. + configureParameters(); +} + +void KeyboardInputMapper::configureParameters() { + mParameters.orientationAware = false; + getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"), + mParameters.orientationAware); + + mParameters.associatedDisplayId = mParameters.orientationAware ? 0 : -1; +} + +void KeyboardInputMapper::dumpParameters(String8& dump) { + dump.append(INDENT3 "Parameters:\n"); + dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", + mParameters.associatedDisplayId); + dump.appendFormat(INDENT4 "OrientationAware: %s\n", + toString(mParameters.orientationAware)); +} + void KeyboardInputMapper::reset() { for (;;) { int32_t keyCode, scanCode; @@ -896,9 +859,10 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, if (down) { // Rotate key codes according to orientation if needed. // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. - if (mAssociatedDisplayId >= 0) { + if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) { int32_t orientation; - if (!getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) { + if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, + NULL, NULL, & orientation)) { orientation = InputReaderPolicyInterface::ROTATION_0; } @@ -1011,8 +975,8 @@ void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& // --- TrackballInputMapper --- -TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) : - InputMapper(device), mAssociatedDisplayId(associatedDisplayId) { +TrackballInputMapper::TrackballInputMapper(InputDevice* device) : + InputMapper(device) { mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD; mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD; mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; @@ -1039,7 +1003,7 @@ void TrackballInputMapper::dump(String8& dump) { { // acquire lock AutoMutex _l(mLock); dump.append(INDENT2 "Trackball Input Mapper:\n"); - dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); + dumpParameters(dump); dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision); dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision); dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down)); @@ -1047,6 +1011,29 @@ void TrackballInputMapper::dump(String8& dump) { } // release lock } +void TrackballInputMapper::configure() { + InputMapper::configure(); + + // Configure basic parameters. + configureParameters(); +} + +void TrackballInputMapper::configureParameters() { + mParameters.orientationAware = false; + getDevice()->getConfiguration().tryGetProperty(String8("trackball.orientationAware"), + mParameters.orientationAware); + + mParameters.associatedDisplayId = mParameters.orientationAware ? 0 : -1; +} + +void TrackballInputMapper::dumpParameters(String8& dump) { + dump.append(INDENT3 "Parameters:\n"); + dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", + mParameters.associatedDisplayId); + dump.appendFormat(INDENT4 "OrientationAware: %s\n", + toString(mParameters.orientationAware)); +} + void TrackballInputMapper::initializeLocked() { mAccumulator.clear(); @@ -1155,11 +1142,13 @@ void TrackballInputMapper::sync(nsecs_t when) { pointerCoords.toolMinor = 0; pointerCoords.orientation = 0; - if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) { + if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0 + && (x != 0.0f || y != 0.0f)) { // Rotate motion based on display orientation if needed. // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. int32_t orientation; - if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) { + if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, + NULL, NULL, & orientation)) { orientation = InputReaderPolicyInterface::ROTATION_0; } @@ -1205,8 +1194,8 @@ int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scan // --- TouchInputMapper --- -TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : - InputMapper(device), mAssociatedDisplayId(associatedDisplayId) { +TouchInputMapper::TouchInputMapper(InputDevice* device) : + InputMapper(device) { mLocked.surfaceOrientation = -1; mLocked.surfaceWidth = -1; mLocked.surfaceHeight = -1; @@ -1218,7 +1207,15 @@ TouchInputMapper::~TouchInputMapper() { } uint32_t TouchInputMapper::getSources() { - return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD; + switch (mParameters.deviceType) { + case Parameters::DEVICE_TYPE_TOUCH_SCREEN: + return AINPUT_SOURCE_TOUCHSCREEN; + case Parameters::DEVICE_TYPE_TOUCH_PAD: + return AINPUT_SOURCE_TOUCHPAD; + default: + assert(false); + return AINPUT_SOURCE_UNKNOWN; + } } void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { @@ -1269,7 +1266,6 @@ void TouchInputMapper::dump(String8& dump) { { // acquire lock AutoMutex _l(mLock); dump.append(INDENT2 "Touch Input Mapper:\n"); - dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); dumpParameters(dump); dumpVirtualKeysLocked(dump); dumpRawAxes(dump); @@ -1339,14 +1335,50 @@ void TouchInputMapper::configureParameters() { mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents(); mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents(); mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); + + String8 deviceTypeString; + mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN; + if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), + deviceTypeString)) { + if (deviceTypeString == "touchPad") { + mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; + } else if (deviceTypeString != "touchScreen") { + LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string()); + } + } + bool isTouchScreen = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; + + mParameters.orientationAware = isTouchScreen; + getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"), + mParameters.orientationAware); + + mParameters.associatedDisplayId = mParameters.orientationAware || isTouchScreen ? 0 : -1; } void TouchInputMapper::dumpParameters(String8& dump) { - dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n", + dump.append(INDENT3 "Parameters:\n"); + + switch (mParameters.deviceType) { + case Parameters::DEVICE_TYPE_TOUCH_SCREEN: + dump.append(INDENT4 "DeviceType: touchScreen\n"); + break; + case Parameters::DEVICE_TYPE_TOUCH_PAD: + dump.append(INDENT4 "DeviceType: touchPad\n"); + break; + default: + assert(false); + } + + dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", + mParameters.associatedDisplayId); + dump.appendFormat(INDENT4 "OrientationAware: %s\n", + toString(mParameters.orientationAware)); + + dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n", toString(mParameters.useBadTouchFilter)); - dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n", + dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n", toString(mParameters.useAveragingTouchFilter)); - dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n", + dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n", toString(mParameters.useJumpyTouchFilter)); } @@ -1384,17 +1416,20 @@ void TouchInputMapper::dumpRawAxes(String8& dump) { bool TouchInputMapper::configureSurfaceLocked() { // Update orientation and dimensions if needed. - int32_t orientation; - int32_t width, height; - if (mAssociatedDisplayId >= 0) { + int32_t orientation = InputReaderPolicyInterface::ROTATION_0; + int32_t width = mRawAxes.x.getRange(); + int32_t height = mRawAxes.y.getRange(); + + if (mParameters.associatedDisplayId >= 0) { + bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; + bool wantOrientation = mParameters.orientationAware; + // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. - if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) { + if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, + wantSize ? &width : NULL, wantSize ? &height : NULL, + wantOrientation ? &orientation : NULL)) { return false; } - } else { - orientation = InputReaderPolicyInterface::ROTATION_0; - width = mRawAxes.x.getRange(); - height = mRawAxes.y.getRange(); } bool orientationChanged = mLocked.surfaceOrientation != orientation; @@ -1686,7 +1721,7 @@ void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { } void TouchInputMapper::parseCalibration() { - const InputDeviceCalibration& in = getDevice()->getCalibration(); + const PropertyMap& in = getDevice()->getConfiguration(); Calibration& out = mCalibration; // Position @@ -1973,7 +2008,7 @@ void TouchInputMapper::dumpCalibration(String8& dump) { if (mCalibration.haveToolSizeIsSummed) { dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %d\n", - mCalibration.toolSizeIsSummed); + toString(mCalibration.toolSizeIsSummed)); } // Pressure @@ -3157,8 +3192,8 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCode // --- SingleTouchInputMapper --- -SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : - TouchInputMapper(device, associatedDisplayId) { +SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : + TouchInputMapper(device) { initialize(); } @@ -3286,8 +3321,8 @@ void SingleTouchInputMapper::configureRawAxes() { // --- MultiTouchInputMapper --- -MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : - TouchInputMapper(device, associatedDisplayId) { +MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : + TouchInputMapper(device) { initialize(); } diff --git a/libs/ui/Keyboard.cpp b/libs/ui/Keyboard.cpp index de76e25..a4cc22d 100644 --- a/libs/ui/Keyboard.cpp +++ b/libs/ui/Keyboard.cpp @@ -28,74 +28,79 @@ namespace android { -static void selectKeyMap(KeyMapInfo& keyMapInfo, const String8& keyMapName, bool defaultKeyMap) { - if (keyMapInfo.keyMapName.isEmpty()) { - keyMapInfo.keyMapName.setTo(keyMapName); - keyMapInfo.isDefaultKeyMap = defaultKeyMap; - } -} - static bool probeKeyMap(KeyMapInfo& keyMapInfo, const String8& keyMapName, bool defaultKeyMap) { - const char* root = getenv("ANDROID_ROOT"); - - // TODO Consider also looking somewhere in a writeable partition like /data for a - // custom keymap supplied by the user for this device. - bool haveKeyLayout = !keyMapInfo.keyLayoutFile.isEmpty(); - if (!haveKeyLayout) { - keyMapInfo.keyLayoutFile.setTo(root); - keyMapInfo.keyLayoutFile.append("/usr/keylayout/"); - keyMapInfo.keyLayoutFile.append(keyMapName); - keyMapInfo.keyLayoutFile.append(".kl"); - if (access(keyMapInfo.keyLayoutFile.string(), R_OK)) { - keyMapInfo.keyLayoutFile.clear(); - } else { - haveKeyLayout = true; + bool foundOne = false; + if (keyMapInfo.keyLayoutFile.isEmpty()) { + keyMapInfo.keyLayoutFile.setTo(getInputDeviceConfigurationFilePath(keyMapName, + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT)); + if (!keyMapInfo.keyLayoutFile.isEmpty()) { + foundOne = true; } } - bool haveKeyCharacterMap = !keyMapInfo.keyCharacterMapFile.isEmpty(); - if (!haveKeyCharacterMap) { - keyMapInfo.keyCharacterMapFile.setTo(root); - keyMapInfo.keyCharacterMapFile.append("/usr/keychars/"); - keyMapInfo.keyCharacterMapFile.append(keyMapName); - keyMapInfo.keyCharacterMapFile.append(".kcm"); - if (access(keyMapInfo.keyCharacterMapFile.string(), R_OK)) { - keyMapInfo.keyCharacterMapFile.clear(); - } else { - haveKeyCharacterMap = true; + if (keyMapInfo.keyCharacterMapFile.isEmpty()) { + keyMapInfo.keyCharacterMapFile.setTo(getInputDeviceConfigurationFilePath(keyMapName, + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP)); + if (!keyMapInfo.keyCharacterMapFile.isEmpty()) { + foundOne = true; } } - if (haveKeyLayout || haveKeyCharacterMap) { - selectKeyMap(keyMapInfo, keyMapName, defaultKeyMap); + if (foundOne && defaultKeyMap) { + keyMapInfo.isDefaultKeyMap = true; } - return haveKeyLayout && haveKeyCharacterMap; + return keyMapInfo.isComplete(); } -status_t resolveKeyMap(const String8& deviceName, KeyMapInfo& outKeyMapInfo) { - // As an initial key map name, try using the device name. - String8 keyMapName(deviceName); - char* p = keyMapName.lockBuffer(keyMapName.size()); - while (*p) { - if (*p == ' ') *p = '_'; - p++; - } - keyMapName.unlockBuffer(); +status_t resolveKeyMap(const String8& deviceName, + const PropertyMap* deviceConfiguration, KeyMapInfo& outKeyMapInfo) { + // Use the configured key layout if available. + if (deviceConfiguration) { + String8 keyLayoutName; + if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"), + keyLayoutName)) { + outKeyMapInfo.keyLayoutFile.setTo(getInputDeviceConfigurationFilePath( + keyLayoutName, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT)); + if (outKeyMapInfo.keyLayoutFile.isEmpty()) { + LOGW("Configuration for keyboard device '%s' requested keyboard layout '%s' but " + "it was not found.", + deviceName.string(), keyLayoutName.string()); + } + } - if (probeKeyMap(outKeyMapInfo, keyMapName, false)) return OK; + String8 keyCharacterMapName; + if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"), + keyCharacterMapName)) { + outKeyMapInfo.keyCharacterMapFile.setTo(getInputDeviceConfigurationFilePath( + keyCharacterMapName, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP)); + if (outKeyMapInfo.keyCharacterMapFile.isEmpty()) { + LOGW("Configuration for keyboard device '%s' requested keyboard character " + "map '%s' but it was not found.", + deviceName.string(), keyCharacterMapName.string()); + } + } - // TODO Consider allowing the user to configure a specific key map somehow. + if (outKeyMapInfo.isComplete()) { + return OK; + } + } + + // Try searching by device name. + if (probeKeyMap(outKeyMapInfo, deviceName, false)) { + return OK; + } - // Try the Generic key map. + // Fall back on the Generic key map. // TODO Apply some additional heuristics here to figure out what kind of // generic key map to use (US English, etc.). - keyMapName.setTo("Generic"); - if (probeKeyMap(outKeyMapInfo, keyMapName, true)) return OK; + if (probeKeyMap(outKeyMapInfo, String8("Generic"), true)) { + return OK; + } // Give up! - keyMapName.setTo("unknown"); - selectKeyMap(outKeyMapInfo, keyMapName, true); - LOGE("Could not determine key map for device '%s'.", deviceName.string()); + LOGE("Could not determine key map for device '%s' and the Generic key map was not found!", + deviceName.string()); + outKeyMapInfo.isDefaultKeyMap = true; return NAME_NOT_FOUND; } @@ -104,8 +109,6 @@ void setKeyboardProperties(int32_t deviceId, const String8& deviceName, char propName[PROPERTY_KEY_MAX]; snprintf(propName, sizeof(propName), "hw.keyboards.%u.devname", deviceId); property_set(propName, deviceName.string()); - snprintf(propName, sizeof(propName), "hw.keyboards.%u.keymap", deviceId); - property_set(propName, keyMapInfo.keyMapName.string()); snprintf(propName, sizeof(propName), "hw.keyboards.%u.klfile", deviceId); property_set(propName, keyMapInfo.keyLayoutFile.string()); snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId); @@ -116,8 +119,6 @@ void clearKeyboardProperties(int32_t deviceId) { char propName[PROPERTY_KEY_MAX]; snprintf(propName, sizeof(propName), "hw.keyboards.%u.devname", deviceId); property_set(propName, ""); - snprintf(propName, sizeof(propName), "hw.keyboards.%u.keymap", deviceId); - property_set(propName, ""); snprintf(propName, sizeof(propName), "hw.keyboards.%u.klfile", deviceId); property_set(propName, ""); snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId); @@ -125,6 +126,14 @@ void clearKeyboardProperties(int32_t deviceId) { } status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFile) { + if (deviceId == DEVICE_ID_VIRTUAL_KEYBOARD) { + outKeyCharacterMapFile.setTo(getInputDeviceConfigurationFilePath(String8("Virtual"), + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP)); + if (!outKeyCharacterMapFile.isEmpty()) { + return OK; + } + } + char propName[PROPERTY_KEY_MAX]; char fn[PROPERTY_VALUE_MAX]; snprintf(propName, sizeof(propName), "hw.keyboards.%u.kcmfile", deviceId); @@ -133,23 +142,13 @@ status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFil return OK; } - const char* root = getenv("ANDROID_ROOT"); - char path[PATH_MAX]; - if (deviceId == DEVICE_ID_VIRTUAL_KEYBOARD) { - snprintf(path, sizeof(path), "%s/usr/keychars/Virtual.kcm", root); - if (!access(path, R_OK)) { - outKeyCharacterMapFile.setTo(path); - return OK; - } - } - - snprintf(path, sizeof(path), "%s/usr/keychars/Generic.kcm", root); - if (!access(path, R_OK)) { - outKeyCharacterMapFile.setTo(path); + outKeyCharacterMapFile.setTo(getInputDeviceConfigurationFilePath(String8("Generic"), + INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP)); + if (!outKeyCharacterMapFile.isEmpty()) { return OK; } - LOGE("Can't find any key character map files (also tried %s)", path); + LOGE("Can't find any key character map files (also tried Virtual and Generic key maps)"); return NAME_NOT_FOUND; } diff --git a/libs/ui/tests/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp index ded0225..05bebc5 100644 --- a/libs/ui/tests/InputReader_test.cpp +++ b/libs/ui/tests/InputReader_test.cpp @@ -43,7 +43,6 @@ class FakeInputReaderPolicy : public InputReaderPolicyInterface { bool mFilterTouchEvents; bool mFilterJumpyTouchEvents; KeyedVector<String8, Vector<VirtualKeyDefinition> > mVirtualKeyDefinitions; - KeyedVector<String8, InputDeviceCalibration> mInputDeviceCalibrations; Vector<String8> mExcludedDeviceNames; protected: @@ -76,20 +75,6 @@ public: mFilterJumpyTouchEvents = enabled; } - void addInputDeviceCalibration(const String8& deviceName, - const InputDeviceCalibration& calibration) { - mInputDeviceCalibrations.add(deviceName, calibration); - } - - void addInputDeviceCalibrationProperty(const String8& deviceName, - const String8& key, const String8& value) { - ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName); - if (index < 0) { - index = mInputDeviceCalibrations.add(deviceName, InputDeviceCalibration()); - } - mInputDeviceCalibrations.editValueAt(index).addProperty(key, value); - } - void addVirtualKeyDefinition(const String8& deviceName, const VirtualKeyDefinition& definition) { if (mVirtualKeyDefinitions.indexOfKey(deviceName) < 0) { @@ -139,14 +124,6 @@ private: } } - virtual void getInputDeviceCalibration(const String8& deviceName, - InputDeviceCalibration& outCalibration) { - ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName); - if (index >= 0) { - outCalibration = mInputDeviceCalibrations.valueAt(index); - } - } - virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) { outExcludedDeviceNames.appendVector(mExcludedDeviceNames); } @@ -371,6 +348,7 @@ class FakeEventHub : public EventHubInterface { struct Device { String8 name; uint32_t classes; + PropertyMap configuration; KeyedVector<int, RawAbsoluteAxisInfo> axes; KeyedVector<int32_t, int32_t> keyCodeStates; KeyedVector<int32_t, int32_t> scanCodeStates; @@ -415,6 +393,11 @@ public: enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0, 0, 0); } + void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) { + Device* device = getDevice(deviceId); + device->configuration.addProperty(key, value); + } + void addAxis(int32_t deviceId, int axis, int32_t minValue, int32_t maxValue, int flat, int fuzz) { Device* device = getDevice(deviceId); @@ -499,6 +482,13 @@ private: return device ? device->name : String8("unknown"); } + virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { + Device* device = getDevice(deviceId); + if (device) { + *outConfiguration = device->configuration; + } + } + virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis, RawAbsoluteAxisInfo* outAxisInfo) const { Device* device = getDevice(deviceId); @@ -1208,9 +1198,7 @@ TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) { TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) { // Configuration. - InputDeviceCalibration calibration; - calibration.addProperty(String8("key"), String8("value")); - mFakePolicy->addInputDeviceCalibration(String8(DEVICE_NAME), calibration); + mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value")); FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD); mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC); @@ -1231,8 +1219,8 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe mDevice->configure(); String8 propertyValue; - ASSERT_TRUE(mDevice->getCalibration().tryGetProperty(String8("key"), propertyValue)) - << "Device should have read calibration during configuration phase."; + ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue)) + << "Device should have read configuration during configuration phase."; ASSERT_STREQ("value", propertyValue.string()); ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled()); @@ -1329,9 +1317,8 @@ protected: mFakeEventHub.clear(); } - void prepareCalibration(const char* key, const char* value) { - mFakePolicy->addInputDeviceCalibrationProperty(String8(DEVICE_NAME), - String8(key), String8(value)); + void addConfigurationProperty(const char* key, const char* value) { + mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value)); } void addMapperAndConfigure(InputMapper* mapper) { @@ -1448,7 +1435,7 @@ void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, TEST_F(KeyboardInputMapperTest, GetSources) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1456,7 +1443,7 @@ TEST_F(KeyboardInputMapperTest, GetSources) { } TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1493,7 +1480,7 @@ TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) { } TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1513,7 +1500,7 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp) } TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1558,7 +1545,7 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) { } TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1597,11 +1584,14 @@ TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) { ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled()); } -TEST_F(KeyboardInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateDPad) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, +TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) { + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); + mFakePolicy->setDisplayInfo(DISPLAY_ID, + DISPLAY_WIDTH, DISPLAY_HEIGHT, + InputReaderPolicyInterface::ROTATION_90); ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, @@ -1612,9 +1602,10 @@ TEST_F(KeyboardInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotate KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); } -TEST_F(KeyboardInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateDPad) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, DISPLAY_ID, +TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) { + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); + addConfigurationProperty("keyboard.orientationAware", "1"); addMapperAndConfigure(mapper); mFakePolicy->setDisplayInfo(DISPLAY_ID, @@ -1689,7 +1680,7 @@ TEST_F(KeyboardInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateDPad) } TEST_F(KeyboardInputMapperTest, GetKeyCodeState) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1701,7 +1692,7 @@ TEST_F(KeyboardInputMapperTest, GetKeyCodeState) { } TEST_F(KeyboardInputMapperTest, GetScanCodeState) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1713,7 +1704,7 @@ TEST_F(KeyboardInputMapperTest, GetScanCodeState) { } TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) { - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1731,7 +1722,7 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/); mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/); - KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1, + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); addMapperAndConfigure(mapper); @@ -1830,14 +1821,14 @@ void TrackballInputMapperTest::testMotionRotation(TrackballInputMapper* mapper, } TEST_F(TrackballInputMapperTest, GetSources) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources()); } TEST_F(TrackballInputMapperTest, PopulateDeviceInfo) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); InputDeviceInfo info; @@ -1850,7 +1841,7 @@ TEST_F(TrackballInputMapperTest, PopulateDeviceInfo) { } TEST_F(TrackballInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON); @@ -1898,7 +1889,7 @@ TEST_F(TrackballInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaS } TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentXYUpdates) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); FakeInputDispatcher::NotifyMotionArgs args; @@ -1922,7 +1913,7 @@ TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentXYUpdates) { } TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); FakeInputDispatcher::NotifyMotionArgs args; @@ -1943,7 +1934,7 @@ TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) { } TEST_F(TrackballInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); FakeInputDispatcher::NotifyMotionArgs args; @@ -1978,7 +1969,7 @@ TEST_F(TrackballInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) } TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); FakeInputDispatcher::NotifyMotionArgs args; @@ -1998,7 +1989,7 @@ TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeBu } TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); FakeInputDispatcher::NotifyMotionArgs args; @@ -2016,10 +2007,13 @@ TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f)); } -TEST_F(TrackballInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateMotions) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1); +TEST_F(TrackballInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) { + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); addMapperAndConfigure(mapper); + mFakePolicy->setDisplayInfo(DISPLAY_ID, + DISPLAY_WIDTH, DISPLAY_HEIGHT, + InputReaderPolicyInterface::ROTATION_90); ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1)); ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1)); ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0)); @@ -2030,8 +2024,9 @@ TEST_F(TrackballInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotat ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1)); } -TEST_F(TrackballInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateMotions) { - TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, DISPLAY_ID); +TEST_F(TrackballInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) { + TrackballInputMapper* mapper = new TrackballInputMapper(mDevice); + addConfigurationProperty("trackball.orientationAware", "1"); addMapperAndConfigure(mapper); mFakePolicy->setDisplayInfo(DISPLAY_ID, @@ -2232,24 +2227,26 @@ void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) { } -TEST_F(SingleTouchInputMapperTest, GetSources_WhenNotAttachedToADisplay_ReturnsTouchPad) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, -1); +TEST_F(SingleTouchInputMapperTest, GetSources_WhenDisplayTypeIsTouchPad_ReturnsTouchPad) { + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareAxes(POSITION); + addConfigurationProperty("touch.displayType", "touchPad"); addMapperAndConfigure(mapper); ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources()); } -TEST_F(SingleTouchInputMapperTest, GetSources_WhenAttachedToADisplay_ReturnsTouchScreen) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); +TEST_F(SingleTouchInputMapperTest, GetSources_WhenDisplayTypeIsTouchScreen_ReturnsTouchScreen) { + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareAxes(POSITION); + addConfigurationProperty("touch.displayType", "touchScreen"); addMapperAndConfigure(mapper); ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources()); } TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2276,7 +2273,7 @@ TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) { } TEST_F(SingleTouchInputMapperTest, GetScanCodeState) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2303,7 +2300,7 @@ TEST_F(SingleTouchInputMapperTest, GetScanCodeState) { } TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2319,7 +2316,7 @@ TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) { TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) { // Note: Ideally we should send cancels but the implementation is more straightforward // with up and this will only happen if a device is forcibly removed. - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2352,7 +2349,7 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) { } TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2378,7 +2375,7 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens } TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2427,7 +2424,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor } TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2541,7 +2538,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB } TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2609,7 +2606,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves } TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -2691,8 +2688,30 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) { ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled()); } -TEST_F(SingleTouchInputMapperTest, Process_Rotation) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); +TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) { + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); + prepareAxes(POSITION); + addConfigurationProperty("touch.orientationAware", "0"); + addMapperAndConfigure(mapper); + + FakeInputDispatcher::NotifyMotionArgs args; + + // Rotation 90. + prepareDisplay(InputReaderPolicyInterface::ROTATION_90); + processDown(mapper, toRawX(50), toRawY(75)); + processSync(mapper); + + ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args)); + ASSERT_NEAR(50, args.pointerCoords[0].x, 1); + ASSERT_NEAR(75, args.pointerCoords[0].y, 1); + + processUp(mapper); + processSync(mapper); + ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled()); +} + +TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) { + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareAxes(POSITION); addMapperAndConfigure(mapper); @@ -2752,7 +2771,7 @@ TEST_F(SingleTouchInputMapperTest, Process_Rotation) { } TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { - SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID); + SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | PRESSURE | TOOL); addMapperAndConfigure(mapper); @@ -2884,7 +2903,7 @@ void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) { TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION); prepareVirtualKeys(); @@ -3135,7 +3154,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin } TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | ID); prepareVirtualKeys(); @@ -3295,7 +3314,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId } TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR); addMapperAndConfigure(mapper); @@ -3340,11 +3359,11 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { } TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | TOUCH | TOOL | MINOR); - prepareCalibration("touch.touchSize.calibration", "geometric"); - prepareCalibration("touch.toolSize.calibration", "geometric"); + addConfigurationProperty("touch.touchSize.calibration", "geometric"); + addConfigurationProperty("touch.toolSize.calibration", "geometric"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. @@ -3381,17 +3400,17 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) } TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | TOUCH | TOOL); - prepareCalibration("touch.touchSize.calibration", "pressure"); - prepareCalibration("touch.toolSize.calibration", "linear"); - prepareCalibration("touch.toolSize.linearScale", "10"); - prepareCalibration("touch.toolSize.linearBias", "160"); - prepareCalibration("touch.toolSize.isSummed", "1"); - prepareCalibration("touch.pressure.calibration", "amplitude"); - prepareCalibration("touch.pressure.source", "touch"); - prepareCalibration("touch.pressure.scale", "0.01"); + addConfigurationProperty("touch.touchSize.calibration", "pressure"); + addConfigurationProperty("touch.toolSize.calibration", "linear"); + addConfigurationProperty("touch.toolSize.linearScale", "10"); + addConfigurationProperty("touch.toolSize.linearBias", "160"); + addConfigurationProperty("touch.toolSize.isSummed", "1"); + addConfigurationProperty("touch.pressure.calibration", "amplitude"); + addConfigurationProperty("touch.pressure.source", "touch"); + addConfigurationProperty("touch.pressure.scale", "0.01"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. @@ -3437,18 +3456,18 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinear } TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) { - MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID); + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); prepareDisplay(InputReaderPolicyInterface::ROTATION_0); prepareAxes(POSITION | TOUCH | TOOL); - prepareCalibration("touch.touchSize.calibration", "pressure"); - prepareCalibration("touch.toolSize.calibration", "area"); - prepareCalibration("touch.toolSize.areaScale", "22"); - prepareCalibration("touch.toolSize.areaBias", "1"); - prepareCalibration("touch.toolSize.linearScale", "9.2"); - prepareCalibration("touch.toolSize.linearBias", "3"); - prepareCalibration("touch.pressure.calibration", "amplitude"); - prepareCalibration("touch.pressure.source", "touch"); - prepareCalibration("touch.pressure.scale", "0.01"); + addConfigurationProperty("touch.touchSize.calibration", "pressure"); + addConfigurationProperty("touch.toolSize.calibration", "area"); + addConfigurationProperty("touch.toolSize.areaScale", "22"); + addConfigurationProperty("touch.toolSize.areaBias", "1"); + addConfigurationProperty("touch.toolSize.linearScale", "9.2"); + addConfigurationProperty("touch.toolSize.linearBias", "3"); + addConfigurationProperty("touch.pressure.calibration", "amplitude"); + addConfigurationProperty("touch.pressure.source", "touch"); + addConfigurationProperty("touch.pressure.scale", "0.01"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk index 9c01aea..8bd833b 100644 --- a/libs/utils/Android.mk +++ b/libs/utils/Android.mk @@ -28,6 +28,7 @@ commonSources:= \ Flattenable.cpp \ ObbFile.cpp \ Pool.cpp \ + PropertyMap.cpp \ RefBase.cpp \ ResourceTypes.cpp \ SharedBuffer.cpp \ diff --git a/libs/utils/PropertyMap.cpp b/libs/utils/PropertyMap.cpp new file mode 100644 index 0000000..fd7edec --- /dev/null +++ b/libs/utils/PropertyMap.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PropertyMap" + +#include <stdlib.h> +#include <string.h> + +#include <utils/PropertyMap.h> +#include <utils/Log.h> + +// Enables debug output for the parser. +#define DEBUG_PARSER 0 + +// Enables debug output for parser performance. +#define DEBUG_PARSER_PERFORMANCE 0 + + +namespace android { + +static const char* WHITESPACE = " \t\r"; +static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r="; + + +// --- PropertyMap --- + +PropertyMap::PropertyMap() { +} + +PropertyMap::~PropertyMap() { +} + +void PropertyMap::clear() { + mProperties.clear(); +} + +void PropertyMap::addProperty(const String8& key, const String8& value) { + mProperties.add(key, value); +} + +bool PropertyMap::hasProperty(const String8& key) const { + return mProperties.indexOfKey(key) >= 0; +} + +bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const { + ssize_t index = mProperties.indexOfKey(key); + if (index < 0) { + return false; + } + + outValue = mProperties.valueAt(index); + return true; +} + +bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const { + int32_t intValue; + if (!tryGetProperty(key, intValue)) { + return false; + } + + outValue = intValue; + return true; +} + +bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const { + String8 stringValue; + if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { + return false; + } + + char* end; + int value = strtol(stringValue.string(), & end, 10); + if (*end != '\0') { + LOGW("Property key '%s' has invalid value '%s'. Expected an integer.", + key.string(), stringValue.string()); + return false; + } + outValue = value; + return true; +} + +bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const { + String8 stringValue; + if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { + return false; + } + + char* end; + float value = strtof(stringValue.string(), & end); + if (*end != '\0') { + LOGW("Property key '%s' has invalid value '%s'. Expected a float.", + key.string(), stringValue.string()); + return false; + } + outValue = value; + return true; +} + +status_t PropertyMap::load(const String8& filename, PropertyMap** outMap) { + *outMap = NULL; + + Tokenizer* tokenizer; + status_t status = Tokenizer::open(filename, &tokenizer); + if (status) { + LOGE("Error %d opening property file %s.", status, filename.string()); + } else { + PropertyMap* map = new PropertyMap(); + if (!map) { + LOGE("Error allocating property map."); + status = NO_MEMORY; + } else { +#if DEBUG_PARSER_PERFORMANCE + nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC); +#endif + Parser parser(map, tokenizer); + status = parser.parse(); +#if DEBUG_PARSER_PERFORMANCE + nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime; + LOGD("Parsed property file '%s' %d lines in %0.3fms.", + tokenizer->getFilename().string(), tokenizer->getLineNumber(), + elapsedTime / 1000000.0); +#endif + if (status) { + delete map; + } else { + *outMap = map; + } + } + delete tokenizer; + } + return status; +} + + +// --- PropertyMap::Parser --- + +PropertyMap::Parser::Parser(PropertyMap* map, Tokenizer* tokenizer) : + mMap(map), mTokenizer(tokenizer) { +} + +PropertyMap::Parser::~Parser() { +} + +status_t PropertyMap::Parser::parse() { + while (!mTokenizer->isEof()) { +#if DEBUG_PARSER + LOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(), + mTokenizer->peekRemainderOfLine().string()); +#endif + + mTokenizer->skipDelimiters(WHITESPACE); + + if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') { + String8 keyToken = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER); + if (keyToken.isEmpty()) { + LOGE("%s: Expected non-empty property key.", mTokenizer->getLocation().string()); + return BAD_VALUE; + } + + mTokenizer->skipDelimiters(WHITESPACE); + + if (mTokenizer->nextChar() != '=') { + LOGE("%s: Expected '=' between property key and value.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + + mTokenizer->skipDelimiters(WHITESPACE); + + String8 valueToken = mTokenizer->nextToken(WHITESPACE); + if (valueToken.find("\\", 0) >= 0 || valueToken.find("\"", 0) >= 0) { + LOGE("%s: Found reserved character '\\' or '\"' in property value.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + + mTokenizer->skipDelimiters(WHITESPACE); + if (!mTokenizer->isEol()) { + LOGE("%s: Expected end of line, got '%s'.", + mTokenizer->getLocation().string(), + mTokenizer->peekRemainderOfLine().string()); + return BAD_VALUE; + } + + if (mMap->hasProperty(keyToken)) { + LOGE("%s: Duplicate property value for key '%s'.", + mTokenizer->getLocation().string(), keyToken.string()); + return BAD_VALUE; + } + + mMap->addProperty(keyToken, valueToken); + } + + mTokenizer->nextLine(); + } + return NO_ERROR; +} + +} // namespace android diff --git a/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java b/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java index a8dd76c..abed18f 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java +++ b/policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java @@ -32,7 +32,8 @@ import android.view.FallbackEventHandler; import android.view.KeyEvent; public class PhoneFallbackEventHandler implements FallbackEventHandler { - static String TAG = "PhoneFallbackEventHandler"; + private static String TAG = "PhoneFallbackEventHandler"; + private static final boolean DEBUG = false; Context mContext; View mView; @@ -180,7 +181,9 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler { } boolean onKeyUp(int keyCode, KeyEvent event) { - Slog.d(TAG, "up " + keyCode); + if (DEBUG) { + Slog.d(TAG, "up " + keyCode); + } final KeyEvent.DispatcherState dispatcher = mView.getKeyDispatcherState(); if (dispatcher != null) { dispatcher.handleUpEvent(event); diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java index 4364c04..30b49d3 100644 --- a/services/java/com/android/server/InputManager.java +++ b/services/java/com/android/server/InputManager.java @@ -41,7 +41,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Properties; /* * Wraps the C++ InputManager and provides its callbacks. @@ -368,11 +367,6 @@ public class InputManager { public int height; } - private static final class InputDeviceCalibration { - public String[] keys; - public String[] values; - } - /* * Callbacks from native. */ @@ -494,33 +488,6 @@ public class InputManager { } @SuppressWarnings("unused") - public InputDeviceCalibration getInputDeviceCalibration(String deviceName) { - // Calibration is specified as a sequence of colon-delimited key value pairs. - Properties properties = new Properties(); - File calibrationFile = new File(Environment.getRootDirectory(), - CALIBRATION_DIR_PATH + deviceName + ".idc"); - if (calibrationFile.exists()) { - try { - FileInputStream fis = new FileInputStream(calibrationFile); - properties.load(fis); - fis.close(); - } catch (IOException ex) { - Slog.w(TAG, "Error reading input device calibration properties for device " - + deviceName + " from " + calibrationFile + ".", ex); - } - } else { - Slog.i(TAG, "No input device calibration properties found for device " - + deviceName + "."); - return null; - } - - InputDeviceCalibration calibration = new InputDeviceCalibration(); - calibration.keys = properties.keySet().toArray(new String[properties.size()]); - calibration.values = properties.values().toArray(new String[properties.size()]); - return calibration; - } - - @SuppressWarnings("unused") public String[] getExcludedDeviceNames() { ArrayList<String> names = new ArrayList<String>(); diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index 3fd6965..d0760c0 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -57,7 +57,6 @@ static struct { jmethodID filterTouchEvents; jmethodID filterJumpyTouchEvents; jmethodID getVirtualKeyDefinitions; - jmethodID getInputDeviceCalibration; jmethodID getExcludedDeviceNames; jmethodID getMaxEventsPerSecond; } gCallbacksClassInfo; @@ -75,13 +74,6 @@ static struct { static struct { jclass clazz; - jfieldID keys; - jfieldID values; -} gInputDeviceCalibrationClassInfo; - -static struct { - jclass clazz; - jfieldID inputChannel; jfieldID name; jfieldID layoutParamsFlags; @@ -186,8 +178,6 @@ public: virtual bool filterJumpyTouchEvents(); virtual void getVirtualKeyDefinitions(const String8& deviceName, Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions); - virtual void getInputDeviceCalibration(const String8& deviceName, - InputDeviceCalibration& outCalibration); virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames); /* --- InputDispatcherPolicyInterface implementation --- */ @@ -489,48 +479,6 @@ void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName, } } -void NativeInputManager::getInputDeviceCalibration(const String8& deviceName, - InputDeviceCalibration& outCalibration) { - outCalibration.clear(); - - JNIEnv* env = jniEnv(); - - jstring deviceNameStr = env->NewStringUTF(deviceName.string()); - if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) { - jobject result = env->CallObjectMethod(mCallbacksObj, - gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr); - if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) { - jobjectArray keys = jobjectArray(env->GetObjectField(result, - gInputDeviceCalibrationClassInfo.keys)); - jobjectArray values = jobjectArray(env->GetObjectField(result, - gInputDeviceCalibrationClassInfo.values)); - - jsize length = env->GetArrayLength(keys); - for (jsize i = 0; i < length; i++) { - jstring keyStr = jstring(env->GetObjectArrayElement(keys, i)); - jstring valueStr = jstring(env->GetObjectArrayElement(values, i)); - - const char* keyChars = env->GetStringUTFChars(keyStr, NULL); - String8 key(keyChars); - env->ReleaseStringUTFChars(keyStr, keyChars); - - const char* valueChars = env->GetStringUTFChars(valueStr, NULL); - String8 value(valueChars); - env->ReleaseStringUTFChars(valueStr, valueChars); - - outCalibration.addProperty(key, value); - - env->DeleteLocalRef(keyStr); - env->DeleteLocalRef(valueStr); - } - env->DeleteLocalRef(keys); - env->DeleteLocalRef(values); - env->DeleteLocalRef(result); - } - env->DeleteLocalRef(deviceNameStr); - } -} - void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) { outExcludedDeviceNames.clear(); @@ -1405,10 +1353,6 @@ int register_android_server_InputManager(JNIEnv* env) { "getVirtualKeyDefinitions", "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;"); - GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz, - "getInputDeviceCalibration", - "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;"); - GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz, "getExcludedDeviceNames", "()[Ljava/lang/String;"); @@ -1435,17 +1379,6 @@ int register_android_server_InputManager(JNIEnv* env) { GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz, "height", "I"); - // InputDeviceCalibration - - FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz, - "com/android/server/InputManager$InputDeviceCalibration"); - - GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz, - "keys", "[Ljava/lang/String;"); - - GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz, - "values", "[Ljava/lang/String;"); - // InputWindow FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow"); |