summaryrefslogtreecommitdiffstats
path: root/libs/ui/Input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/Input.cpp')
-rw-r--r--libs/ui/Input.cpp114
1 files changed, 110 insertions, 4 deletions
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 944a79b..b8d59e6 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -7,11 +7,117 @@
//#define LOG_NDEBUG 0
+#define DEBUG_PROBE 0
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.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 bool isValidNameChar(char ch) {
+ return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
+}
+
+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 (!isValidNameChar(ch)) {
+ ch = '_';
+ }
+ path.append(&ch, 1);
+ }
+ path.append(CONFIGURATION_FILE_EXTENSION[type]);
+}
+
+String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
+ const InputDeviceIdentifier& deviceIdentifier,
+ InputDeviceConfigurationFileType type) {
+ if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
+ if (deviceIdentifier.version != 0) {
+ // Try vendor product version.
+ String8 versionPath(getInputDeviceConfigurationFilePathByName(
+ String8::format("Vendor_%04x_Product_%04x_Version_%04x",
+ deviceIdentifier.vendor, deviceIdentifier.product,
+ deviceIdentifier.version),
+ type));
+ if (!versionPath.isEmpty()) {
+ return versionPath;
+ }
+ }
+
+ // Try vendor product.
+ String8 productPath(getInputDeviceConfigurationFilePathByName(
+ String8::format("Vendor_%04x_Product_%04x",
+ deviceIdentifier.vendor, deviceIdentifier.product),
+ type));
+ if (!productPath.isEmpty()) {
+ return productPath;
+ }
+ }
+
+ // Try device name.
+ return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
+}
+
+String8 getInputDeviceConfigurationFilePathByName(
+ 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 +129,7 @@ void InputEvent::initialize(const InputEvent& from) {
mSource = from.mSource;
}
-// class KeyEvent
+// --- KeyEvent ---
bool KeyEvent::hasDefaultAction(int32_t keyCode) {
switch (keyCode) {
@@ -131,7 +237,7 @@ void KeyEvent::initialize(const KeyEvent& from) {
mEventTime = from.mEventTime;
}
-// class MotionEvent
+// --- MotionEvent ---
void MotionEvent::initialize(
int32_t deviceId,
@@ -178,7 +284,7 @@ void MotionEvent::offsetLocation(float xOffset, float yOffset) {
mYOffset += yOffset;
}
-// class InputDeviceInfo
+// --- InputDeviceInfo ---
InputDeviceInfo::InputDeviceInfo() {
initialize(-1, String8("uninitialized device info"));