InputDevice.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "InputDevice"
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <ctype.h>
  20. #include <input/InputDevice.h>
  21. namespace android {
  22. static const char* CONFIGURATION_FILE_DIR[] = {
  23. "idc/",
  24. "keylayout/",
  25. "keychars/",
  26. };
  27. static const char* CONFIGURATION_FILE_EXTENSION[] = {
  28. ".idc",
  29. ".kl",
  30. ".kcm",
  31. };
  32. static bool isValidNameChar(char ch) {
  33. return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
  34. }
  35. static void appendInputDeviceConfigurationFileRelativePath(String8& path,
  36. const String8& name, InputDeviceConfigurationFileType type) {
  37. path.append(CONFIGURATION_FILE_DIR[type]);
  38. for (size_t i = 0; i < name.length(); i++) {
  39. char ch = name[i];
  40. if (!isValidNameChar(ch)) {
  41. ch = '_';
  42. }
  43. path.append(&ch, 1);
  44. }
  45. path.append(CONFIGURATION_FILE_EXTENSION[type]);
  46. }
  47. String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
  48. const InputDeviceIdentifier& deviceIdentifier,
  49. InputDeviceConfigurationFileType type) {
  50. if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
  51. if (deviceIdentifier.version != 0) {
  52. // Try vendor product version.
  53. String8 versionPath(getInputDeviceConfigurationFilePathByName(
  54. String8::format("Vendor_%04x_Product_%04x_Version_%04x",
  55. deviceIdentifier.vendor, deviceIdentifier.product,
  56. deviceIdentifier.version),
  57. type));
  58. if (!versionPath.isEmpty()) {
  59. return versionPath;
  60. }
  61. }
  62. // Try vendor product.
  63. String8 productPath(getInputDeviceConfigurationFilePathByName(
  64. String8::format("Vendor_%04x_Product_%04x",
  65. deviceIdentifier.vendor, deviceIdentifier.product),
  66. type));
  67. if (!productPath.isEmpty()) {
  68. return productPath;
  69. }
  70. }
  71. // Try device name.
  72. return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
  73. }
  74. String8 getInputDeviceConfigurationFilePathByName(
  75. const String8& name, InputDeviceConfigurationFileType type) {
  76. // Search system repository.
  77. String8 path;
  78. path.setTo(getenv("ANDROID_ROOT"));
  79. path.append("/usr/");
  80. appendInputDeviceConfigurationFileRelativePath(path, name, type);
  81. #if DEBUG_PROBE
  82. ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
  83. #endif
  84. if (!access(path.string(), R_OK)) {
  85. #if DEBUG_PROBE
  86. ALOGD("Found");
  87. #endif
  88. return path;
  89. }
  90. // Search user repository.
  91. // TODO Should only look here if not in safe mode.
  92. path.setTo(getenv("ANDROID_DATA"));
  93. path.append("/system/devices/");
  94. appendInputDeviceConfigurationFileRelativePath(path, name, type);
  95. #if DEBUG_PROBE
  96. ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
  97. #endif
  98. if (!access(path.string(), R_OK)) {
  99. #if DEBUG_PROBE
  100. ALOGD("Found");
  101. #endif
  102. return path;
  103. }
  104. // Not found.
  105. #if DEBUG_PROBE
  106. ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
  107. name.string(), type);
  108. #endif
  109. return String8();
  110. }
  111. // --- InputDeviceInfo ---
  112. InputDeviceInfo::InputDeviceInfo() {
  113. initialize(-1, 0, -1, InputDeviceIdentifier(), String8(), false, false);
  114. }
  115. InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
  116. mId(other.mId), mGeneration(other.mGeneration), mControllerNumber(other.mControllerNumber),
  117. mIdentifier(other.mIdentifier), mAlias(other.mAlias), mIsExternal(other.mIsExternal),
  118. mHasMic(other.mHasMic), mSources(other.mSources),
  119. mKeyboardType(other.mKeyboardType), mKeyCharacterMap(other.mKeyCharacterMap),
  120. mHasVibrator(other.mHasVibrator), mHasButtonUnderPad(other.mHasButtonUnderPad),
  121. mMotionRanges(other.mMotionRanges) {
  122. }
  123. InputDeviceInfo::~InputDeviceInfo() {
  124. }
  125. void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
  126. const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal,
  127. bool hasMic) {
  128. mId = id;
  129. mGeneration = generation;
  130. mControllerNumber = controllerNumber;
  131. mIdentifier = identifier;
  132. mAlias = alias;
  133. mIsExternal = isExternal;
  134. mHasMic = hasMic;
  135. mSources = 0;
  136. mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
  137. mHasVibrator = false;
  138. mHasButtonUnderPad = false;
  139. mMotionRanges.clear();
  140. }
  141. const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
  142. int32_t axis, uint32_t source) const {
  143. size_t numRanges = mMotionRanges.size();
  144. for (size_t i = 0; i < numRanges; i++) {
  145. const MotionRange& range = mMotionRanges.itemAt(i);
  146. if (range.axis == axis && range.source == source) {
  147. return &range;
  148. }
  149. }
  150. return NULL;
  151. }
  152. void InputDeviceInfo::addSource(uint32_t source) {
  153. mSources |= source;
  154. }
  155. void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
  156. float flat, float fuzz, float resolution) {
  157. MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
  158. mMotionRanges.add(range);
  159. }
  160. void InputDeviceInfo::addMotionRange(const MotionRange& range) {
  161. mMotionRanges.add(range);
  162. }
  163. } // namespace android