diff options
| author | 2012-04-13 04:09:27 -0700 | |
|---|---|---|
| committer | 2012-04-13 17:01:15 -0700 | |
| commit | a47425a13c19f95057df78b8bb65bb25657e8753 (patch) | |
| tree | 675c0d6bf611f2427bb3d11315d410bf9087b20a /services/input/EventHub.cpp | |
| parent | c2346134bb519a54d50655cbef940fc3fdec60a9 (diff) | |
Add support for input devices that have vibrators.
Added a getVibrator() method to InputDevice which returns a Vibrator
associated with that input device. Its uses the same API as the
system vibrator which makes it easy for applications to be modified
to use one or the other.
Bug: 6334179
Change-Id: Ifc7f13dbcb778670f3f1c07ccc562334e6109d2e
Diffstat (limited to 'services/input/EventHub.cpp')
| -rw-r--r-- | services/input/EventHub.cpp | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index fbffc947aeb3..c0eb1b934b1e 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -161,12 +161,14 @@ EventHub::Device::Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier) : next(NULL), fd(fd), id(id), path(path), identifier(identifier), - classes(0), configuration(NULL), virtualKeyMap(NULL) { + classes(0), configuration(NULL), virtualKeyMap(NULL), + ffEffectPlaying(false), ffEffectId(-1) { memset(keyBitmask, 0, sizeof(keyBitmask)); memset(absBitmask, 0, sizeof(absBitmask)); memset(relBitmask, 0, sizeof(relBitmask)); memset(swBitmask, 0, sizeof(swBitmask)); memset(ledBitmask, 0, sizeof(ledBitmask)); + memset(ffBitmask, 0, sizeof(ffBitmask)); memset(propBitmask, 0, sizeof(propBitmask)); } @@ -534,6 +536,62 @@ sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { return NULL; } +void EventHub::vibrate(int32_t deviceId, nsecs_t duration) { + AutoMutex _l(mLock); + Device* device = getDeviceLocked(deviceId); + if (device && !device->isVirtual()) { + ff_effect effect; + memset(&effect, 0, sizeof(effect)); + effect.type = FF_RUMBLE; + effect.id = device->ffEffectId; + effect.u.rumble.strong_magnitude = 0xc000; + effect.u.rumble.weak_magnitude = 0xc000; + effect.replay.length = (duration + 999999LL) / 1000000LL; + effect.replay.delay = 0; + if (ioctl(device->fd, EVIOCSFF, &effect)) { + ALOGW("Could not upload force feedback effect to device %s due to error %d.", + device->identifier.name.string(), errno); + return; + } + device->ffEffectId = effect.id; + + struct input_event ev; + ev.time.tv_sec = 0; + ev.time.tv_usec = 0; + ev.type = EV_FF; + ev.code = device->ffEffectId; + ev.value = 1; + if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { + ALOGW("Could not start force feedback effect on device %s due to error %d.", + device->identifier.name.string(), errno); + return; + } + device->ffEffectPlaying = true; + } +} + +void EventHub::cancelVibrate(int32_t deviceId) { + AutoMutex _l(mLock); + Device* device = getDeviceLocked(deviceId); + if (device && !device->isVirtual()) { + if (device->ffEffectPlaying) { + device->ffEffectPlaying = false; + + struct input_event ev; + ev.time.tv_sec = 0; + ev.time.tv_usec = 0; + ev.type = EV_FF; + ev.code = device->ffEffectId; + ev.value = 0; + if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { + ALOGW("Could not stop force feedback effect on device %s due to error %d.", + device->identifier.name.string(), errno); + return; + } + } + } +} + EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const { if (deviceId == BUILT_IN_KEYBOARD_ID) { deviceId = mBuiltInKeyboardId; @@ -949,6 +1007,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask); ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask); ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask); + ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask); ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask); // See if this is a keyboard. Ignore everything in the button range except for @@ -1010,6 +1069,11 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { } } + // Check whether this device supports the vibrator. + if (test_bit(FF_RUMBLE, device->ffBitmask)) { + device->classes |= INPUT_DEVICE_CLASS_VIBRATOR; + } + // Configure virtual keys. if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) { // Load the virtual keys for the touch screen, if any. |