Android 系统对于usb,蓝牙接口的触摸设备默认判断为外接设备,外接设备默认操控的是副屏,在双屏异显情况下就会发现只能点击到副屏。
frameworks/native/services/inputflinger/EventHub.cpp
status_t EventHub::openDeviceLocked(const char* devicePath) {
...
// Determine whether the device is external or internal.判断是否为外接设备,如果是加入外接设备标识
if (isExternalDeviceLocked(device)) {
device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
}
...
}
一种方法是不管判断条件是否通过都不加入这个标识;
即注释掉 device->classes |= INPUT_DEVICE_CLASS_EXTERNAL
,这种方法可以保证主屏一直能正常触控,但是副屏如果再接触摸就无法正常触控。
frameworks/native/services/inputflinger/EventHub.cpp
bool EventHub::isExternalDeviceLocked(Device* device) {
if (device->configuration) {
bool value;
if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
return !value;
}
}
//设备标识符未USB或蓝牙设备返回true 即外接设备
return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
}
此处发现除了设备标识符还可以通过device.internal
属性来控制是否为外接设备,这个属性是输入设备配置文件(.idc)文件里面的属性。
idc 是Input Device Configuration的缩写,输入设备配置文件(.idc文件)包含特定设备的配置属性,这些属性会影响输入设备的行为。
输入设备配置文件通常并非标准外围设备(例如HID键盘和鼠标)所必需的,因为默认的系统行为通常可确保它们即插即用。另一方面,
内置的嵌入式设备(尤其是触摸屏)几乎总是需要输入设备配置文件来指定其行为。
/odm/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/vendor/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/system/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/data/system/devices/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
/odm/usr/idc/Vendor_XXXX_Product_XXXX.idc
/vendor/usr/idc/Vendor_XXXX_Product_XXXX.idc
/system/usr/idc/Vendor_XXXX_Product_XXXX.idc
/data/system/devices/idc/Vendor_XXXX_Product_XXXX.idc
/odm/usr/idc/device-name.idc
/vendor/usr/idc/device-name.idc
/system/usr/idc/device-name.idc
/data/system/devices/idc/device-name.idc
当构建包含设备名称的文件路径时,设备名称中除 “0-9”、“a-z”、“A-Z”、“-”或“”之外的所有字符将替换为“”。
# 0 外部设备,1 内部设备
# 触摸唤醒参数,当设置为0时,系统休眠点击触摸屏可以唤醒,1则反之。
device.internal = 0
# 定义:keyboard.layout =
# 指定与设备关联的键布局文件名称,不包含.kl扩展名。如果找不到此文件,输入系统将使用默认键布局。
keyboard.layout = qwerty
# 定义:keyboard.characterMap =
# 指定与输入设备关联的键字符映射文件的名称,不包括.kcm扩展名。 如果找不到此文件,输入系统将使用默认的键字符映射。在查找期间,名称中的空格将转换为下划线。
keyboard.characterMap = qwerty
#定义:keyboard.orientationAware = 0 |1
#指定键盘是否应对显示方向更改做出反应,如果值为1,则在关联的显示方向改变时旋转方向键盘键,如果值为0,则键盘不受显示方向更改的影响。默认值为0。
#方向感知用于支持方向键盘键的旋转,例如Motorola Droid上的旋转。 例如,当设备从其自然方向顺时针旋转90度时,KEYCODE_DPAD_UP被重新映射以产生KEYCODE_DPAD_RIGHT,因为当设备保持在该方向时,“向上”键最终指向“右”。
keyboard.orientationAware = 1
#定义:keyboard.builtIn = 0 |1
#指定键盘是否为内置(物理连接)键盘,如果设备名称以-keypad结尾,则默认值为1,否则为0。
#内置键盘的设备ID始终为0.其他非内置键盘将分配唯一的非零设备ID。
#对于内置键盘使用id为0对于保持与KeyCharacterMap.BUILT_IN_KEYBOARD字段的兼容性非常重要,该字段指定内置键盘的id并且值为0.此字段已在API中弃用但较旧 应用程序可能仍在使用它。无论此属性的设置如何,特殊功能键盘(其键字符映射指定SPECIAL_FUNCTION的类型)将永远不会注册为内置键盘。
keyboard.builtIn = 1
Eventhub在打开设备时会读取设备的idc文件.
->Eventhub.openDeviceLocked->loadConfigurationLocked
void EventHub::loadConfigurationLocked(Device* device) {
device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
if (device->configurationFile.isEmpty()) {
ALOGD("No input device configuration file found for device '%s'.",
device->identifier.name.string());
} else {
status_t status = PropertyMap::load(device->configurationFile,
&device->configuration);
if (status) {
ALOGE("Error loading input device configuration file for device '%s'. "
"Using default configuration.",
device->identifier.name.string());
}
}
}
综上可知,我们需要添加idc文件来控制触摸屏的属性。
adb shell dumpsys input //列出系统目前所有的输入设备的信息
3: ILITEK ILITEK-TP
Classes: 0x00000014
Path: /dev/input/event0
Enabled: true
Descriptor: f1b4838838e240568fcbdd50c0f63be308c623ef
Location: usb-ff500000.usb-1.3/input0
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0003, vendor=0x222a, product=0x0001, version=0x0110
KeyLayoutFile:
KeyCharacterMapFile:
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
Vendor_222a_Product_0001.idc
# Filename:Vendor_222a_Product_0001.idc
# My TouchScreen Device configuration file.
touch.deviceType = touchScreen
device.internal = 1
touch.orientationAware = 1
keyboard.layout = Vendor_222a_Product_0001
keyboard.orientationAware = 1
cursor.mode = navigation
cursor.orientationAware = 1
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/Vendor_222a_Product_0001.idc:vendor/usr/idc/Vendor_222a_Product_0001.idc
编译系统固件升级,触摸屏即能正常操控主屏。
frameworks/native/services/inputflinger/InputReader.cpp
// Initial downs on external touch devices should wake the device.
// Normally we don't do this for internal touch screens to prevent them from waking
// up in your pocket but you can enable it using the input device configuration.
- mParameters.wake = getDevice()->isExternal();
+ mParameters.wake = true;
getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"),
mParameters.wake);