Android Input之InputDevice

InputDevice

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。

InputDevice的创建

/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

你可能感兴趣的:(Android,Input,android,input)