InputDevice是InputReader中用来存储输入设备信息的类。与EventHub中的Device结构体相同,InputDevice也描述了一个输入设备,并
以设备Id为键保存在mDevices字典中。
InputDevice类与EventHub的Device结构体类似也保存了设备Id、厂商信息以及设备所属的类别。它们之间的一个重要差别是:InputDevice
相对于Device结构体多了一个InputMapper列表。
InputMapper是InputReader中实际进行原始事件加工的场所,它有一系列的子类,分别用于加工不同类型的原始输入事件。而InputDevice的
process()函数使用InputMapper的方式是一个简化了的职责链设计模式。InputDevice不需要直到那一个InputMapper可以处理一个原始输入
事件,只需将一个事件逐个交给每一个InputMapper尝试处理,如果InputMapper可以接受这个事件则处理之,否则什么都不做。
prcessEventsLocked()函数会根据EventHub的设备增删事件来创建和销毁InputDevice。
DEVICE_ADDED:调用addDeviceLocked()函数创建InputDevice
DEVICE_REMOVED:调用removeDeviceLocked()将InputDevice删除
FINISHED_DEVICE_SCAN:InputReader会产生一个ConfigurationChanged事件并将其发送给InputDispatcher。
/frameworks/native/services/inputflinger/InputReader.cpp
[InputReader.cpp–>InputReader::addDeviceLocked()]
void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
if (deviceIndex >= 0) {
ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
return;
}
/**
1 从EventHub中获取厂商信息与设备类别
*/
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
/**
2 创建InputDevice对象
*/
InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
/**
3 使用InputReader中保存的策略配置信息对创建的InputDevice进行策略配置,并通过reset()进行设备重置
mConfig是InputReaderConfiguration,这一来自InputReaderPolicy的配置信息是的IMS以及应用程序在一
定程度上影响输入事件的处理过程
*/
device->configure(when, &mConfig, 0);
device->reset(when);
if (device->isIgnored()) {
ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
identifier.name.string());
} else {
ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
identifier.name.string(), device->getSources());
}
/**
4 将设备放入mDevices中
*/
mDevices.add(deviceId, device);
bumpGenerationLocked();
if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
notifyExternalStylusPresenceChanged();
}
}
/frameworks/native/services/inputflinger/InputReader.cpp
[InputReader.cpp–>InputReader::createDeviceLocked()]
InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, uint32_t classes) {
/**
1. 根据设备Id,厂商信息以及设备类型创建一个InputDevice对象
*/
InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
controllerNumber, identifier, classes);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
device->setExternal(true);
}
// Devices with mics.
if (classes & INPUT_DEVICE_CLASS_MIC) {
device->setMic(true);
}
/**
2. 按照设备类型,为InputDevice添加特定类型的InputMapper
*/
// Switch-like devices.
if (classes & INPUT_DEVICE_CLASS_SWITCH) {
device->addMapper(new SwitchInputMapper(device));
}
// Scroll wheel-like devices.
if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
device->addMapper(new RotaryEncoderInputMapper(device));
}
// Vibrator-like devices.
if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
device->addMapper(new VibratorInputMapper(device));
}
// Keyboard-like devices.
uint32_t keyboardSource = 0;
int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
if (classes & INPUT_DEVICE_CLASS_DPAD) {
keyboardSource |= AINPUT_SOURCE_DPAD;
}
if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
if (keyboardSource != 0) {
device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
}
// Cursor-like devices.
if (classes & INPUT_DEVICE_CLASS_CURSOR) {
device->addMapper(new CursorInputMapper(device));
}
// Touchscreens and touchpad devices.
if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
device->addMapper(new MultiTouchInputMapper(device));
} else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
device->addMapper(new SingleTouchInputMapper(device));
}
// Joystick-like devices.
if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
device->addMapper(new JoystickInputMapper(device));
}
// External stylus-like devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
device->addMapper(new ExternalStylusInputMapper(device));
}
return device;
}
/frameworks/native/services/inputflinger/InputReader.cpp
[InputReader.cpp–>InputReader::InputDevice::InputDevice()]
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
mIdentifier(identifier), mClasses(classes),
mSources(0), mIsExternal(false), mHasMic(false), mDropUntilNextSync(false) {
}
[InputReader.cpp–>InputReader::InputDevice::addMapper()]
void InputDevice::addMapper(InputMapper* mapper) {
mMappers.add(mapper);
}
/frameworks/native/services/inputflinger/InputReader.h
Vector mMappers;
InputMapper