19f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown/* 29f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Copyright (C) 2012 The Android Open Source Project 39f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 49f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 59f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * you may not use this file except in compliance with the License. 69f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * You may obtain a copy of the License at 79f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 89f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 99f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * 109f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * Unless required by applicable law or agreed to in writing, software 119f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * See the License for the specific language governing permissions and 149f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown * limitations under the License. 159f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown */ 169f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 179f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#define LOG_TAG "InputDevice" 189f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 199f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#include <stdlib.h> 209f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#include <unistd.h> 219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#include <ctype.h> 229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 239f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#include <androidfw/InputDevice.h> 249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 259f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownnamespace android { 269f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 279f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownstatic const char* CONFIGURATION_FILE_DIR[] = { 289f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown "idc/", 299f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown "keylayout/", 309f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown "keychars/", 319f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown}; 329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 339f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownstatic const char* CONFIGURATION_FILE_EXTENSION[] = { 349f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ".idc", 359f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ".kl", 369f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ".kcm", 379f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown}; 389f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 399f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownstatic bool isValidNameChar(char ch) { 409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_'); 419f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 429f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 439f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownstatic void appendInputDeviceConfigurationFileRelativePath(String8& path, 449f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown const String8& name, InputDeviceConfigurationFileType type) { 459f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.append(CONFIGURATION_FILE_DIR[type]); 469f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown for (size_t i = 0; i < name.length(); i++) { 479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown char ch = name[i]; 489f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!isValidNameChar(ch)) { 499f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ch = '_'; 509f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 519f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.append(&ch, 1); 529f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 539f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.append(CONFIGURATION_FILE_EXTENSION[type]); 549f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 559f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 569f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff BrownString8 getInputDeviceConfigurationFilePathByDeviceIdentifier( 579f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown const InputDeviceIdentifier& deviceIdentifier, 589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown InputDeviceConfigurationFileType type) { 599f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) { 609f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (deviceIdentifier.version != 0) { 619f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Try vendor product version. 629f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String8 versionPath(getInputDeviceConfigurationFilePathByName( 639f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String8::format("Vendor_%04x_Product_%04x_Version_%04x", 649f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown deviceIdentifier.vendor, deviceIdentifier.product, 659f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown deviceIdentifier.version), 669f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown type)); 679f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!versionPath.isEmpty()) { 689f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return versionPath; 699f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Try vendor product. 739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String8 productPath(getInputDeviceConfigurationFilePathByName( 749f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String8::format("Vendor_%04x_Product_%04x", 759f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown deviceIdentifier.vendor, deviceIdentifier.product), 769f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown type)); 779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!productPath.isEmpty()) { 789f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return productPath; 799f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 809f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Try device name. 839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type); 849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 859f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 869f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff BrownString8 getInputDeviceConfigurationFilePathByName( 879f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown const String8& name, InputDeviceConfigurationFileType type) { 889f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Search system repository. 899f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown String8 path; 909f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.setTo(getenv("ANDROID_ROOT")); 919f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.append("/usr/"); 929f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown appendInputDeviceConfigurationFileRelativePath(path, name, type); 939f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#if DEBUG_PROBE 949f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ALOGD("Probing for system provided input device configuration file: path='%s'", path.string()); 959f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#endif 969f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!access(path.string(), R_OK)) { 979f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#if DEBUG_PROBE 989f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ALOGD("Found"); 999f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#endif 1009f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return path; 1019f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1029f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1039f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Search user repository. 1049f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // TODO Should only look here if not in safe mode. 1059f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.setTo(getenv("ANDROID_DATA")); 1069f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown path.append("/system/devices/"); 1079f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown appendInputDeviceConfigurationFileRelativePath(path, name, type); 1089f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#if DEBUG_PROBE 1099f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ALOGD("Probing for system user input device configuration file: path='%s'", path.string()); 1109f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#endif 1119f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (!access(path.string(), R_OK)) { 1129f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#if DEBUG_PROBE 1139f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ALOGD("Found"); 1149f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#endif 1159f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return path; 1169f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1179f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1189f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown // Not found. 1199f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#if DEBUG_PROBE 1209f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown ALOGD("Probe failed to find input device configuration file: name='%s', type=%d", 1219f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown name.string(), type); 1229f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown#endif 1239f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return String8(); 1249f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1259f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1269f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1279f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown// --- InputDeviceInfo --- 1289f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1299f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff BrownInputDeviceInfo::InputDeviceInfo() { 130daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown initialize(-1, -1, InputDeviceIdentifier(), String8(), false); 1319f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1329f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1339f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff BrownInputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : 1345bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier), 135daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown mAlias(other.mAlias), mIsExternal(other.mIsExternal), mSources(other.mSources), 1369f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mKeyboardType(other.mKeyboardType), 1379f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mKeyCharacterMap(other.mKeyCharacterMap), 138a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mHasVibrator(other.mHasVibrator), 1399f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mMotionRanges(other.mMotionRanges) { 1409f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1419f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1429f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff BrownInputDeviceInfo::~InputDeviceInfo() { 1439f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1449f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 145af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brownvoid InputDeviceInfo::initialize(int32_t id, int32_t generation, 146daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) { 1479f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mId = id; 148af9e8d38184c6ba4d2d3eb5bde7014a66dd8a78bJeff Brown mGeneration = generation; 1495bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown mIdentifier = identifier; 1505bbd4b4f5fc19302fa017ad6afee6eb2d489d91aJeff Brown mAlias = alias; 151daa3753a04699724d2cfe824ac1f5a266d643a05Jeff Brown mIsExternal = isExternal; 1529f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mSources = 0; 1539f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; 154a47425a13c19f95057df78b8bb65bb25657e8753Jeff Brown mHasVibrator = false; 1559f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mMotionRanges.clear(); 1569f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1579f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1589f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownconst InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( 1599f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown int32_t axis, uint32_t source) const { 1609f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown size_t numRanges = mMotionRanges.size(); 1619f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown for (size_t i = 0; i < numRanges; i++) { 1629f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown const MotionRange& range = mMotionRanges.itemAt(i); 1639f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown if (range.axis == axis && range.source == source) { 1649f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return ⦥ 1659f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1669f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown } 1679f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown return NULL; 1689f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1699f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1709f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownvoid InputDeviceInfo::addSource(uint32_t source) { 1719f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mSources |= source; 1729f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1739f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1749f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownvoid InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, 1759f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown float flat, float fuzz) { 1769f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown MotionRange range = { axis, source, min, max, flat, fuzz }; 1779f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mMotionRanges.add(range); 1789f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1799f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1809f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brownvoid InputDeviceInfo::addMotionRange(const MotionRange& range) { 1819f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown mMotionRanges.add(range); 1829f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} 1839f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown 1849f25b7fdf216c9ef0bd2322cd223eeaf0d60f77fJeff Brown} // namespace android 185