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
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 @@
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 @@
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 @@
uint32_t classes;
uint8_t* keyBitmask;
KeyLayoutMap* layoutMap;
+ String8 configurationFile;
+ PropertyMap* configuration;
KeyMapInfo keyMapInfo;
int fd;
device_t* next;
@@ -264,6 +271,7 @@
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 @@
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..cfceaab1 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -47,23 +47,6 @@
};
-/* 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 @@
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 @@
int32_t getMetaState();
- inline const InputDeviceCalibration& getCalibration() {
- return mCalibration;
+ inline const PropertyMap& getConfiguration() {
+ return mConfiguration;
}
private:
@@ -330,7 +309,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
Mutex mLock;
- int32_t mAssociatedDisplayId;
+ // Immutable configuration parameters.
+ struct Parameters {
+ int32_t associatedDisplayId;
+ bool orientationAware;
+ } mParameters;
struct Accumulator {
enum {
@@ -499,13 +491,16 @@
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 @@
}
};
- 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 @@
bool haveToolSizeAreaBias;
float toolSizeAreaBias;
bool haveToolSizeIsSummed;
- int32_t toolSizeIsSummed;
+ bool toolSizeIsSummed;
// Pressure
enum PressureCalibration {
@@ -846,7 +848,7 @@
class SingleTouchInputMapper : public TouchInputMapper {
public:
- SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+ SingleTouchInputMapper(InputDevice* device);
virtual ~SingleTouchInputMapper();
virtual void reset();
@@ -892,7 +894,7 @@
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 @@
};
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