summaryrefslogtreecommitdiffstats
path: root/widget/gonk/libui
diff options
context:
space:
mode:
Diffstat (limited to 'widget/gonk/libui')
-rw-r--r--widget/gonk/libui/EventHub.cpp1549
-rw-r--r--widget/gonk/libui/EventHub.h435
-rw-r--r--widget/gonk/libui/Input.cpp635
-rw-r--r--widget/gonk/libui/Input.h622
-rw-r--r--widget/gonk/libui/InputApplication.cpp42
-rw-r--r--widget/gonk/libui/InputApplication.h83
-rw-r--r--widget/gonk/libui/InputDevice.cpp184
-rw-r--r--widget/gonk/libui/InputDevice.h156
-rw-r--r--widget/gonk/libui/InputDispatcher.cpp4430
-rw-r--r--widget/gonk/libui/InputDispatcher.h1117
-rw-r--r--widget/gonk/libui/InputListener.cpp182
-rw-r--r--widget/gonk/libui/InputListener.h196
-rw-r--r--widget/gonk/libui/InputManager.cpp93
-rw-r--r--widget/gonk/libui/InputManager.h109
-rw-r--r--widget/gonk/libui/InputReader.cpp6510
-rw-r--r--widget/gonk/libui/InputReader.h1811
-rw-r--r--widget/gonk/libui/InputTransport.cpp957
-rw-r--r--widget/gonk/libui/InputTransport.h443
-rw-r--r--widget/gonk/libui/InputWindow.cpp64
-rw-r--r--widget/gonk/libui/InputWindow.h205
-rw-r--r--widget/gonk/libui/KeyCharacterMap.cpp1153
-rw-r--r--widget/gonk/libui/KeyCharacterMap.h257
-rw-r--r--widget/gonk/libui/KeyLayoutMap.cpp446
-rw-r--r--widget/gonk/libui/KeyLayoutMap.h117
-rw-r--r--widget/gonk/libui/Keyboard.cpp300
-rw-r--r--widget/gonk/libui/Keyboard.h122
-rw-r--r--widget/gonk/libui/KeycodeLabels.h380
-rw-r--r--widget/gonk/libui/PointerController.cpp604
-rw-r--r--widget/gonk/libui/PointerController.h266
-rw-r--r--widget/gonk/libui/PowerManager.h33
-rw-r--r--widget/gonk/libui/SpriteController.cpp515
-rw-r--r--widget/gonk/libui/SpriteController.h319
-rw-r--r--widget/gonk/libui/Tokenizer.cpp175
-rw-r--r--widget/gonk/libui/Tokenizer.h136
-rw-r--r--widget/gonk/libui/Trace.h64
-rw-r--r--widget/gonk/libui/VelocityControl.cpp110
-rw-r--r--widget/gonk/libui/VelocityControl.h107
-rw-r--r--widget/gonk/libui/VelocityTracker.cpp929
-rw-r--r--widget/gonk/libui/VelocityTracker.h269
-rw-r--r--widget/gonk/libui/VirtualKeyMap.cpp171
-rw-r--r--widget/gonk/libui/VirtualKeyMap.h81
-rw-r--r--widget/gonk/libui/android_input.h850
-rw-r--r--widget/gonk/libui/android_keycodes.h315
-rw-r--r--widget/gonk/libui/cutils_log.h569
-rw-r--r--widget/gonk/libui/cutils_trace.h276
-rw-r--r--widget/gonk/libui/linux_input.h1029
-rw-r--r--widget/gonk/libui/sha1.c289
-rw-r--r--widget/gonk/libui/sha1.h31
48 files changed, 0 insertions, 29736 deletions
diff --git a/widget/gonk/libui/EventHub.cpp b/widget/gonk/libui/EventHub.cpp
deleted file mode 100644
index 9da29bbeb..000000000
--- a/widget/gonk/libui/EventHub.cpp
+++ /dev/null
@@ -1,1549 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "EventHub"
-
-// #define LOG_NDEBUG 0
-#include "cutils_log.h"
-
-#include "EventHub.h"
-
-#include <hardware_legacy/power.h>
-
-#include <cutils/properties.h>
-#include "cutils_log.h"
-#include <utils/Timers.h>
-#include <utils/threads.h>
-#include <utils/Errors.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-#include "KeyLayoutMap.h"
-#include "KeyCharacterMap.h"
-#include "VirtualKeyMap.h"
-
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-
-#include <sys/inotify.h>
-#include <sys/epoll.h>
-#include <sys/ioctl.h>
-#include <sys/limits.h>
-#include "sha1.h"
-
-/* this macro is used to tell if "bit" is set in "array"
- * it selects a byte from the array, and does a boolean AND
- * operation with a byte that only has the relevant bit set.
- * eg. to check for the 12th bit, we do (array[1] & 1<<4)
- */
-#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8)))
-
-/* this macro computes the number of bytes needed to represent a bit array of the specified size */
-#define sizeof_bit_array(bits) ((bits + 7) / 8)
-
-#define INDENT " "
-#define INDENT2 " "
-#define INDENT3 " "
-
-namespace android {
-
-static const char *WAKE_LOCK_ID = "KeyEvents";
-static const char *DEVICE_PATH = "/dev/input";
-
-/* return the larger integer */
-static inline int max(int v1, int v2)
-{
- return (v1 > v2) ? v1 : v2;
-}
-
-static inline const char* toString(bool value) {
- return value ? "true" : "false";
-}
-
-static String8 sha1(const String8& in) {
- SHA1_CTX ctx;
- SHA1Init(&ctx);
- SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
- u_char digest[SHA1_DIGEST_LENGTH];
- SHA1Final(digest, &ctx);
-
- String8 out;
- for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) {
- out.appendFormat("%02x", digest[i]);
- }
- return out;
-}
-
-static void setDescriptor(InputDeviceIdentifier& identifier) {
- // Compute a device descriptor that uniquely identifies the device.
- // The descriptor is assumed to be a stable identifier. Its value should not
- // change between reboots, reconnections, firmware updates or new releases of Android.
- // Ideally, we also want the descriptor to be short and relatively opaque.
- String8 rawDescriptor;
- rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product);
- if (!identifier.uniqueId.isEmpty()) {
- rawDescriptor.append("uniqueId:");
- rawDescriptor.append(identifier.uniqueId);
- } if (identifier.vendor == 0 && identifier.product == 0) {
- // If we don't know the vendor and product id, then the device is probably
- // built-in so we need to rely on other information to uniquely identify
- // the input device. Usually we try to avoid relying on the device name or
- // location but for built-in input device, they are unlikely to ever change.
- if (!identifier.name.isEmpty()) {
- rawDescriptor.append("name:");
- rawDescriptor.append(identifier.name);
- } else if (!identifier.location.isEmpty()) {
- rawDescriptor.append("location:");
- rawDescriptor.append(identifier.location);
- }
- }
- identifier.descriptor = sha1(rawDescriptor);
- ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
- identifier.descriptor.string());
-}
-
-// --- Global Functions ---
-
-uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
- // Touch devices get dibs on touch-related axes.
- if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) {
- switch (axis) {
- case ABS_X:
- case ABS_Y:
- case ABS_PRESSURE:
- case ABS_TOOL_WIDTH:
- case ABS_DISTANCE:
- case ABS_TILT_X:
- case ABS_TILT_Y:
- case ABS_MT_SLOT:
- case ABS_MT_TOUCH_MAJOR:
- case ABS_MT_TOUCH_MINOR:
- case ABS_MT_WIDTH_MAJOR:
- case ABS_MT_WIDTH_MINOR:
- case ABS_MT_ORIENTATION:
- case ABS_MT_POSITION_X:
- case ABS_MT_POSITION_Y:
- case ABS_MT_TOOL_TYPE:
- case ABS_MT_BLOB_ID:
- case ABS_MT_TRACKING_ID:
- case ABS_MT_PRESSURE:
- case ABS_MT_DISTANCE:
- return INPUT_DEVICE_CLASS_TOUCH;
- }
- }
-
- // Joystick devices get the rest.
- return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK;
-}
-
-// --- EventHub::Device ---
-
-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),
- ffEffectPlaying(false), ffEffectId(-1),
- timestampOverrideSec(0), timestampOverrideUsec(0) {
- 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));
-}
-
-EventHub::Device::~Device() {
- close();
- delete configuration;
- delete virtualKeyMap;
-}
-
-void EventHub::Device::close() {
- if (fd >= 0) {
- ::close(fd);
- fd = -1;
- }
-}
-
-
-// --- EventHub ---
-
-const uint32_t EventHub::EPOLL_ID_INOTIFY;
-const uint32_t EventHub::EPOLL_ID_WAKE;
-const int EventHub::EPOLL_SIZE_HINT;
-const int EventHub::EPOLL_MAX_EVENTS;
-
-EventHub::EventHub(void) :
- mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1),
- mOpeningDevices(0), mClosingDevices(0),
- mNeedToSendFinishedDeviceScan(false),
- mNeedToReopenDevices(false), mNeedToScanDevices(true),
- mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
- mEpollFd = epoll_create(EPOLL_SIZE_HINT);
- LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
-
- mINotifyFd = inotify_init();
- int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
- LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s. errno=%d",
- DEVICE_PATH, errno);
-
- struct epoll_event eventItem;
- memset(&eventItem, 0, sizeof(eventItem));
- eventItem.events = EPOLLIN;
- eventItem.data.u32 = EPOLL_ID_INOTIFY;
- result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno);
-
- int wakeFds[2];
- result = pipe(wakeFds);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
-
- mWakeReadPipeFd = wakeFds[0];
- mWakeWritePipeFd = wakeFds[1];
-
- result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d",
- errno);
-
- result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
- errno);
-
- eventItem.data.u32 = EPOLL_ID_WAKE;
- result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d",
- errno);
-}
-
-EventHub::~EventHub(void) {
- closeAllDevicesLocked();
-
- while (mClosingDevices) {
- Device* device = mClosingDevices;
- mClosingDevices = device->next;
- delete device;
- }
-
- ::close(mEpollFd);
- ::close(mINotifyFd);
- ::close(mWakeReadPipeFd);
- ::close(mWakeWritePipeFd);
-
- release_wake_lock(WAKE_LOCK_ID);
-}
-
-InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device == NULL) return InputDeviceIdentifier();
- return device->identifier;
-}
-
-uint32_t EventHub::getDeviceClasses(int32_t deviceId) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device == NULL) return 0;
- return device->classes;
-}
-
-void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device && device->configuration) {
- *outConfiguration = *device->configuration;
- } else {
- outConfiguration->clear();
- }
-}
-
-status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
- RawAbsoluteAxisInfo* outAxisInfo) const {
- outAxisInfo->clear();
-
- if (axis >= 0 && axis <= ABS_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
- struct input_absinfo info;
- if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
- ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
- axis, device->identifier.name.string(), device->fd, errno);
- return -errno;
- }
-
- if (info.minimum != info.maximum) {
- outAxisInfo->valid = true;
- outAxisInfo->minValue = info.minimum;
- outAxisInfo->maxValue = info.maximum;
- outAxisInfo->flat = info.flat;
- outAxisInfo->fuzz = info.fuzz;
- outAxisInfo->resolution = info.resolution;
- }
- return OK;
- }
- }
- return -1;
-}
-
-bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
- if (axis >= 0 && axis <= REL_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device) {
- return test_bit(axis, device->relBitmask);
- }
- }
- return false;
-}
-
-bool EventHub::hasInputProperty(int32_t deviceId, int property) const {
- if (property >= 0 && property <= INPUT_PROP_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device) {
- return test_bit(property, device->propBitmask);
- }
- }
- return false;
-}
-
-int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
- if (scanCode >= 0 && scanCode <= KEY_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) {
- uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
- memset(keyState, 0, sizeof(keyState));
- if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
- return test_bit(scanCode, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
- }
- }
- }
- return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) {
- Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
- if (scanCodes.size() != 0) {
- uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
- memset(keyState, 0, sizeof(keyState));
- if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
- for (size_t i = 0; i < scanCodes.size(); i++) {
- int32_t sc = scanCodes.itemAt(i);
- if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) {
- return AKEY_STATE_DOWN;
- }
- }
- return AKEY_STATE_UP;
- }
- }
- }
- return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
- if (sw >= 0 && sw <= SW_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) {
- uint8_t swState[sizeof_bit_array(SW_MAX + 1)];
- memset(swState, 0, sizeof(swState));
- if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) {
- return test_bit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
- }
- }
- }
- return AKEY_STATE_UNKNOWN;
-}
-
-status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
- *outValue = 0;
-
- if (axis >= 0 && axis <= ABS_MAX) {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
- struct input_absinfo info;
- if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
- ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
- axis, device->identifier.name.string(), device->fd, errno);
- return -errno;
- }
-
- *outValue = info.value;
- return OK;
- }
- }
- return -1;
-}
-
-bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) const {
- AutoMutex _l(mLock);
-
- Device* device = getDeviceLocked(deviceId);
- if (device && device->keyMap.haveKeyLayout()) {
- Vector<int32_t> scanCodes;
- for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
- scanCodes.clear();
-
- status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey(
- keyCodes[codeIndex], &scanCodes);
- if (! err) {
- // check the possible scan codes identified by the layout map against the
- // map of codes actually emitted by the driver
- for (size_t sc = 0; sc < scanCodes.size(); sc++) {
- if (test_bit(scanCodes[sc], device->keyBitmask)) {
- outFlags[codeIndex] = 1;
- break;
- }
- }
- }
- }
- return true;
- }
- return false;
-}
-
-status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
- int32_t* outKeycode, uint32_t* outFlags) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
-
- if (device) {
- // Check the key character map first.
- sp<KeyCharacterMap> kcm = device->getKeyCharacterMap();
- if (kcm != NULL) {
- if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
- *outFlags = 0;
- return NO_ERROR;
- }
- }
-
- // Check the key layout next.
- if (device->keyMap.haveKeyLayout()) {
- if (!device->keyMap.keyLayoutMap->mapKey(
- scanCode, usageCode, outKeycode, outFlags)) {
- return NO_ERROR;
- }
- }
- }
-
- *outKeycode = 0;
- *outFlags = 0;
- return NAME_NOT_FOUND;
-}
-
-status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
-
- if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo);
- if (err == NO_ERROR) {
- return NO_ERROR;
- }
- }
-
- return NAME_NOT_FOUND;
-}
-
-void EventHub::setExcludedDevices(const Vector<String8>& devices) {
- AutoMutex _l(mLock);
-
- mExcludedDevices = devices;
-}
-
-bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device && scanCode >= 0 && scanCode <= KEY_MAX) {
- if (test_bit(scanCode, device->keyBitmask)) {
- return true;
- }
- }
- return false;
-}
-
-bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device && led >= 0 && led <= LED_MAX) {
- if (test_bit(led, device->ledBitmask)) {
- return true;
- }
- }
- return false;
-}
-
-void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) {
- struct input_event ev;
- ev.time.tv_sec = 0;
- ev.time.tv_usec = 0;
- ev.type = EV_LED;
- ev.code = led;
- ev.value = on ? 1 : 0;
-
- ssize_t nWrite;
- do {
- nWrite = write(device->fd, &ev, sizeof(struct input_event));
- } while (nWrite == -1 && errno == EINTR);
- }
-}
-
-void EventHub::getVirtualKeyDefinitions(int32_t deviceId,
- Vector<VirtualKeyDefinition>& outVirtualKeys) const {
- outVirtualKeys.clear();
-
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device && device->virtualKeyMap) {
- outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys());
- }
-}
-
-sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device) {
- return device->getKeyCharacterMap();
- }
- return NULL;
-}
-
-bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId,
- const sp<KeyCharacterMap>& map) {
- AutoMutex _l(mLock);
- Device* device = getDeviceLocked(deviceId);
- if (device) {
- if (map != device->overlayKeyMap) {
- device->overlayKeyMap = map;
- device->combinedKeyMap = KeyCharacterMap::combine(
- device->keyMap.keyCharacterMap, map);
- return true;
- }
- }
- return false;
-}
-
-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;
- }
- ssize_t index = mDevices.indexOfKey(deviceId);
- return index >= 0 ? mDevices.valueAt(index) : NULL;
-}
-
-EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const {
- for (size_t i = 0; i < mDevices.size(); i++) {
- Device* device = mDevices.valueAt(i);
- if (device->path == devicePath) {
- return device;
- }
- }
- return NULL;
-}
-
-size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
- ALOG_ASSERT(bufferSize >= 1);
-
- AutoMutex _l(mLock);
-
- struct input_event readBuffer[bufferSize];
-
- RawEvent* event = buffer;
- size_t capacity = bufferSize;
- bool awoken = false;
- for (;;) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
- // Reopen input devices if needed.
- if (mNeedToReopenDevices) {
- mNeedToReopenDevices = false;
-
- ALOGI("Reopening all input devices due to a configuration change.");
-
- closeAllDevicesLocked();
- mNeedToScanDevices = true;
- break; // return to the caller before we actually rescan
- }
-
- // Report any devices that had last been added/removed.
- while (mClosingDevices) {
- Device* device = mClosingDevices;
- ALOGV("Reporting device closed: id=%d, name=%s\n",
- device->id, device->path.string());
- mClosingDevices = device->next;
- event->when = now;
- event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
- event->type = DEVICE_REMOVED;
- event += 1;
- delete device;
- mNeedToSendFinishedDeviceScan = true;
- if (--capacity == 0) {
- break;
- }
- }
-
- if (mNeedToScanDevices) {
- mNeedToScanDevices = false;
- scanDevicesLocked();
- mNeedToSendFinishedDeviceScan = true;
- }
-
- while (mOpeningDevices != NULL) {
- Device* device = mOpeningDevices;
- ALOGV("Reporting device opened: id=%d, name=%s\n",
- device->id, device->path.string());
- mOpeningDevices = device->next;
- event->when = now;
- event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
- event->type = DEVICE_ADDED;
- event += 1;
- mNeedToSendFinishedDeviceScan = true;
- if (--capacity == 0) {
- break;
- }
- }
-
- if (mNeedToSendFinishedDeviceScan) {
- mNeedToSendFinishedDeviceScan = false;
- event->when = now;
- event->type = FINISHED_DEVICE_SCAN;
- event += 1;
- if (--capacity == 0) {
- break;
- }
- }
-
- // Grab the next input event.
- bool deviceChanged = false;
- while (mPendingEventIndex < mPendingEventCount) {
- const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
- if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {
- if (eventItem.events & EPOLLIN) {
- mPendingINotify = true;
- } else {
- ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
- }
- continue;
- }
-
- if (eventItem.data.u32 == EPOLL_ID_WAKE) {
- if (eventItem.events & EPOLLIN) {
- ALOGV("awoken after wake()");
- awoken = true;
- char buffer[16];
- ssize_t nRead;
- do {
- nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
- } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
- } else {
- ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.",
- eventItem.events);
- }
- continue;
- }
-
- ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32);
- if (deviceIndex < 0) {
- ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.",
- eventItem.events, eventItem.data.u32);
- continue;
- }
-
- Device* device = mDevices.valueAt(deviceIndex);
- if (eventItem.events & EPOLLIN) {
- int32_t readSize = read(device->fd, readBuffer,
- sizeof(struct input_event) * capacity);
- if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
- // Device was removed before INotify noticed.
- ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d "
- "capacity: %d errno: %d)\n",
- device->fd, readSize, bufferSize, capacity, errno);
- deviceChanged = true;
- closeDeviceLocked(device);
- } else if (readSize < 0) {
- if (errno != EAGAIN && errno != EINTR) {
- ALOGW("could not get event (errno=%d)", errno);
- }
- } else if ((readSize % sizeof(struct input_event)) != 0) {
- ALOGE("could not get event (wrong size: %d)", readSize);
- } else {
- int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
-
- size_t count = size_t(readSize) / sizeof(struct input_event);
- for (size_t i = 0; i < count; i++) {
- struct input_event& iev = readBuffer[i];
- ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
- device->path.string(),
- (int) iev.time.tv_sec, (int) iev.time.tv_usec,
- iev.type, iev.code, iev.value);
-
- // Some input devices may have a better concept of the time
- // when an input event was actually generated than the kernel
- // which simply timestamps all events on entry to evdev.
- // This is a custom Android extension of the input protocol
- // mainly intended for use with uinput based device drivers.
- if (iev.type == EV_MSC) {
- if (iev.code == MSC_ANDROID_TIME_SEC) {
- device->timestampOverrideSec = iev.value;
- continue;
- } else if (iev.code == MSC_ANDROID_TIME_USEC) {
- device->timestampOverrideUsec = iev.value;
- continue;
- }
- }
- if (device->timestampOverrideSec || device->timestampOverrideUsec) {
- iev.time.tv_sec = device->timestampOverrideSec;
- iev.time.tv_usec = device->timestampOverrideUsec;
- if (iev.type == EV_SYN && iev.code == SYN_REPORT) {
- device->timestampOverrideSec = 0;
- device->timestampOverrideUsec = 0;
- }
- ALOGV("applied override time %d.%06d",
- int(iev.time.tv_sec), int(iev.time.tv_usec));
- }
-
-#ifdef HAVE_POSIX_CLOCKS
- // Use the time specified in the event instead of the current time
- // so that downstream code can get more accurate estimates of
- // event dispatch latency from the time the event is enqueued onto
- // the evdev client buffer.
- //
- // The event's timestamp fortuitously uses the same monotonic clock
- // time base as the rest of Android. The kernel event device driver
- // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts().
- // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere
- // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a
- // system call that also queries ktime_get_ts().
- event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
- + nsecs_t(iev.time.tv_usec) * 1000LL;
- ALOGV("event time %lld, now %lld", event->when, now);
-
- // Bug 7291243: Add a guard in case the kernel generates timestamps
- // that appear to be far into the future because they were generated
- // using the wrong clock source.
- //
- // This can happen because when the input device is initially opened
- // it has a default clock source of CLOCK_REALTIME. Any input events
- // enqueued right after the device is opened will have timestamps
- // generated using CLOCK_REALTIME. We later set the clock source
- // to CLOCK_MONOTONIC but it is already too late.
- //
- // Invalid input event timestamps can result in ANRs, crashes and
- // and other issues that are hard to track down. We must not let them
- // propagate through the system.
- //
- // Log a warning so that we notice the problem and recover gracefully.
- if (event->when >= now + 10 * 1000000000LL) {
- // Double-check. Time may have moved on.
- nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC);
- if (event->when > time) {
- ALOGW("An input event from %s has a timestamp that appears to "
- "have been generated using the wrong clock source "
- "(expected CLOCK_MONOTONIC): "
- "event time %lld, current time %lld, call time %lld. "
- "Using current time instead.",
- device->path.string(), event->when, time, now);
- event->when = time;
- } else {
- ALOGV("Event time is ok but failed the fast path and required "
- "an extra call to systemTime: "
- "event time %lld, current time %lld, call time %lld.",
- event->when, time, now);
- }
- }
-#else
- event->when = now;
-#endif
- event->deviceId = deviceId;
- event->type = iev.type;
- event->code = iev.code;
- event->value = iev.value;
- event += 1;
- capacity -= 1;
- }
- if (capacity == 0) {
- // The result buffer is full. Reset the pending event index
- // so we will try to read the device again on the next iteration.
- mPendingEventIndex -= 1;
- break;
- }
- }
- } else if (eventItem.events & EPOLLHUP) {
- ALOGI("Removing device %s due to epoll hang-up event.",
- device->identifier.name.string());
- deviceChanged = true;
- closeDeviceLocked(device);
- } else {
- ALOGW("Received unexpected epoll event 0x%08x for device %s.",
- eventItem.events, device->identifier.name.string());
- }
- }
-
- // readNotify() will modify the list of devices so this must be done after
- // processing all other events to ensure that we read all remaining events
- // before closing the devices.
- if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
- mPendingINotify = false;
- readNotifyLocked();
- deviceChanged = true;
- }
-
- // Report added or removed devices immediately.
- if (deviceChanged) {
- continue;
- }
-
- // Return now if we have collected any events or if we were explicitly awoken.
- if (event != buffer || awoken) {
- break;
- }
-
- // Poll for events. Mind the wake lock dance!
- // We hold a wake lock at all times except during epoll_wait(). This works due to some
- // subtle choreography. When a device driver has pending (unread) events, it acquires
- // a kernel wake lock. However, once the last pending event has been read, the device
- // driver will release the kernel wake lock. To prevent the system from going to sleep
- // when this happens, the EventHub holds onto its own user wake lock while the client
- // is processing events. Thus the system can only sleep if there are no events
- // pending or currently being processed.
- //
- // The timeout is advisory only. If the device is asleep, it will not wake just to
- // service the timeout.
- mPendingEventIndex = 0;
-
- mLock.unlock(); // release lock before poll, must be before release_wake_lock
- release_wake_lock(WAKE_LOCK_ID);
-
- int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
-
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
- mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock
-
- if (pollResult == 0) {
- // Timed out.
- mPendingEventCount = 0;
- break;
- }
-
- if (pollResult < 0) {
- // An error occurred.
- mPendingEventCount = 0;
-
- // Sleep after errors to avoid locking up the system.
- // Hopefully the error is transient.
- if (errno != EINTR) {
- ALOGW("poll failed (errno=%d)\n", errno);
- usleep(100000);
- }
- } else {
- // Some events occurred.
- mPendingEventCount = size_t(pollResult);
- }
- }
-
- // All done, return the number of events we read.
- return event - buffer;
-}
-
-void EventHub::wake() {
- ALOGV("wake() called");
-
- ssize_t nWrite;
- do {
- nWrite = write(mWakeWritePipeFd, "W", 1);
- } while (nWrite == -1 && errno == EINTR);
-
- if (nWrite != 1 && errno != EAGAIN) {
- ALOGW("Could not write wake signal, errno=%d", errno);
- }
-}
-
-void EventHub::scanDevicesLocked() {
- status_t res = scanDirLocked(DEVICE_PATH);
- if(res < 0) {
- ALOGE("scan dir failed for %s\n", DEVICE_PATH);
- }
- if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
- createVirtualKeyboardLocked();
- }
-}
-
-// ----------------------------------------------------------------------------
-
-static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
- const uint8_t* end = array + endIndex;
- array += startIndex;
- while (array != end) {
- if (*(array++) != 0) {
- return true;
- }
- }
- return false;
-}
-
-static const int32_t GAMEPAD_KEYCODES[] = {
- AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C,
- AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z,
- AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1,
- AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
- AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
- AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE,
- AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4,
- AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8,
- AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12,
- AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16,
-};
-
-status_t EventHub::openDeviceLocked(const char *devicePath) {
- char buffer[80];
-
- ALOGV("Opening device: %s", devicePath);
-
- int fd = open(devicePath, O_RDWR | O_CLOEXEC);
- if(fd < 0) {
- ALOGE("could not open %s, %s\n", devicePath, strerror(errno));
- return -1;
- }
-
- InputDeviceIdentifier identifier;
-
- // Get device name.
- if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
- //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno));
- } else {
- buffer[sizeof(buffer) - 1] = '\0';
- identifier.name.setTo(buffer);
- }
-
- // Check to see if the device is on our excluded list
- for (size_t i = 0; i < mExcludedDevices.size(); i++) {
- const String8& item = mExcludedDevices.itemAt(i);
- if (identifier.name == item) {
- ALOGI("ignoring event id %s driver %s\n", devicePath, item.string());
- close(fd);
- return -1;
- }
- }
-
- // Get device driver version.
- int driverVersion;
- if(ioctl(fd, EVIOCGVERSION, &driverVersion)) {
- ALOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno));
- close(fd);
- return -1;
- }
-
- // Get device identifier.
- struct input_id inputId;
- if(ioctl(fd, EVIOCGID, &inputId)) {
- ALOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno));
- close(fd);
- return -1;
- }
- identifier.bus = inputId.bustype;
- identifier.product = inputId.product;
- identifier.vendor = inputId.vendor;
- identifier.version = inputId.version;
-
- // Get device physical location.
- if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
- //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
- } else {
- buffer[sizeof(buffer) - 1] = '\0';
- identifier.location.setTo(buffer);
- }
-
- // Get device unique id.
- if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
- //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
- } else {
- buffer[sizeof(buffer) - 1] = '\0';
- identifier.uniqueId.setTo(buffer);
- }
-
- // Fill in the descriptor.
- setDescriptor(identifier);
-
- // Make file descriptor non-blocking for use with poll().
- if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
- ALOGE("Error %d making device file descriptor non-blocking.", errno);
- close(fd);
- return -1;
- }
-
- // Allocate device. (The device object takes ownership of the fd at this point.)
- int32_t deviceId = mNextDeviceId++;
- Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
-
- ALOGV("add device %d: %s\n", deviceId, devicePath);
- ALOGV(" bus: %04x\n"
- " vendor %04x\n"
- " product %04x\n"
- " version %04x\n",
- identifier.bus, identifier.vendor, identifier.product, identifier.version);
- ALOGV(" name: \"%s\"\n", identifier.name.string());
- ALOGV(" location: \"%s\"\n", identifier.location.string());
- ALOGV(" unique id: \"%s\"\n", identifier.uniqueId.string());
- ALOGV(" descriptor: \"%s\"\n", identifier.descriptor.string());
- ALOGV(" driver: v%d.%d.%d\n",
- driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
-
- // Load the configuration file for the device.
- loadConfigurationLocked(device);
-
- // Figure out the kinds of events the device reports.
- ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask);
- ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask);
- 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
- // joystick and gamepad buttons which are handled like keyboards for the most part.
- bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC))
- || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK),
- sizeof_bit_array(KEY_MAX + 1));
- bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC),
- sizeof_bit_array(BTN_MOUSE))
- || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK),
- sizeof_bit_array(BTN_DIGI));
- if (haveKeyboardKeys || haveGamepadButtons) {
- device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
- }
-
- // See if this is a cursor device such as a trackball or mouse.
- if (test_bit(BTN_MOUSE, device->keyBitmask)
- && test_bit(REL_X, device->relBitmask)
- && test_bit(REL_Y, device->relBitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_CURSOR;
- }
-
- // See if this is a touch pad.
- // Is this a new modern multi-touch driver?
- if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
- && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) {
- // Some joysticks such as the PS3 controller report axes that conflict
- // with the ABS_MT range. Try to confirm that the device really is
- // a touch screen.
- if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) {
- device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
- }
- // Is this an old style single-touch driver?
- } else if (test_bit(BTN_TOUCH, device->keyBitmask)
- && test_bit(ABS_X, device->absBitmask)
- && test_bit(ABS_Y, device->absBitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_TOUCH;
- }
-
- // See if this device is a joystick.
- // Assumes that joysticks always have gamepad buttons in order to distinguish them
- // from other devices such as accelerometers that also have absolute axes.
- if (haveGamepadButtons) {
- uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK;
- for (int i = 0; i <= ABS_MAX; i++) {
- if (test_bit(i, device->absBitmask)
- && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) {
- device->classes = assumedClasses;
- break;
- }
- }
- }
-
- // Check whether this device has switches.
- for (int i = 0; i <= SW_MAX; i++) {
- if (test_bit(i, device->swBitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_SWITCH;
- break;
- }
- }
-
- // 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.
- // We do this now so that we can make sure to load the keymap if necessary.
- status_t status = loadVirtualKeyMapLocked(device);
- if (!status) {
- device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
- }
- }
-
- // Load the key map.
- // We need to do this for joysticks too because the key layout may specify axes.
- status_t keyMapStatus = NAME_NOT_FOUND;
- if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) {
- // Load the keymap for the device.
- keyMapStatus = loadKeyMapLocked(device);
- }
-
- // Configure the keyboard, gamepad or virtual keyboard.
- if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) {
- // Register the keyboard as a built-in keyboard if it is eligible.
- if (!keyMapStatus
- && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD
- && isEligibleBuiltInKeyboard(device->identifier,
- device->configuration, &device->keyMap)) {
- mBuiltInKeyboardId = device->id;
- }
-
- // 'Q' key support = cheap test of whether this is an alpha-capable kbd
- if (hasKeycodeLocked(device, AKEYCODE_Q)) {
- device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
- }
-
- // See if this device has a DPAD.
- if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&
- hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) {
- device->classes |= INPUT_DEVICE_CLASS_DPAD;
- }
-
- // See if this device has a gamepad.
- for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) {
- if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) {
- device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;
- break;
- }
- }
-
- // Disable kernel key repeat since we handle it ourselves
- unsigned int repeatRate[] = {0,0};
- if (ioctl(fd, EVIOCSREP, repeatRate)) {
- ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno));
- }
- }
-
- // If the device isn't recognized as something we handle, don't monitor it.
- if (device->classes == 0) {
- ALOGV("Dropping device: id=%d, path='%s', name='%s'",
- deviceId, devicePath, device->identifier.name.string());
- delete device;
- return -1;
- }
-
- // Determine whether the device is external or internal.
- if (isExternalDeviceLocked(device)) {
- device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
- }
-
- // Register with epoll.
- struct epoll_event eventItem;
- memset(&eventItem, 0, sizeof(eventItem));
- eventItem.events = EPOLLIN;
- eventItem.data.u32 = deviceId;
- if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
- ALOGE("Could not add device fd to epoll instance. errno=%d", errno);
- delete device;
- return -1;
- }
-
- // Enable wake-lock behavior on kernels that support it.
- // TODO: Only need this for devices that can really wake the system.
- bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1);
-
- // Tell the kernel that we want to use the monotonic clock for reporting timestamps
- // associated with input events. This is important because the input system
- // uses the timestamps extensively and assumes they were recorded using the monotonic
- // clock.
- //
- // In older kernel, before Linux 3.4, there was no way to tell the kernel which
- // clock to use to input event timestamps. The standard kernel behavior was to
- // record a real time timestamp, which isn't what we want. Android kernels therefore
- // contained a patch to the evdev_event() function in drivers/input/evdev.c to
- // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic
- // clock to be used instead of the real time clock.
- //
- // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock.
- // Therefore, we no longer require the Android-specific kernel patch described above
- // as long as we make sure to set select the monotonic clock. We do that here.
- int clockId = CLOCK_MONOTONIC;
- bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
-
- ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
- "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
- "usingSuspendBlockIoctl=%s, usingClockIoctl=%s",
- deviceId, fd, devicePath, device->identifier.name.string(),
- device->classes,
- device->configurationFile.string(),
- device->keyMap.keyLayoutFile.string(),
- device->keyMap.keyCharacterMapFile.string(),
- toString(mBuiltInKeyboardId == deviceId),
- toString(usingSuspendBlockIoctl), toString(usingClockIoctl));
-
- addDeviceLocked(device);
- return 0;
-}
-
-void EventHub::createVirtualKeyboardLocked() {
- InputDeviceIdentifier identifier;
- identifier.name = "Virtual";
- identifier.uniqueId = "<virtual>";
- setDescriptor(identifier);
-
- Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier);
- device->classes = INPUT_DEVICE_CLASS_KEYBOARD
- | INPUT_DEVICE_CLASS_ALPHAKEY
- | INPUT_DEVICE_CLASS_DPAD
- | INPUT_DEVICE_CLASS_VIRTUAL;
- loadKeyMapLocked(device);
- addDeviceLocked(device);
-}
-
-void EventHub::addDeviceLocked(Device* device) {
- mDevices.add(device->id, device);
- device->next = mOpeningDevices;
- mOpeningDevices = device;
-}
-
-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());
- }
- }
-}
-
-status_t EventHub::loadVirtualKeyMapLocked(Device* device) {
- // The virtual key map is supplied by the kernel as a system board property file.
- String8 path;
- path.append("/sys/board_properties/virtualkeys.");
- path.append(device->identifier.name);
- if (access(path.string(), R_OK)) {
- return NAME_NOT_FOUND;
- }
- return VirtualKeyMap::load(path, &device->virtualKeyMap);
-}
-
-status_t EventHub::loadKeyMapLocked(Device* device) {
- return device->keyMap.load(device->identifier, device->configuration);
-}
-
-bool EventHub::isExternalDeviceLocked(Device* device) {
- if (device->configuration) {
- bool value;
- if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
- return !value;
- }
- }
- return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH;
-}
-
-bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
- if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
- return false;
- }
-
- Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
- const size_t N = scanCodes.size();
- for (size_t i=0; i<N && i<=KEY_MAX; i++) {
- int32_t sc = scanCodes.itemAt(i);
- if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
- return true;
- }
- }
-
- return false;
-}
-
-status_t EventHub::closeDeviceByPathLocked(const char *devicePath) {
- Device* device = getDeviceByPathLocked(devicePath);
- if (device) {
- closeDeviceLocked(device);
- return 0;
- }
- ALOGV("Remove device: %s not found, device may already have been removed.", devicePath);
- return -1;
-}
-
-void EventHub::closeAllDevicesLocked() {
- while (mDevices.size() > 0) {
- closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1));
- }
-}
-
-void EventHub::closeDeviceLocked(Device* device) {
- ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
- device->path.string(), device->identifier.name.string(), device->id,
- device->fd, device->classes);
-
- if (device->id == mBuiltInKeyboardId) {
- ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
- device->path.string(), mBuiltInKeyboardId);
- mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
- }
-
- if (!device->isVirtual()) {
- if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) {
- ALOGW("Could not remove device fd from epoll instance. errno=%d", errno);
- }
- }
-
- mDevices.removeItem(device->id);
- device->close();
-
- // Unlink for opening devices list if it is present.
- Device* pred = NULL;
- bool found = false;
- for (Device* entry = mOpeningDevices; entry != NULL; ) {
- if (entry == device) {
- found = true;
- break;
- }
- pred = entry;
- entry = entry->next;
- }
- if (found) {
- // Unlink the device from the opening devices list then delete it.
- // We don't need to tell the client that the device was closed because
- // it does not even know it was opened in the first place.
- ALOGI("Device %s was immediately closed after opening.", device->path.string());
- if (pred) {
- pred->next = device->next;
- } else {
- mOpeningDevices = device->next;
- }
- delete device;
- } else {
- // Link into closing devices list.
- // The device will be deleted later after we have informed the client.
- device->next = mClosingDevices;
- mClosingDevices = device;
- }
-}
-
-status_t EventHub::readNotifyLocked() {
- int res;
- char devname[PATH_MAX];
- char *filename;
- char event_buf[512];
- int event_size;
- int event_pos = 0;
- struct inotify_event *event;
-
- ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd);
- res = read(mINotifyFd, event_buf, sizeof(event_buf));
- if(res < (int)sizeof(*event)) {
- if(errno == EINTR)
- return 0;
- ALOGW("could not get event, %s\n", strerror(errno));
- return -1;
- }
- //printf("got %d bytes of event information\n", res);
-
- strcpy(devname, DEVICE_PATH);
- filename = devname + strlen(devname);
- *filename++ = '/';
-
- while(res >= (int)sizeof(*event)) {
- event = (struct inotify_event *)(event_buf + event_pos);
- //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
- if(event->len) {
- strcpy(filename, event->name);
- if(event->mask & IN_CREATE) {
- openDeviceLocked(devname);
- } else {
- ALOGI("Removing device '%s' due to inotify event\n", devname);
- closeDeviceByPathLocked(devname);
- }
- }
- event_size = sizeof(*event) + event->len;
- res -= event_size;
- event_pos += event_size;
- }
- return 0;
-}
-
-status_t EventHub::scanDirLocked(const char *dirname)
-{
- char devname[PATH_MAX];
- char *filename;
- DIR *dir;
- struct dirent *de;
- dir = opendir(dirname);
- if(dir == NULL)
- return -1;
- strcpy(devname, dirname);
- filename = devname + strlen(devname);
- *filename++ = '/';
- while((de = readdir(dir))) {
- if(de->d_name[0] == '.' &&
- (de->d_name[1] == '\0' ||
- (de->d_name[1] == '.' && de->d_name[2] == '\0')))
- continue;
- strcpy(filename, de->d_name);
- openDeviceLocked(devname);
- }
- closedir(dir);
- return 0;
-}
-
-void EventHub::requestReopenDevices() {
- ALOGV("requestReopenDevices() called");
-
- AutoMutex _l(mLock);
- mNeedToReopenDevices = true;
-}
-
-void EventHub::dump(String8& dump) {
- dump.append("Event Hub State:\n");
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId);
-
- dump.append(INDENT "Devices:\n");
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- const Device* device = mDevices.valueAt(i);
- if (mBuiltInKeyboardId == device->id) {
- dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
- device->id, device->identifier.name.string());
- } else {
- dump.appendFormat(INDENT2 "%d: %s\n", device->id,
- device->identifier.name.string());
- }
- dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
- dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
- dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
- dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
- dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
- dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
- "product=0x%04x, version=0x%04x\n",
- device->identifier.bus, device->identifier.vendor,
- device->identifier.product, device->identifier.version);
- dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n",
- device->keyMap.keyLayoutFile.string());
- dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n",
- device->keyMap.keyCharacterMapFile.string());
- dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
- device->configurationFile.string());
- dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
- toString(device->overlayKeyMap != NULL));
- }
- } // release lock
-}
-
-void EventHub::monitor() {
- // Acquire and release the lock to ensure that the event hub has not deadlocked.
- mLock.lock();
- mLock.unlock();
-}
-
-
-}; // namespace android
diff --git a/widget/gonk/libui/EventHub.h b/widget/gonk/libui/EventHub.h
deleted file mode 100644
index e4e658b21..000000000
--- a/widget/gonk/libui/EventHub.h
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-#ifndef _RUNTIME_EVENT_HUB_H
-#define _RUNTIME_EVENT_HUB_H
-
-#include "Input.h"
-#include "InputDevice.h"
-#include "Keyboard.h"
-#include "KeyLayoutMap.h"
-#include "KeyCharacterMap.h"
-#include "VirtualKeyMap.h"
-#include <utils/String8.h>
-#include <utils/threads.h>
-#include "cutils_log.h"
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include <utils/PropertyMap.h>
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-
-#include "linux_input.h"
-#include <sys/epoll.h>
-
-/* Convenience constants. */
-
-#define BTN_FIRST 0x100 // first button code
-#define BTN_LAST 0x15f // last button code
-
-/*
- * These constants are used privately in Android to pass raw timestamps
- * through evdev from uinput device drivers because there is currently no
- * other way to transfer this information. The evdev driver automatically
- * timestamps all input events with the time they were posted and clobbers
- * whatever information was passed in.
- *
- * For the purposes of this hack, the timestamp is specified in the
- * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying
- * seconds and microseconds.
- */
-#define MSC_ANDROID_TIME_SEC 0x6
-#define MSC_ANDROID_TIME_USEC 0x7
-
-namespace android {
-
-enum {
- // Device id of a special "virtual" keyboard that is always present.
- VIRTUAL_KEYBOARD_ID = -1,
- // Device id of the "built-in" keyboard if there is one.
- BUILT_IN_KEYBOARD_ID = 0,
-};
-
-/*
- * A raw event as retrieved from the EventHub.
- */
-struct RawEvent {
- nsecs_t when;
- int32_t deviceId;
- int32_t type;
- int32_t code;
- int32_t value;
-};
-
-/* Describes an absolute axis. */
-struct RawAbsoluteAxisInfo {
- bool valid; // true if the information is valid, false otherwise
-
- int32_t minValue; // minimum value
- int32_t maxValue; // maximum value
- int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
- int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
- int32_t resolution; // resolution in units per mm or radians per mm
-
- inline void clear() {
- valid = false;
- minValue = 0;
- maxValue = 0;
- flat = 0;
- fuzz = 0;
- resolution = 0;
- }
-};
-
-/*
- * Input device classes.
- */
-enum {
- /* The input device is a keyboard or has buttons. */
- INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001,
-
- /* The input device is an alpha-numeric keyboard (not just a dial pad). */
- INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002,
-
- /* The input device is a touchscreen or a touchpad (either single-touch or multi-touch). */
- INPUT_DEVICE_CLASS_TOUCH = 0x00000004,
-
- /* The input device is a cursor device such as a trackball or mouse. */
- INPUT_DEVICE_CLASS_CURSOR = 0x00000008,
-
- /* The input device is a multi-touch touchscreen. */
- INPUT_DEVICE_CLASS_TOUCH_MT = 0x00000010,
-
- /* The input device is a directional pad (implies keyboard, has DPAD keys). */
- INPUT_DEVICE_CLASS_DPAD = 0x00000020,
-
- /* The input device is a gamepad (implies keyboard, has BUTTON keys). */
- INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040,
-
- /* The input device has switches. */
- INPUT_DEVICE_CLASS_SWITCH = 0x00000080,
-
- /* The input device is a joystick (implies gamepad, has joystick absolute axes). */
- INPUT_DEVICE_CLASS_JOYSTICK = 0x00000100,
-
- /* The input device has a vibrator (supports FF_RUMBLE). */
- INPUT_DEVICE_CLASS_VIBRATOR = 0x00000200,
-
- /* The input device is virtual (not a real device, not part of UI configuration). */
- INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000,
-
- /* The input device is external (not built-in). */
- INPUT_DEVICE_CLASS_EXTERNAL = 0x80000000,
-};
-
-/*
- * Gets the class that owns an axis, in cases where multiple classes might claim
- * the same axis for different purposes.
- */
-extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses);
-
-/*
- * Grand Central Station for events.
- *
- * The event hub aggregates input events received across all known input
- * devices on the system, including devices that may be emulated by the simulator
- * environment. In addition, the event hub generates fake input events to indicate
- * when devices are added or removed.
- *
- * The event hub provides a stream of input events (via the getEvent function).
- * It also supports querying the current actual state of input devices such as identifying
- * which keys are currently down. Finally, the event hub keeps track of the capabilities of
- * individual input devices, such as their class and the set of key codes that they support.
- */
-class EventHubInterface : public virtual RefBase {
-protected:
- EventHubInterface() { }
- virtual ~EventHubInterface() { }
-
-public:
- // Synthetic raw event type codes produced when devices are added or removed.
- enum {
- // Sent when a device is added.
- DEVICE_ADDED = 0x10000000,
- // Sent when a device is removed.
- DEVICE_REMOVED = 0x20000000,
- // Sent when all added/removed devices from the most recent scan have been reported.
- // This event is always sent at least once.
- FINISHED_DEVICE_SCAN = 0x30000000,
-
- FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
- };
-
- virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
-
- virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0;
-
- virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0;
-
- virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
- RawAbsoluteAxisInfo* outAxisInfo) const = 0;
-
- virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
-
- virtual bool hasInputProperty(int32_t deviceId, int property) const = 0;
-
- virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
- int32_t* outKeycode, uint32_t* outFlags) const = 0;
-
- virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
- AxisInfo* outAxisInfo) const = 0;
-
- // Sets devices that are excluded from opening.
- // This can be used to ignore input devices for sensors.
- virtual void setExcludedDevices(const Vector<String8>& devices) = 0;
-
- /*
- * Wait for events to become available and returns them.
- * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
- * This ensures that the device will not go to sleep while the event is being processed.
- * If the device needs to remain awake longer than that, then the caller is responsible
- * for taking care of it (say, by poking the power manager user activity timer).
- *
- * The timeout is advisory only. If the device is asleep, it will not wake just to
- * service the timeout.
- *
- * Returns the number of events obtained, or 0 if the timeout expired.
- */
- virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 0;
-
- /*
- * Query current input state.
- */
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
- virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
- int32_t* outValue) const = 0;
-
- /*
- * Examine key input devices for specific framework keycode support
- */
- virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
- uint8_t* outFlags) const = 0;
-
- virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0;
- virtual bool hasLed(int32_t deviceId, int32_t led) const = 0;
- virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
-
- virtual void getVirtualKeyDefinitions(int32_t deviceId,
- Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
-
- virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
- virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0;
-
- /* Control the vibrator. */
- virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0;
- virtual void cancelVibrate(int32_t deviceId) = 0;
-
- /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */
- virtual void requestReopenDevices() = 0;
-
- /* Wakes up getEvents() if it is blocked on a read. */
- virtual void wake() = 0;
-
- /* Dump EventHub state to a string. */
- virtual void dump(String8& dump) = 0;
-
- /* Called by the heatbeat to ensures that the reader has not deadlocked. */
- virtual void monitor() = 0;
-};
-
-class EventHub : public EventHubInterface
-{
-public:
- EventHub();
-
- virtual uint32_t getDeviceClasses(int32_t deviceId) const;
-
- virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const;
-
- virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const;
-
- virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
- RawAbsoluteAxisInfo* outAxisInfo) const;
-
- virtual bool hasRelativeAxis(int32_t deviceId, int axis) const;
-
- virtual bool hasInputProperty(int32_t deviceId, int property) const;
-
- virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
- int32_t* outKeycode, uint32_t* outFlags) const;
-
- virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
- AxisInfo* outAxisInfo) const;
-
- virtual void setExcludedDevices(const Vector<String8>& devices);
-
- virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
- virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
- virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
- virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const;
-
- virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) const;
-
- virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize);
-
- virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const;
- virtual bool hasLed(int32_t deviceId, int32_t led) const;
- virtual void setLedState(int32_t deviceId, int32_t led, bool on);
-
- virtual void getVirtualKeyDefinitions(int32_t deviceId,
- Vector<VirtualKeyDefinition>& outVirtualKeys) const;
-
- virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
- virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map);
-
- virtual void vibrate(int32_t deviceId, nsecs_t duration);
- virtual void cancelVibrate(int32_t deviceId);
-
- virtual void requestReopenDevices();
-
- virtual void wake();
-
- virtual void dump(String8& dump);
- virtual void monitor();
-
-protected:
- virtual ~EventHub();
-
-private:
- struct Device {
- Device* next;
-
- int fd; // may be -1 if device is virtual
- const int32_t id;
- const String8 path;
- const InputDeviceIdentifier identifier;
-
- uint32_t classes;
-
- uint8_t keyBitmask[(KEY_MAX + 1) / 8];
- uint8_t absBitmask[(ABS_MAX + 1) / 8];
- uint8_t relBitmask[(REL_MAX + 1) / 8];
- uint8_t swBitmask[(SW_MAX + 1) / 8];
- uint8_t ledBitmask[(LED_MAX + 1) / 8];
- uint8_t ffBitmask[(FF_MAX + 1) / 8];
- uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
-
- String8 configurationFile;
- PropertyMap* configuration;
- VirtualKeyMap* virtualKeyMap;
- KeyMap keyMap;
-
- sp<KeyCharacterMap> overlayKeyMap;
- sp<KeyCharacterMap> combinedKeyMap;
-
- bool ffEffectPlaying;
- int16_t ffEffectId; // initially -1
-
- int32_t timestampOverrideSec;
- int32_t timestampOverrideUsec;
-
- Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
- ~Device();
-
- void close();
-
- inline bool isVirtual() const { return fd < 0; }
-
- const sp<KeyCharacterMap>& getKeyCharacterMap() const {
- if (combinedKeyMap != NULL) {
- return combinedKeyMap;
- }
- return keyMap.keyCharacterMap;
- }
- };
-
- status_t openDeviceLocked(const char *devicePath);
- void createVirtualKeyboardLocked();
- void addDeviceLocked(Device* device);
-
- status_t closeDeviceByPathLocked(const char *devicePath);
- void closeDeviceLocked(Device* device);
- void closeAllDevicesLocked();
-
- status_t scanDirLocked(const char *dirname);
- void scanDevicesLocked();
- status_t readNotifyLocked();
-
- Device* getDeviceLocked(int32_t deviceId) const;
- Device* getDeviceByPathLocked(const char* devicePath) const;
-
- bool hasKeycodeLocked(Device* device, int keycode) const;
-
- void loadConfigurationLocked(Device* device);
- status_t loadVirtualKeyMapLocked(Device* device);
- status_t loadKeyMapLocked(Device* device);
-
- bool isExternalDeviceLocked(Device* device);
-
- // Protect all internal state.
- mutable Mutex mLock;
-
- // The actual id of the built-in keyboard, or NO_BUILT_IN_KEYBOARD if none.
- // EventHub remaps the built-in keyboard to id 0 externally as required by the API.
- enum {
- // Must not conflict with any other assigned device ids, including
- // the virtual keyboard id (-1).
- NO_BUILT_IN_KEYBOARD = -2,
- };
- int32_t mBuiltInKeyboardId;
-
- int32_t mNextDeviceId;
-
- KeyedVector<int32_t, Device*> mDevices;
-
- Device *mOpeningDevices;
- Device *mClosingDevices;
-
- bool mNeedToSendFinishedDeviceScan;
- bool mNeedToReopenDevices;
- bool mNeedToScanDevices;
- Vector<String8> mExcludedDevices;
-
- int mEpollFd;
- int mINotifyFd;
- int mWakeReadPipeFd;
- int mWakeWritePipeFd;
-
- // Ids used for epoll notifications not associated with devices.
- static const uint32_t EPOLL_ID_INOTIFY = 0x80000001;
- static const uint32_t EPOLL_ID_WAKE = 0x80000002;
-
- // Epoll FD list size hint.
- static const int EPOLL_SIZE_HINT = 8;
-
- // Maximum number of signalled FDs to handle at a time.
- static const int EPOLL_MAX_EVENTS = 16;
-
- // The array of pending epoll events and the index of the next event to be handled.
- struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
- size_t mPendingEventCount;
- size_t mPendingEventIndex;
- bool mPendingINotify;
-};
-
-}; // namespace android
-
-#endif // _RUNTIME_EVENT_HUB_H
diff --git a/widget/gonk/libui/Input.cpp b/widget/gonk/libui/Input.cpp
deleted file mode 100644
index 2208191e6..000000000
--- a/widget/gonk/libui/Input.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Input"
-//#define LOG_NDEBUG 0
-#include "cutils_log.h"
-
-#include <math.h>
-#include <limits.h>
-
-#include "Input.h"
-
-#ifdef HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-
-#include "SkPoint.h"
-#include "SkMatrix.h"
-#include "SkScalar.h"
-#endif
-
-namespace android {
-
-// --- InputEvent ---
-
-void InputEvent::initialize(int32_t deviceId, int32_t source) {
- mDeviceId = deviceId;
- mSource = source;
-}
-
-void InputEvent::initialize(const InputEvent& from) {
- mDeviceId = from.mDeviceId;
- mSource = from.mSource;
-}
-
-// --- KeyEvent ---
-
-bool KeyEvent::hasDefaultAction(int32_t keyCode) {
- switch (keyCode) {
- case AKEYCODE_HOME:
- case AKEYCODE_BACK:
- case AKEYCODE_CALL:
- case AKEYCODE_ENDCALL:
- case AKEYCODE_VOLUME_UP:
- case AKEYCODE_VOLUME_DOWN:
- case AKEYCODE_VOLUME_MUTE:
- case AKEYCODE_POWER:
- case AKEYCODE_CAMERA:
- case AKEYCODE_HEADSETHOOK:
- case AKEYCODE_MENU:
- case AKEYCODE_NOTIFICATION:
- case AKEYCODE_FOCUS:
- case AKEYCODE_SEARCH:
- case AKEYCODE_MEDIA_PLAY:
- case AKEYCODE_MEDIA_PAUSE:
- case AKEYCODE_MEDIA_PLAY_PAUSE:
- case AKEYCODE_MEDIA_STOP:
- case AKEYCODE_MEDIA_NEXT:
- case AKEYCODE_MEDIA_PREVIOUS:
- case AKEYCODE_MEDIA_REWIND:
- case AKEYCODE_MEDIA_RECORD:
- case AKEYCODE_MEDIA_FAST_FORWARD:
- case AKEYCODE_MUTE:
- case AKEYCODE_BRIGHTNESS_DOWN:
- case AKEYCODE_BRIGHTNESS_UP:
- return true;
- }
-
- return false;
-}
-
-bool KeyEvent::hasDefaultAction() const {
- return hasDefaultAction(getKeyCode());
-}
-
-bool KeyEvent::isSystemKey(int32_t keyCode) {
- switch (keyCode) {
- case AKEYCODE_MENU:
- case AKEYCODE_SOFT_RIGHT:
- case AKEYCODE_HOME:
- case AKEYCODE_BACK:
- case AKEYCODE_CALL:
- case AKEYCODE_ENDCALL:
- case AKEYCODE_VOLUME_UP:
- case AKEYCODE_VOLUME_DOWN:
- case AKEYCODE_VOLUME_MUTE:
- case AKEYCODE_MUTE:
- case AKEYCODE_POWER:
- case AKEYCODE_HEADSETHOOK:
- case AKEYCODE_MEDIA_PLAY:
- case AKEYCODE_MEDIA_PAUSE:
- case AKEYCODE_MEDIA_PLAY_PAUSE:
- case AKEYCODE_MEDIA_STOP:
- case AKEYCODE_MEDIA_NEXT:
- case AKEYCODE_MEDIA_PREVIOUS:
- case AKEYCODE_MEDIA_REWIND:
- case AKEYCODE_MEDIA_RECORD:
- case AKEYCODE_MEDIA_FAST_FORWARD:
- case AKEYCODE_CAMERA:
- case AKEYCODE_FOCUS:
- case AKEYCODE_SEARCH:
- case AKEYCODE_BRIGHTNESS_DOWN:
- case AKEYCODE_BRIGHTNESS_UP:
- return true;
- }
-
- return false;
-}
-
-bool KeyEvent::isSystemKey() const {
- return isSystemKey(getKeyCode());
-}
-
-void KeyEvent::initialize(
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t keyCode,
- int32_t scanCode,
- int32_t metaState,
- int32_t repeatCount,
- nsecs_t downTime,
- nsecs_t eventTime) {
- InputEvent::initialize(deviceId, source);
- mAction = action;
- mFlags = flags;
- mKeyCode = keyCode;
- mScanCode = scanCode;
- mMetaState = metaState;
- mRepeatCount = repeatCount;
- mDownTime = downTime;
- mEventTime = eventTime;
-}
-
-void KeyEvent::initialize(const KeyEvent& from) {
- InputEvent::initialize(from);
- mAction = from.mAction;
- mFlags = from.mFlags;
- mKeyCode = from.mKeyCode;
- mScanCode = from.mScanCode;
- mMetaState = from.mMetaState;
- mRepeatCount = from.mRepeatCount;
- mDownTime = from.mDownTime;
- mEventTime = from.mEventTime;
-}
-
-
-// --- PointerCoords ---
-
-float PointerCoords::getAxisValue(int32_t axis) const {
- if (axis < 0 || axis > 63) {
- return 0;
- }
-
- uint64_t axisBit = 1LL << axis;
- if (!(bits & axisBit)) {
- return 0;
- }
- uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
- return values[index];
-}
-
-status_t PointerCoords::setAxisValue(int32_t axis, float value) {
- if (axis < 0 || axis > 63) {
- return NAME_NOT_FOUND;
- }
-
- uint64_t axisBit = 1LL << axis;
- uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
- if (!(bits & axisBit)) {
- if (value == 0) {
- return OK; // axes with value 0 do not need to be stored
- }
- uint32_t count = __builtin_popcountll(bits);
- if (count >= MAX_AXES) {
- tooManyAxes(axis);
- return NO_MEMORY;
- }
- bits |= axisBit;
- for (uint32_t i = count; i > index; i--) {
- values[i] = values[i - 1];
- }
- }
- values[index] = value;
- return OK;
-}
-
-static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
- float value = c.getAxisValue(axis);
- if (value != 0) {
- c.setAxisValue(axis, value * scaleFactor);
- }
-}
-
-void PointerCoords::scale(float scaleFactor) {
- // No need to scale pressure or size since they are normalized.
- // No need to scale orientation since it is meaningless to do so.
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
- scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
-}
-
-#ifdef HAVE_ANDROID_OS
-status_t PointerCoords::readFromParcel(Parcel* parcel) {
- bits = parcel->readInt64();
-
- uint32_t count = __builtin_popcountll(bits);
- if (count > MAX_AXES) {
- return BAD_VALUE;
- }
-
- for (uint32_t i = 0; i < count; i++) {
- values[i] = parcel->readFloat();
- }
- return OK;
-}
-
-status_t PointerCoords::writeToParcel(Parcel* parcel) const {
- parcel->writeInt64(bits);
-
- uint32_t count = __builtin_popcountll(bits);
- for (uint32_t i = 0; i < count; i++) {
- parcel->writeFloat(values[i]);
- }
- return OK;
-}
-#endif
-
-void PointerCoords::tooManyAxes(int axis) {
- ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
- "cannot contain more than %d axis values.", axis, int(MAX_AXES));
-}
-
-bool PointerCoords::operator==(const PointerCoords& other) const {
- if (bits != other.bits) {
- return false;
- }
- uint32_t count = __builtin_popcountll(bits);
- for (uint32_t i = 0; i < count; i++) {
- if (values[i] != other.values[i]) {
- return false;
- }
- }
- return true;
-}
-
-void PointerCoords::copyFrom(const PointerCoords& other) {
- bits = other.bits;
- uint32_t count = __builtin_popcountll(bits);
- for (uint32_t i = 0; i < count; i++) {
- values[i] = other.values[i];
- }
-}
-
-
-// --- PointerProperties ---
-
-bool PointerProperties::operator==(const PointerProperties& other) const {
- return id == other.id
- && toolType == other.toolType;
-}
-
-void PointerProperties::copyFrom(const PointerProperties& other) {
- id = other.id;
- toolType = other.toolType;
-}
-
-
-// --- MotionEvent ---
-
-void MotionEvent::initialize(
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords) {
- InputEvent::initialize(deviceId, source);
- mAction = action;
- mFlags = flags;
- mEdgeFlags = edgeFlags;
- mMetaState = metaState;
- mButtonState = buttonState;
- mXOffset = xOffset;
- mYOffset = yOffset;
- mXPrecision = xPrecision;
- mYPrecision = yPrecision;
- mDownTime = downTime;
- mPointerProperties.clear();
- mPointerProperties.appendArray(pointerProperties, pointerCount);
- mSampleEventTimes.clear();
- mSamplePointerCoords.clear();
- addSample(eventTime, pointerCoords);
-}
-
-void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
- InputEvent::initialize(other->mDeviceId, other->mSource);
- mAction = other->mAction;
- mFlags = other->mFlags;
- mEdgeFlags = other->mEdgeFlags;
- mMetaState = other->mMetaState;
- mButtonState = other->mButtonState;
- mXOffset = other->mXOffset;
- mYOffset = other->mYOffset;
- mXPrecision = other->mXPrecision;
- mYPrecision = other->mYPrecision;
- mDownTime = other->mDownTime;
- mPointerProperties = other->mPointerProperties;
-
- if (keepHistory) {
- mSampleEventTimes = other->mSampleEventTimes;
- mSamplePointerCoords = other->mSamplePointerCoords;
- } else {
- mSampleEventTimes.clear();
- mSampleEventTimes.push(other->getEventTime());
- mSamplePointerCoords.clear();
- size_t pointerCount = other->getPointerCount();
- size_t historySize = other->getHistorySize();
- mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
- + (historySize * pointerCount), pointerCount);
- }
-}
-
-void MotionEvent::addSample(
- int64_t eventTime,
- const PointerCoords* pointerCoords) {
- mSampleEventTimes.push(eventTime);
- mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
-}
-
-const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
- return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
- return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
- float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
- switch (axis) {
- case AMOTION_EVENT_AXIS_X:
- return value + mXOffset;
- case AMOTION_EVENT_AXIS_Y:
- return value + mYOffset;
- }
- return value;
-}
-
-const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
- size_t pointerIndex, size_t historicalIndex) const {
- return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
-}
-
-float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
- size_t historicalIndex) const {
- return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
-}
-
-float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
- size_t historicalIndex) const {
- float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
- switch (axis) {
- case AMOTION_EVENT_AXIS_X:
- return value + mXOffset;
- case AMOTION_EVENT_AXIS_Y:
- return value + mYOffset;
- }
- return value;
-}
-
-ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
- size_t pointerCount = mPointerProperties.size();
- for (size_t i = 0; i < pointerCount; i++) {
- if (mPointerProperties.itemAt(i).id == pointerId) {
- return i;
- }
- }
- return -1;
-}
-
-void MotionEvent::offsetLocation(float xOffset, float yOffset) {
- mXOffset += xOffset;
- mYOffset += yOffset;
-}
-
-void MotionEvent::scale(float scaleFactor) {
- mXOffset *= scaleFactor;
- mYOffset *= scaleFactor;
- mXPrecision *= scaleFactor;
- mYPrecision *= scaleFactor;
-
- size_t numSamples = mSamplePointerCoords.size();
- for (size_t i = 0; i < numSamples; i++) {
- mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
- }
-}
-
-#ifdef HAVE_ANDROID_OS
-static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
- // Construct and transform a vector oriented at the specified clockwise angle from vertical.
- // Coordinate system: down is increasing Y, right is increasing X.
- SkPoint vector;
- vector.fX = SkFloatToScalar(sinf(angleRadians));
- vector.fY = SkFloatToScalar(-cosf(angleRadians));
- matrix->mapVectors(& vector, 1);
-
- // Derive the transformed vector's clockwise angle from vertical.
- float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
- if (result < - M_PI_2) {
- result += M_PI;
- } else if (result > M_PI_2) {
- result -= M_PI;
- }
- return result;
-}
-
-void MotionEvent::transform(const SkMatrix* matrix) {
- float oldXOffset = mXOffset;
- float oldYOffset = mYOffset;
-
- // The tricky part of this implementation is to preserve the value of
- // rawX and rawY. So we apply the transformation to the first point
- // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
- SkPoint point;
- float rawX = getRawX(0);
- float rawY = getRawY(0);
- matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
- & point);
- float newX = SkScalarToFloat(point.fX);
- float newY = SkScalarToFloat(point.fY);
- float newXOffset = newX - rawX;
- float newYOffset = newY - rawY;
-
- mXOffset = newXOffset;
- mYOffset = newYOffset;
-
- // Apply the transformation to all samples.
- size_t numSamples = mSamplePointerCoords.size();
- for (size_t i = 0; i < numSamples; i++) {
- PointerCoords& c = mSamplePointerCoords.editItemAt(i);
- float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
- float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
- matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
- c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
- c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
-
- float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
- c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
- }
-}
-
-status_t MotionEvent::readFromParcel(Parcel* parcel) {
- size_t pointerCount = parcel->readInt32();
- size_t sampleCount = parcel->readInt32();
- if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
- return BAD_VALUE;
- }
-
- mDeviceId = parcel->readInt32();
- mSource = parcel->readInt32();
- mAction = parcel->readInt32();
- mFlags = parcel->readInt32();
- mEdgeFlags = parcel->readInt32();
- mMetaState = parcel->readInt32();
- mButtonState = parcel->readInt32();
- mXOffset = parcel->readFloat();
- mYOffset = parcel->readFloat();
- mXPrecision = parcel->readFloat();
- mYPrecision = parcel->readFloat();
- mDownTime = parcel->readInt64();
-
- mPointerProperties.clear();
- mPointerProperties.setCapacity(pointerCount);
- mSampleEventTimes.clear();
- mSampleEventTimes.setCapacity(sampleCount);
- mSamplePointerCoords.clear();
- mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
-
- for (size_t i = 0; i < pointerCount; i++) {
- mPointerProperties.push();
- PointerProperties& properties = mPointerProperties.editTop();
- properties.id = parcel->readInt32();
- properties.toolType = parcel->readInt32();
- }
-
- while (sampleCount-- > 0) {
- mSampleEventTimes.push(parcel->readInt64());
- for (size_t i = 0; i < pointerCount; i++) {
- mSamplePointerCoords.push();
- status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
- if (status) {
- return status;
- }
- }
- }
- return OK;
-}
-
-status_t MotionEvent::writeToParcel(Parcel* parcel) const {
- size_t pointerCount = mPointerProperties.size();
- size_t sampleCount = mSampleEventTimes.size();
-
- parcel->writeInt32(pointerCount);
- parcel->writeInt32(sampleCount);
-
- parcel->writeInt32(mDeviceId);
- parcel->writeInt32(mSource);
- parcel->writeInt32(mAction);
- parcel->writeInt32(mFlags);
- parcel->writeInt32(mEdgeFlags);
- parcel->writeInt32(mMetaState);
- parcel->writeInt32(mButtonState);
- parcel->writeFloat(mXOffset);
- parcel->writeFloat(mYOffset);
- parcel->writeFloat(mXPrecision);
- parcel->writeFloat(mYPrecision);
- parcel->writeInt64(mDownTime);
-
- for (size_t i = 0; i < pointerCount; i++) {
- const PointerProperties& properties = mPointerProperties.itemAt(i);
- parcel->writeInt32(properties.id);
- parcel->writeInt32(properties.toolType);
- }
-
- const PointerCoords* pc = mSamplePointerCoords.array();
- for (size_t h = 0; h < sampleCount; h++) {
- parcel->writeInt64(mSampleEventTimes.itemAt(h));
- for (size_t i = 0; i < pointerCount; i++) {
- status_t status = (pc++)->writeToParcel(parcel);
- if (status) {
- return status;
- }
- }
- }
- return OK;
-}
-#endif
-
-bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
- if (source & AINPUT_SOURCE_CLASS_POINTER) {
- // Specifically excludes HOVER_MOVE and SCROLL.
- switch (action & AMOTION_EVENT_ACTION_MASK) {
- case AMOTION_EVENT_ACTION_DOWN:
- case AMOTION_EVENT_ACTION_MOVE:
- case AMOTION_EVENT_ACTION_UP:
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- case AMOTION_EVENT_ACTION_POINTER_UP:
- case AMOTION_EVENT_ACTION_CANCEL:
- case AMOTION_EVENT_ACTION_OUTSIDE:
- return true;
- }
- }
- return false;
-}
-
-
-// --- PooledInputEventFactory ---
-
-PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
- mMaxPoolSize(maxPoolSize) {
-}
-
-PooledInputEventFactory::~PooledInputEventFactory() {
- for (size_t i = 0; i < mKeyEventPool.size(); i++) {
- delete mKeyEventPool.itemAt(i);
- }
- for (size_t i = 0; i < mMotionEventPool.size(); i++) {
- delete mMotionEventPool.itemAt(i);
- }
-}
-
-KeyEvent* PooledInputEventFactory::createKeyEvent() {
- if (!mKeyEventPool.isEmpty()) {
- KeyEvent* event = mKeyEventPool.top();
- mKeyEventPool.pop();
- return event;
- }
- return new KeyEvent();
-}
-
-MotionEvent* PooledInputEventFactory::createMotionEvent() {
- if (!mMotionEventPool.isEmpty()) {
- MotionEvent* event = mMotionEventPool.top();
- mMotionEventPool.pop();
- return event;
- }
- return new MotionEvent();
-}
-
-void PooledInputEventFactory::recycle(InputEvent* event) {
- switch (event->getType()) {
- case AINPUT_EVENT_TYPE_KEY:
- if (mKeyEventPool.size() < mMaxPoolSize) {
- mKeyEventPool.push(static_cast<KeyEvent*>(event));
- return;
- }
- break;
- case AINPUT_EVENT_TYPE_MOTION:
- if (mMotionEventPool.size() < mMaxPoolSize) {
- mMotionEventPool.push(static_cast<MotionEvent*>(event));
- return;
- }
- break;
- }
- delete event;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/Input.h b/widget/gonk/libui/Input.h
deleted file mode 100644
index 3d958bfab..000000000
--- a/widget/gonk/libui/Input.h
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_INPUT_H
-#define _ANDROIDFW_INPUT_H
-
-/**
- * Native input event structures.
- */
-
-#include "android_input.h"
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#ifdef HAVE_ANDROID_OS
-class SkMatrix;
-#endif
-
-/*
- * Additional private constants not defined in ndk/ui/input.h.
- */
-enum {
- /* Signifies that the key is being predispatched */
- AKEY_EVENT_FLAG_PREDISPATCH = 0x20000000,
-
- /* Private control to determine when an app is tracking a key sequence. */
- AKEY_EVENT_FLAG_START_TRACKING = 0x40000000,
-
- /* Key event is inconsistent with previously sent key events. */
- AKEY_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
- /* Motion event is inconsistent with previously sent motion events. */
- AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
-};
-
-enum {
- /* Used when a motion event is not associated with any display.
- * Typically used for non-pointer events. */
- ADISPLAY_ID_NONE = -1,
-
- /* The default display id. */
- ADISPLAY_ID_DEFAULT = 0,
-};
-
-enum {
- /*
- * Indicates that an input device has switches.
- * This input source flag is hidden from the API because switches are only used by the system
- * and applications have no way to interact with them.
- */
- AINPUT_SOURCE_SWITCH = 0x80000000,
-};
-
-/*
- * SystemUiVisibility constants from View.
- */
-enum {
- ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE = 0,
- ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN = 0x00000001,
-};
-
-/*
- * Maximum number of pointers supported per motion event.
- * Smallest number of pointers is 1.
- * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers
- * will occasionally emit 11. There is not much harm making this constant bigger.)
- */
-#define MAX_POINTERS 16
-
-/*
- * Maximum pointer id value supported in a motion event.
- * Smallest pointer id is 0.
- * (This is limited by our use of BitSet32 to track pointer assignments.)
- */
-#define MAX_POINTER_ID 31
-
-/*
- * Declare a concrete type for the NDK's input event forward declaration.
- */
-struct AInputEvent {
- virtual ~AInputEvent() { }
-};
-
-/*
- * Declare a concrete type for the NDK's input device forward declaration.
- */
-struct AInputDevice {
- virtual ~AInputDevice() { }
-};
-
-
-namespace android {
-
-#ifdef HAVE_ANDROID_OS
-class Parcel;
-#endif
-
-/*
- * Flags that flow alongside events in the input dispatch system to help with certain
- * policy decisions such as waking from device sleep.
- *
- * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
- */
-enum {
- /* These flags originate in RawEvents and are generally set in the key map.
- * NOTE: If you edit these flags, also edit labels in KeycodeLabels.h. */
-
- POLICY_FLAG_WAKE = 0x00000001,
- POLICY_FLAG_WAKE_DROPPED = 0x00000002,
- POLICY_FLAG_SHIFT = 0x00000004,
- POLICY_FLAG_CAPS_LOCK = 0x00000008,
- POLICY_FLAG_ALT = 0x00000010,
- POLICY_FLAG_ALT_GR = 0x00000020,
- POLICY_FLAG_MENU = 0x00000040,
- POLICY_FLAG_LAUNCHER = 0x00000080,
- POLICY_FLAG_VIRTUAL = 0x00000100,
- POLICY_FLAG_FUNCTION = 0x00000200,
-
- POLICY_FLAG_RAW_MASK = 0x0000ffff,
-
- /* These flags are set by the input dispatcher. */
-
- // Indicates that the input event was injected.
- POLICY_FLAG_INJECTED = 0x01000000,
-
- // Indicates that the input event is from a trusted source such as a directly attached
- // input device or an application with system-wide event injection permission.
- POLICY_FLAG_TRUSTED = 0x02000000,
-
- // Indicates that the input event has passed through an input filter.
- POLICY_FLAG_FILTERED = 0x04000000,
-
- // Disables automatic key repeating behavior.
- POLICY_FLAG_DISABLE_KEY_REPEAT = 0x08000000,
-
- /* These flags are set by the input reader policy as it intercepts each event. */
-
- // Indicates that the screen was off when the event was received and the event
- // should wake the device.
- POLICY_FLAG_WOKE_HERE = 0x10000000,
-
- // Indicates that the screen was dim when the event was received and the event
- // should brighten the device.
- POLICY_FLAG_BRIGHT_HERE = 0x20000000,
-
- // Indicates that the event should be dispatched to applications.
- // The input event should still be sent to the InputDispatcher so that it can see all
- // input events received include those that it will not deliver.
- POLICY_FLAG_PASS_TO_USER = 0x40000000,
-};
-
-/*
- * Pointer coordinate data.
- */
-struct PointerCoords {
- enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
-
- // Bitfield of axes that are present in this structure.
- uint64_t bits;
-
- // Values of axes that are stored in this structure packed in order by axis id
- // for each axis that is present in the structure according to 'bits'.
- float values[MAX_AXES];
-
- inline void clear() {
- bits = 0;
- }
-
- float getAxisValue(int32_t axis) const;
- status_t setAxisValue(int32_t axis, float value);
-
- void scale(float scale);
-
- inline float getX() const {
- return getAxisValue(AMOTION_EVENT_AXIS_X);
- }
-
- inline float getY() const {
- return getAxisValue(AMOTION_EVENT_AXIS_Y);
- }
-
-#ifdef HAVE_ANDROID_OS
- status_t readFromParcel(Parcel* parcel);
- status_t writeToParcel(Parcel* parcel) const;
-#endif
-
- bool operator==(const PointerCoords& other) const;
- inline bool operator!=(const PointerCoords& other) const {
- return !(*this == other);
- }
-
- void copyFrom(const PointerCoords& other);
-
-private:
- void tooManyAxes(int axis);
-};
-
-/*
- * Pointer property data.
- */
-struct PointerProperties {
- // The id of the pointer.
- int32_t id;
-
- // The pointer tool type.
- int32_t toolType;
-
- inline void clear() {
- id = -1;
- toolType = 0;
- }
-
- bool operator==(const PointerProperties& other) const;
- inline bool operator!=(const PointerProperties& other) const {
- return !(*this == other);
- }
-
- void copyFrom(const PointerProperties& other);
-};
-
-/*
- * Input events.
- */
-class InputEvent : public AInputEvent {
-public:
- virtual ~InputEvent() { }
-
- virtual int32_t getType() const = 0;
-
- inline int32_t getDeviceId() const { return mDeviceId; }
-
- inline int32_t getSource() const { return mSource; }
-
- inline void setSource(int32_t source) { mSource = source; }
-
-protected:
- void initialize(int32_t deviceId, int32_t source);
- void initialize(const InputEvent& from);
-
- int32_t mDeviceId;
- int32_t mSource;
-};
-
-/*
- * Key events.
- */
-class KeyEvent : public InputEvent {
-public:
- virtual ~KeyEvent() { }
-
- virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
-
- inline int32_t getAction() const { return mAction; }
-
- inline int32_t getFlags() const { return mFlags; }
-
- inline void setFlags(int32_t flags) { mFlags = flags; }
-
- inline int32_t getKeyCode() const { return mKeyCode; }
-
- inline int32_t getScanCode() const { return mScanCode; }
-
- inline int32_t getMetaState() const { return mMetaState; }
-
- inline int32_t getRepeatCount() const { return mRepeatCount; }
-
- inline nsecs_t getDownTime() const { return mDownTime; }
-
- inline nsecs_t getEventTime() const { return mEventTime; }
-
- // Return true if this event may have a default action implementation.
- static bool hasDefaultAction(int32_t keyCode);
- bool hasDefaultAction() const;
-
- // Return true if this event represents a system key.
- static bool isSystemKey(int32_t keyCode);
- bool isSystemKey() const;
-
- void initialize(
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t keyCode,
- int32_t scanCode,
- int32_t metaState,
- int32_t repeatCount,
- nsecs_t downTime,
- nsecs_t eventTime);
- void initialize(const KeyEvent& from);
-
-protected:
- int32_t mAction;
- int32_t mFlags;
- int32_t mKeyCode;
- int32_t mScanCode;
- int32_t mMetaState;
- int32_t mRepeatCount;
- nsecs_t mDownTime;
- nsecs_t mEventTime;
-};
-
-/*
- * Motion events.
- */
-class MotionEvent : public InputEvent {
-public:
- virtual ~MotionEvent() { }
-
- virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
-
- inline int32_t getAction() const { return mAction; }
-
- inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; }
-
- inline int32_t getActionIndex() const {
- return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
- >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- }
-
- inline void setAction(int32_t action) { mAction = action; }
-
- inline int32_t getFlags() const { return mFlags; }
-
- inline void setFlags(int32_t flags) { mFlags = flags; }
-
- inline int32_t getEdgeFlags() const { return mEdgeFlags; }
-
- inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
-
- inline int32_t getMetaState() const { return mMetaState; }
-
- inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
-
- inline int32_t getButtonState() const { return mButtonState; }
-
- inline float getXOffset() const { return mXOffset; }
-
- inline float getYOffset() const { return mYOffset; }
-
- inline float getXPrecision() const { return mXPrecision; }
-
- inline float getYPrecision() const { return mYPrecision; }
-
- inline nsecs_t getDownTime() const { return mDownTime; }
-
- inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; }
-
- inline size_t getPointerCount() const { return mPointerProperties.size(); }
-
- inline const PointerProperties* getPointerProperties(size_t pointerIndex) const {
- return &mPointerProperties[pointerIndex];
- }
-
- inline int32_t getPointerId(size_t pointerIndex) const {
- return mPointerProperties[pointerIndex].id;
- }
-
- inline int32_t getToolType(size_t pointerIndex) const {
- return mPointerProperties[pointerIndex].toolType;
- }
-
- inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
-
- const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
-
- float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
-
- inline float getRawX(size_t pointerIndex) const {
- return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
- }
-
- inline float getRawY(size_t pointerIndex) const {
- return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
- }
-
- float getAxisValue(int32_t axis, size_t pointerIndex) const;
-
- inline float getX(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
- }
-
- inline float getY(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
- }
-
- inline float getPressure(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
- }
-
- inline float getSize(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
- }
-
- inline float getTouchMajor(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
- }
-
- inline float getTouchMinor(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
- }
-
- inline float getToolMajor(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
- }
-
- inline float getToolMinor(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
- }
-
- inline float getOrientation(size_t pointerIndex) const {
- return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
- }
-
- inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
-
- inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
- return mSampleEventTimes[historicalIndex];
- }
-
- const PointerCoords* getHistoricalRawPointerCoords(
- size_t pointerIndex, size_t historicalIndex) const;
-
- float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
- size_t historicalIndex) const;
-
- inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalRawAxisValue(
- AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalRawAxisValue(
- AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
- }
-
- float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
-
- inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
- }
-
- inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
- return getHistoricalAxisValue(
- AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
- }
-
- ssize_t findPointerIndex(int32_t pointerId) const;
-
- void initialize(
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords);
-
- void copyFrom(const MotionEvent* other, bool keepHistory);
-
- void addSample(
- nsecs_t eventTime,
- const PointerCoords* pointerCoords);
-
- void offsetLocation(float xOffset, float yOffset);
-
- void scale(float scaleFactor);
-
-#ifdef HAVE_ANDROID_OS
- void transform(const SkMatrix* matrix);
-
- status_t readFromParcel(Parcel* parcel);
- status_t writeToParcel(Parcel* parcel) const;
-#endif
-
- static bool isTouchEvent(int32_t source, int32_t action);
- inline bool isTouchEvent() const {
- return isTouchEvent(mSource, mAction);
- }
-
- // Low-level accessors.
- inline const PointerProperties* getPointerProperties() const {
- return mPointerProperties.array();
- }
- inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
- inline const PointerCoords* getSamplePointerCoords() const {
- return mSamplePointerCoords.array();
- }
-
-protected:
- int32_t mAction;
- int32_t mFlags;
- int32_t mEdgeFlags;
- int32_t mMetaState;
- int32_t mButtonState;
- float mXOffset;
- float mYOffset;
- float mXPrecision;
- float mYPrecision;
- nsecs_t mDownTime;
- Vector<PointerProperties> mPointerProperties;
- Vector<nsecs_t> mSampleEventTimes;
- Vector<PointerCoords> mSamplePointerCoords;
-};
-
-/*
- * Input event factory.
- */
-class InputEventFactoryInterface {
-protected:
- virtual ~InputEventFactoryInterface() { }
-
-public:
- InputEventFactoryInterface() { }
-
- virtual KeyEvent* createKeyEvent() = 0;
- virtual MotionEvent* createMotionEvent() = 0;
-};
-
-/*
- * A simple input event factory implementation that uses a single preallocated instance
- * of each type of input event that are reused for each request.
- */
-class PreallocatedInputEventFactory : public InputEventFactoryInterface {
-public:
- PreallocatedInputEventFactory() { }
- virtual ~PreallocatedInputEventFactory() { }
-
- virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
- virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
-
-private:
- KeyEvent mKeyEvent;
- MotionEvent mMotionEvent;
-};
-
-/*
- * An input event factory implementation that maintains a pool of input events.
- */
-class PooledInputEventFactory : public InputEventFactoryInterface {
-public:
- PooledInputEventFactory(size_t maxPoolSize = 20);
- virtual ~PooledInputEventFactory();
-
- virtual KeyEvent* createKeyEvent();
- virtual MotionEvent* createMotionEvent();
-
- void recycle(InputEvent* event);
-
-private:
- const size_t mMaxPoolSize;
-
- Vector<KeyEvent*> mKeyEventPool;
- Vector<MotionEvent*> mMotionEventPool;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_H
diff --git a/widget/gonk/libui/InputApplication.cpp b/widget/gonk/libui/InputApplication.cpp
deleted file mode 100644
index ce432356b..000000000
--- a/widget/gonk/libui/InputApplication.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputApplication"
-
-#include "InputApplication.h"
-
-#include "cutils_log.h"
-
-namespace android {
-
-// --- InputApplicationHandle ---
-
-InputApplicationHandle::InputApplicationHandle() :
- mInfo(NULL) {
-}
-
-InputApplicationHandle::~InputApplicationHandle() {
- delete mInfo;
-}
-
-void InputApplicationHandle::releaseInfo() {
- if (mInfo) {
- delete mInfo;
- mInfo = NULL;
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputApplication.h b/widget/gonk/libui/InputApplication.h
deleted file mode 100644
index ba789559c..000000000
--- a/widget/gonk/libui/InputApplication.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_APPLICATION_H
-#define _UI_INPUT_APPLICATION_H
-
-#include "Input.h"
-
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/*
- * Describes the properties of an application that can receive input.
- */
-struct InputApplicationInfo {
- String8 name;
- nsecs_t dispatchingTimeout;
-};
-
-
-/*
- * Handle for an application that can receive input.
- *
- * Used by the native input dispatcher as a handle for the window manager objects
- * that describe an application.
- */
-class InputApplicationHandle : public RefBase {
-public:
- inline const InputApplicationInfo* getInfo() const {
- return mInfo;
- }
-
- inline String8 getName() const {
- return mInfo ? mInfo->name : String8("<invalid>");
- }
-
- inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
- return mInfo ? mInfo->dispatchingTimeout : defaultValue;
- }
-
- /**
- * Requests that the state of this object be updated to reflect
- * the most current available information about the application.
- *
- * This method should only be called from within the input dispatcher's
- * critical section.
- *
- * Returns true on success, or false if the handle is no longer valid.
- */
- virtual bool updateInfo() = 0;
-
- /**
- * Releases the storage used by the associated information when it is
- * no longer needed.
- */
- void releaseInfo();
-
-protected:
- InputApplicationHandle();
- virtual ~InputApplicationHandle();
-
- InputApplicationInfo* mInfo;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_APPLICATION_H
diff --git a/widget/gonk/libui/InputDevice.cpp b/widget/gonk/libui/InputDevice.cpp
deleted file mode 100644
index 01a437dd4..000000000
--- a/widget/gonk/libui/InputDevice.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputDevice"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include "InputDevice.h"
-
-namespace android {
-
-static const char* CONFIGURATION_FILE_DIR[] = {
- "idc/",
- "keylayout/",
- "keychars/",
-};
-
-static const char* CONFIGURATION_FILE_EXTENSION[] = {
- ".idc",
- ".kl",
- ".kcm",
-};
-
-static bool isValidNameChar(char ch) {
- return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_');
-}
-
-static void appendInputDeviceConfigurationFileRelativePath(String8& path,
- const String8& name, InputDeviceConfigurationFileType type) {
- path.append(CONFIGURATION_FILE_DIR[type]);
- for (size_t i = 0; i < name.length(); i++) {
- char ch = name[i];
- if (!isValidNameChar(ch)) {
- ch = '_';
- }
- path.append(&ch, 1);
- }
- path.append(CONFIGURATION_FILE_EXTENSION[type]);
-}
-
-String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
- const InputDeviceIdentifier& deviceIdentifier,
- InputDeviceConfigurationFileType type) {
- if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) {
- if (deviceIdentifier.version != 0) {
- // Try vendor product version.
- String8 versionPath(getInputDeviceConfigurationFilePathByName(
- String8::format("Vendor_%04x_Product_%04x_Version_%04x",
- deviceIdentifier.vendor, deviceIdentifier.product,
- deviceIdentifier.version),
- type));
- if (!versionPath.isEmpty()) {
- return versionPath;
- }
- }
-
- // Try vendor product.
- String8 productPath(getInputDeviceConfigurationFilePathByName(
- String8::format("Vendor_%04x_Product_%04x",
- deviceIdentifier.vendor, deviceIdentifier.product),
- type));
- if (!productPath.isEmpty()) {
- return productPath;
- }
- }
-
- // Try device name.
- return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type);
-}
-
-String8 getInputDeviceConfigurationFilePathByName(
- const String8& name, InputDeviceConfigurationFileType type) {
- // Search system repository.
- String8 path;
- path.setTo(getenv("ANDROID_ROOT"));
- path.append("/usr/");
- appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
- ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
-#endif
- if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
- ALOGD("Found");
-#endif
- return path;
- }
-
- // Search user repository.
- // TODO Should only look here if not in safe mode.
- path.setTo(getenv("ANDROID_DATA"));
- path.append("/system/devices/");
- appendInputDeviceConfigurationFileRelativePath(path, name, type);
-#if DEBUG_PROBE
- ALOGD("Probing for system user input device configuration file: path='%s'", path.string());
-#endif
- if (!access(path.string(), R_OK)) {
-#if DEBUG_PROBE
- ALOGD("Found");
-#endif
- return path;
- }
-
- // Not found.
-#if DEBUG_PROBE
- ALOGD("Probe failed to find input device configuration file: name='%s', type=%d",
- name.string(), type);
-#endif
- return String8();
-}
-
-
-// --- InputDeviceInfo ---
-
-InputDeviceInfo::InputDeviceInfo() {
- initialize(-1, -1, InputDeviceIdentifier(), String8(), false);
-}
-
-InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
- mId(other.mId), mGeneration(other.mGeneration), mIdentifier(other.mIdentifier),
- mAlias(other.mAlias), mIsExternal(other.mIsExternal), mSources(other.mSources),
- mKeyboardType(other.mKeyboardType),
- mKeyCharacterMap(other.mKeyCharacterMap),
- mHasVibrator(other.mHasVibrator),
- mMotionRanges(other.mMotionRanges) {
-}
-
-InputDeviceInfo::~InputDeviceInfo() {
-}
-
-void InputDeviceInfo::initialize(int32_t id, int32_t generation,
- const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) {
- mId = id;
- mGeneration = generation;
- mIdentifier = identifier;
- mAlias = alias;
- mIsExternal = isExternal;
- mSources = 0;
- mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
- mHasVibrator = false;
- mMotionRanges.clear();
-}
-
-const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
- int32_t axis, uint32_t source) const {
- size_t numRanges = mMotionRanges.size();
- for (size_t i = 0; i < numRanges; i++) {
- const MotionRange& range = mMotionRanges.itemAt(i);
- if (range.axis == axis && range.source == source) {
- return &range;
- }
- }
- return NULL;
-}
-
-void InputDeviceInfo::addSource(uint32_t source) {
- mSources |= source;
-}
-
-void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
- float flat, float fuzz, float resolution) {
- MotionRange range = { axis, source, min, max, flat, fuzz, resolution };
- mMotionRanges.add(range);
-}
-
-void InputDeviceInfo::addMotionRange(const MotionRange& range) {
- mMotionRanges.add(range);
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputDevice.h b/widget/gonk/libui/InputDevice.h
deleted file mode 100644
index 0ab5863c9..000000000
--- a/widget/gonk/libui/InputDevice.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_INPUT_DEVICE_H
-#define _ANDROIDFW_INPUT_DEVICE_H
-
-#include "Input.h"
-#include "KeyCharacterMap.h"
-
-namespace android {
-
-/*
- * Identifies a device.
- */
-struct InputDeviceIdentifier {
- inline InputDeviceIdentifier() :
- bus(0), vendor(0), product(0), version(0) {
- }
-
- // Information provided by the kernel.
- String8 name;
- String8 location;
- String8 uniqueId;
- uint16_t bus;
- uint16_t vendor;
- uint16_t product;
- uint16_t version;
-
- // A composite input device descriptor string that uniquely identifies the device
- // even across reboots or reconnections. The value of this field is used by
- // upper layers of the input system to associate settings with individual devices.
- // It is hashed from whatever kernel provided information is available.
- // Ideally, the way this value is computed should not change between Android releases
- // because that would invalidate persistent settings that rely on it.
- String8 descriptor;
-};
-
-/*
- * Describes the characteristics and capabilities of an input device.
- */
-class InputDeviceInfo {
-public:
- InputDeviceInfo();
- InputDeviceInfo(const InputDeviceInfo& other);
- ~InputDeviceInfo();
-
- struct MotionRange {
- int32_t axis;
- uint32_t source;
- float min;
- float max;
- float flat;
- float fuzz;
- float resolution;
- };
-
- void initialize(int32_t id, int32_t generation, const InputDeviceIdentifier& identifier,
- const String8& alias, bool isExternal);
-
- inline int32_t getId() const { return mId; }
- inline int32_t getGeneration() const { return mGeneration; }
- inline const InputDeviceIdentifier& getIdentifier() const { return mIdentifier; }
- inline const String8& getAlias() const { return mAlias; }
- inline const String8& getDisplayName() const {
- return mAlias.isEmpty() ? mIdentifier.name : mAlias;
- }
- inline bool isExternal() const { return mIsExternal; }
- inline uint32_t getSources() const { return mSources; }
-
- const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
-
- void addSource(uint32_t source);
- void addMotionRange(int32_t axis, uint32_t source,
- float min, float max, float flat, float fuzz, float resolution);
- void addMotionRange(const MotionRange& range);
-
- inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
- inline int32_t getKeyboardType() const { return mKeyboardType; }
-
- inline void setKeyCharacterMap(const sp<KeyCharacterMap>& value) {
- mKeyCharacterMap = value;
- }
-
- inline sp<KeyCharacterMap> getKeyCharacterMap() const {
- return mKeyCharacterMap;
- }
-
- inline void setVibrator(bool hasVibrator) { mHasVibrator = hasVibrator; }
- inline bool hasVibrator() const { return mHasVibrator; }
-
- inline const Vector<MotionRange>& getMotionRanges() const {
- return mMotionRanges;
- }
-
-private:
- int32_t mId;
- int32_t mGeneration;
- InputDeviceIdentifier mIdentifier;
- String8 mAlias;
- bool mIsExternal;
- uint32_t mSources;
- int32_t mKeyboardType;
- sp<KeyCharacterMap> mKeyCharacterMap;
- bool mHasVibrator;
-
- Vector<MotionRange> mMotionRanges;
-};
-
-/* Types of input device configuration files. */
-enum InputDeviceConfigurationFileType {
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0, /* .idc file */
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT = 1, /* .kl file */
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP = 2, /* .kcm file */
-};
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The device identifier is used to construct several default configuration file
- * names to try based on the device name, vendor, product, and version.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByDeviceIdentifier(
- const InputDeviceIdentifier& deviceIdentifier,
- InputDeviceConfigurationFileType type);
-
-/*
- * Gets the path of an input device configuration file, if one is available.
- * Considers both system provided and user installed configuration files.
- *
- * The name is case-sensitive and is used to construct the filename to resolve.
- * All characters except 'a'-'z', 'A'-'Z', '0'-'9', '-', and '_' are replaced by underscores.
- *
- * Returns an empty string if not found.
- */
-extern String8 getInputDeviceConfigurationFilePathByName(
- const String8& name, InputDeviceConfigurationFileType type);
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_DEVICE_H
diff --git a/widget/gonk/libui/InputDispatcher.cpp b/widget/gonk/libui/InputDispatcher.cpp
deleted file mode 100644
index 7adaa1998..000000000
--- a/widget/gonk/libui/InputDispatcher.cpp
+++ /dev/null
@@ -1,4430 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputDispatcher"
-#define ATRACE_TAG ATRACE_TAG_INPUT
-
-//#define LOG_NDEBUG 0
-#include "cutils_log.h"
-
-// Log detailed debug messages about each inbound event notification to the dispatcher.
-#define DEBUG_INBOUND_EVENT_DETAILS 0
-
-// Log detailed debug messages about each outbound event processed by the dispatcher.
-#define DEBUG_OUTBOUND_EVENT_DETAILS 0
-
-// Log debug messages about the dispatch cycle.
-#define DEBUG_DISPATCH_CYCLE 0
-
-// Log debug messages about registrations.
-#define DEBUG_REGISTRATION 0
-
-// Log debug messages about input event injection.
-#define DEBUG_INJECTION 0
-
-// Log debug messages about input focus tracking.
-#define DEBUG_FOCUS 0
-
-// Log debug messages about the app switch latency optimization.
-#define DEBUG_APP_SWITCH 0
-
-// Log debug messages about hover events.
-#define DEBUG_HOVER 0
-
-#include "InputDispatcher.h"
-
-#include "Trace.h"
-#include "PowerManager.h"
-
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <time.h>
-
-#define INDENT " "
-#define INDENT2 " "
-#define INDENT3 " "
-#define INDENT4 " "
-
-namespace android {
-
-// Default input dispatching timeout if there is no focused application or paused window
-// from which to determine an appropriate dispatching timeout.
-const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
-
-// Amount of time to allow for all pending events to be processed when an app switch
-// key is on the way. This is used to preempt input dispatch and drop input events
-// when an application takes too long to respond and the user has pressed an app switch key.
-const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
-
-// Amount of time to allow for an event to be dispatched (measured since its eventTime)
-// before considering it stale and dropping it.
-const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
-
-// Amount of time to allow touch events to be streamed out to a connection before requiring
-// that the first event be finished. This value extends the ANR timeout by the specified
-// amount. For example, if streaming is allowed to get ahead by one second relative to the
-// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
-const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
-
-// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
-const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
-
-
-static inline nsecs_t now() {
- return systemTime(SYSTEM_TIME_MONOTONIC);
-}
-
-static inline const char* toString(bool value) {
- return value ? "true" : "false";
-}
-
-static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
- return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
- >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-}
-
-static bool isValidKeyAction(int32_t action) {
- switch (action) {
- case AKEY_EVENT_ACTION_DOWN:
- case AKEY_EVENT_ACTION_UP:
- return true;
- default:
- return false;
- }
-}
-
-static bool validateKeyEvent(int32_t action) {
- if (! isValidKeyAction(action)) {
- ALOGE("Key event has invalid action code 0x%x", action);
- return false;
- }
- return true;
-}
-
-static bool isValidMotionAction(int32_t action, size_t pointerCount) {
- switch (action & AMOTION_EVENT_ACTION_MASK) {
- case AMOTION_EVENT_ACTION_DOWN:
- case AMOTION_EVENT_ACTION_UP:
- case AMOTION_EVENT_ACTION_CANCEL:
- case AMOTION_EVENT_ACTION_MOVE:
- case AMOTION_EVENT_ACTION_OUTSIDE:
- case AMOTION_EVENT_ACTION_HOVER_ENTER:
- case AMOTION_EVENT_ACTION_HOVER_MOVE:
- case AMOTION_EVENT_ACTION_HOVER_EXIT:
- case AMOTION_EVENT_ACTION_SCROLL:
- return true;
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- case AMOTION_EVENT_ACTION_POINTER_UP: {
- int32_t index = getMotionEventActionPointerIndex(action);
- return index >= 0 && size_t(index) < pointerCount;
- }
- default:
- return false;
- }
-}
-
-static bool validateMotionEvent(int32_t action, size_t pointerCount,
- const PointerProperties* pointerProperties) {
- if (! isValidMotionAction(action, pointerCount)) {
- ALOGE("Motion event has invalid action code 0x%x", action);
- return false;
- }
- if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
- ALOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
- pointerCount, MAX_POINTERS);
- return false;
- }
- BitSet32 pointerIdBits;
- for (size_t i = 0; i < pointerCount; i++) {
- int32_t id = pointerProperties[i].id;
- if (id < 0 || id > MAX_POINTER_ID) {
- ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
- id, MAX_POINTER_ID);
- return false;
- }
- if (pointerIdBits.hasBit(id)) {
- ALOGE("Motion event has duplicate pointer id %d", id);
- return false;
- }
- pointerIdBits.markBit(id);
- }
- return true;
-}
-
-static bool isMainDisplay(int32_t displayId) {
- return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
-}
-
-static void dumpRegion(String8& dump, const SkRegion& region) {
- if (region.isEmpty()) {
- dump.append("<empty>");
- return;
- }
-
- bool first = true;
- for (SkRegion::Iterator it(region); !it.done(); it.next()) {
- if (first) {
- first = false;
- } else {
- dump.append("|");
- }
- const SkIRect& rect = it.rect();
- dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
- }
-}
-
-
-// --- InputDispatcher ---
-
-InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
- mPolicy(policy),
- mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
- mNextUnblockedEvent(NULL),
- mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
- mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
- mLooper = new Looper(false);
-
- mKeyRepeatState.lastKeyEntry = NULL;
-
- policy->getDispatcherConfiguration(&mConfig);
-}
-
-InputDispatcher::~InputDispatcher() {
- { // acquire lock
- AutoMutex _l(mLock);
-
- resetKeyRepeatLocked();
- releasePendingEventLocked();
- drainInboundQueueLocked();
- }
-
- while (mConnectionsByFd.size() != 0) {
- unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
- }
-}
-
-void InputDispatcher::dispatchOnce() {
- nsecs_t nextWakeupTime = LONG_LONG_MAX;
- { // acquire lock
- AutoMutex _l(mLock);
- mDispatcherIsAliveCondition.broadcast();
-
- // Run a dispatch loop if there are no pending commands.
- // The dispatch loop might enqueue commands to run afterwards.
- if (!haveCommandsLocked()) {
- dispatchOnceInnerLocked(&nextWakeupTime);
- }
-
- // Run all pending commands if there are any.
- // If any commands were run then force the next poll to wake up immediately.
- if (runCommandsLockedInterruptible()) {
- nextWakeupTime = LONG_LONG_MIN;
- }
- } // release lock
-
- // Wait for callback or timeout or wake. (make sure we round up, not down)
- nsecs_t currentTime = now();
- int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
- mLooper->pollOnce(timeoutMillis);
-}
-
-void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
- nsecs_t currentTime = now();
-
- // Reset the key repeat timer whenever we disallow key events, even if the next event
- // is not a key. This is to ensure that we abort a key repeat if the device is just coming
- // out of sleep.
- if (!mPolicy->isKeyRepeatEnabled()) {
- resetKeyRepeatLocked();
- }
-
- // If dispatching is frozen, do not process timeouts or try to deliver any new events.
- if (mDispatchFrozen) {
-#if DEBUG_FOCUS
- ALOGD("Dispatch frozen. Waiting some more.");
-#endif
- return;
- }
-
- // Optimize latency of app switches.
- // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
- // been pressed. When it expires, we preempt dispatch and drop all other pending events.
- bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
- if (mAppSwitchDueTime < *nextWakeupTime) {
- *nextWakeupTime = mAppSwitchDueTime;
- }
-
- // Ready to start a new event.
- // If we don't already have a pending event, go grab one.
- if (! mPendingEvent) {
- if (mInboundQueue.isEmpty()) {
- if (isAppSwitchDue) {
- // The inbound queue is empty so the app switch key we were waiting
- // for will never arrive. Stop waiting for it.
- resetPendingAppSwitchLocked(false);
- isAppSwitchDue = false;
- }
-
- // Synthesize a key repeat if appropriate.
- if (mKeyRepeatState.lastKeyEntry) {
- if (currentTime >= mKeyRepeatState.nextRepeatTime) {
- mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
- } else {
- if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
- *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
- }
- }
- }
-
- // Nothing to do if there is no pending event.
- if (!mPendingEvent) {
- return;
- }
- } else {
- // Inbound queue has at least one entry.
- mPendingEvent = mInboundQueue.dequeueAtHead();
- traceInboundQueueLengthLocked();
- }
-
- // Poke user activity for this event.
- if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
- pokeUserActivityLocked(mPendingEvent);
- }
-
- // Get ready to dispatch the event.
- resetANRTimeoutsLocked();
- }
-
- // Now we have an event to dispatch.
- // All events are eventually dequeued and processed this way, even if we intend to drop them.
- ALOG_ASSERT(mPendingEvent != NULL);
- bool done = false;
- DropReason dropReason = DROP_REASON_NOT_DROPPED;
- if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
- dropReason = DROP_REASON_POLICY;
- } else if (!mDispatchEnabled) {
- dropReason = DROP_REASON_DISABLED;
- }
-
- if (mNextUnblockedEvent == mPendingEvent) {
- mNextUnblockedEvent = NULL;
- }
-
- switch (mPendingEvent->type) {
- case EventEntry::TYPE_CONFIGURATION_CHANGED: {
- ConfigurationChangedEntry* typedEntry =
- static_cast<ConfigurationChangedEntry*>(mPendingEvent);
- done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
- break;
- }
-
- case EventEntry::TYPE_DEVICE_RESET: {
- DeviceResetEntry* typedEntry =
- static_cast<DeviceResetEntry*>(mPendingEvent);
- done = dispatchDeviceResetLocked(currentTime, typedEntry);
- dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
- break;
- }
-
- case EventEntry::TYPE_KEY: {
- KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
- if (isAppSwitchDue) {
- if (isAppSwitchKeyEventLocked(typedEntry)) {
- resetPendingAppSwitchLocked(true);
- isAppSwitchDue = false;
- } else if (dropReason == DROP_REASON_NOT_DROPPED) {
- dropReason = DROP_REASON_APP_SWITCH;
- }
- }
- if (dropReason == DROP_REASON_NOT_DROPPED
- && isStaleEventLocked(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
- }
- done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
- MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
- dropReason = DROP_REASON_APP_SWITCH;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED
- && isStaleEventLocked(currentTime, typedEntry)) {
- dropReason = DROP_REASON_STALE;
- }
- if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
- dropReason = DROP_REASON_BLOCKED;
- }
- done = dispatchMotionLocked(currentTime, typedEntry,
- &dropReason, nextWakeupTime);
- break;
- }
-
- default:
- ALOG_ASSERT(false);
- break;
- }
-
- if (done) {
- if (dropReason != DROP_REASON_NOT_DROPPED) {
- dropInboundEventLocked(mPendingEvent, dropReason);
- }
-
- releasePendingEventLocked();
- *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
- }
-}
-
-bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
- bool needWake = mInboundQueue.isEmpty();
- mInboundQueue.enqueueAtTail(entry);
- traceInboundQueueLengthLocked();
-
- switch (entry->type) {
- case EventEntry::TYPE_KEY: {
- // Optimize app switch latency.
- // If the application takes too long to catch up then we drop all events preceding
- // the app switch key.
- KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
- if (isAppSwitchKeyEventLocked(keyEntry)) {
- if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
- mAppSwitchSawKeyDown = true;
- } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
- if (mAppSwitchSawKeyDown) {
-#if DEBUG_APP_SWITCH
- ALOGD("App switch is pending!");
-#endif
- mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
- mAppSwitchSawKeyDown = false;
- needWake = true;
- }
- }
- }
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
- // Optimize case where the current application is unresponsive and the user
- // decides to touch a window in a different application.
- // If the application takes too long to catch up then we drop all events preceding
- // the touch into the other window.
- MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
- && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
- && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
- && mInputTargetWaitApplicationHandle != NULL) {
- int32_t displayId = motionEntry->displayId;
- int32_t x = int32_t(motionEntry->pointerCoords[0].
- getAxisValue(AMOTION_EVENT_AXIS_X));
- int32_t y = int32_t(motionEntry->pointerCoords[0].
- getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
- if (touchedWindowHandle != NULL
- && touchedWindowHandle->inputApplicationHandle
- != mInputTargetWaitApplicationHandle) {
- // User touched a different application than the one we are waiting on.
- // Flag the event, and start pruning the input queue.
- mNextUnblockedEvent = motionEntry;
- needWake = true;
- }
- }
- break;
- }
- }
-
- return needWake;
-}
-
-sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
- int32_t x, int32_t y) {
- // Traverse windows from front to back to find touched window.
- size_t numWindows = mWindowHandles.size();
- for (size_t i = 0; i < numWindows; i++) {
- sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
- if (windowInfo->displayId == displayId) {
- int32_t flags = windowInfo->layoutParamsFlags;
-
- if (windowInfo->visible) {
- if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
- bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
- | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
- if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
- // Found window.
- return windowHandle;
- }
- }
- }
-
- if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
- // Error window is on top but not visible, so touch is dropped.
- return NULL;
- }
- }
- }
- return NULL;
-}
-
-void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
- const char* reason;
- switch (dropReason) {
- case DROP_REASON_POLICY:
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("Dropped event because policy consumed it.");
-#endif
- reason = "inbound event was dropped because the policy consumed it";
- break;
- case DROP_REASON_DISABLED:
- ALOGI("Dropped event because input dispatch is disabled.");
- reason = "inbound event was dropped because input dispatch is disabled";
- break;
- case DROP_REASON_APP_SWITCH:
- ALOGI("Dropped event because of pending overdue app switch.");
- reason = "inbound event was dropped because of pending overdue app switch";
- break;
- case DROP_REASON_BLOCKED:
- ALOGI("Dropped event because the current application is not responding and the user "
- "has started interacting with a different application.");
- reason = "inbound event was dropped because the current application is not responding "
- "and the user has started interacting with a different application";
- break;
- case DROP_REASON_STALE:
- ALOGI("Dropped event because it is stale.");
- reason = "inbound event was dropped because it is stale";
- break;
- default:
- ALOG_ASSERT(false);
- return;
- }
-
- switch (entry->type) {
- case EventEntry::TYPE_KEY: {
- CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
- synthesizeCancelationEventsForAllConnectionsLocked(options);
- break;
- }
- case EventEntry::TYPE_MOTION: {
- MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
- synthesizeCancelationEventsForAllConnectionsLocked(options);
- } else {
- CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
- synthesizeCancelationEventsForAllConnectionsLocked(options);
- }
- break;
- }
- }
-}
-
-bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
- return keyCode == AKEYCODE_HOME
- || keyCode == AKEYCODE_ENDCALL
- || keyCode == AKEYCODE_APP_SWITCH;
-}
-
-bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
- return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
- && isAppSwitchKeyCode(keyEntry->keyCode)
- && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
- && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
-}
-
-bool InputDispatcher::isAppSwitchPendingLocked() {
- return mAppSwitchDueTime != LONG_LONG_MAX;
-}
-
-void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
- mAppSwitchDueTime = LONG_LONG_MAX;
-
-#if DEBUG_APP_SWITCH
- if (handled) {
- ALOGD("App switch has arrived.");
- } else {
- ALOGD("App switch was abandoned.");
- }
-#endif
-}
-
-bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
- return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
-}
-
-bool InputDispatcher::haveCommandsLocked() const {
- return !mCommandQueue.isEmpty();
-}
-
-bool InputDispatcher::runCommandsLockedInterruptible() {
- if (mCommandQueue.isEmpty()) {
- return false;
- }
-
- do {
- CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
-
- Command command = commandEntry->command;
- (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
-
- commandEntry->connection.clear();
- delete commandEntry;
- } while (! mCommandQueue.isEmpty());
- return true;
-}
-
-InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
- CommandEntry* commandEntry = new CommandEntry(command);
- mCommandQueue.enqueueAtTail(commandEntry);
- return commandEntry;
-}
-
-void InputDispatcher::drainInboundQueueLocked() {
- while (! mInboundQueue.isEmpty()) {
- EventEntry* entry = mInboundQueue.dequeueAtHead();
- releaseInboundEventLocked(entry);
- }
- traceInboundQueueLengthLocked();
-}
-
-void InputDispatcher::releasePendingEventLocked() {
- if (mPendingEvent) {
- resetANRTimeoutsLocked();
- releaseInboundEventLocked(mPendingEvent);
- mPendingEvent = NULL;
- }
-}
-
-void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
- InjectionState* injectionState = entry->injectionState;
- if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("Injected inbound event was dropped.");
-#endif
- setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
- }
- if (entry == mNextUnblockedEvent) {
- mNextUnblockedEvent = NULL;
- }
- entry->release();
-}
-
-void InputDispatcher::resetKeyRepeatLocked() {
- if (mKeyRepeatState.lastKeyEntry) {
- mKeyRepeatState.lastKeyEntry->release();
- mKeyRepeatState.lastKeyEntry = NULL;
- }
-}
-
-InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
- KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
-
- // Reuse the repeated key entry if it is otherwise unreferenced.
- uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
- | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
- if (entry->refCount == 1) {
- entry->recycle();
- entry->eventTime = currentTime;
- entry->policyFlags = policyFlags;
- entry->repeatCount += 1;
- } else {
- KeyEntry* newEntry = new KeyEntry(currentTime,
- entry->deviceId, entry->source, policyFlags,
- entry->action, entry->flags, entry->keyCode, entry->scanCode,
- entry->metaState, entry->repeatCount + 1, entry->downTime);
-
- mKeyRepeatState.lastKeyEntry = newEntry;
- entry->release();
-
- entry = newEntry;
- }
- entry->syntheticRepeat = true;
-
- // Increment reference count since we keep a reference to the event in
- // mKeyRepeatState.lastKeyEntry in addition to the one we return.
- entry->refCount += 1;
-
- mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
- return entry;
-}
-
-bool InputDispatcher::dispatchConfigurationChangedLocked(
- nsecs_t currentTime, ConfigurationChangedEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
-#endif
-
- // Reset key repeating in case a keyboard device was added or removed or something.
- resetKeyRepeatLocked();
-
- // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doNotifyConfigurationChangedInterruptible);
- commandEntry->eventTime = entry->eventTime;
- return true;
-}
-
-bool InputDispatcher::dispatchDeviceResetLocked(
- nsecs_t currentTime, DeviceResetEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
-#endif
-
- CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
- "device was reset");
- options.deviceId = entry->deviceId;
- synthesizeCancelationEventsForAllConnectionsLocked(options);
- return true;
-}
-
-bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
- DropReason* dropReason, nsecs_t* nextWakeupTime) {
- // Preprocessing.
- if (! entry->dispatchInProgress) {
- if (entry->repeatCount == 0
- && entry->action == AKEY_EVENT_ACTION_DOWN
- && (entry->policyFlags & POLICY_FLAG_TRUSTED)
- && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
- if (mKeyRepeatState.lastKeyEntry
- && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
- // We have seen two identical key downs in a row which indicates that the device
- // driver is automatically generating key repeats itself. We take note of the
- // repeat here, but we disable our own next key repeat timer since it is clear that
- // we will not need to synthesize key repeats ourselves.
- entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
- resetKeyRepeatLocked();
- mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
- } else {
- // Not a repeat. Save key down state in case we do see a repeat later.
- resetKeyRepeatLocked();
- mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
- }
- mKeyRepeatState.lastKeyEntry = entry;
- entry->refCount += 1;
- } else if (! entry->syntheticRepeat) {
- resetKeyRepeatLocked();
- }
-
- if (entry->repeatCount == 1) {
- entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
- } else {
- entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
- }
-
- entry->dispatchInProgress = true;
-
- logOutboundKeyDetailsLocked("dispatchKey - ", entry);
- }
-
- // Handle case where the policy asked us to try again later last time.
- if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
- if (currentTime < entry->interceptKeyWakeupTime) {
- if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
- *nextWakeupTime = entry->interceptKeyWakeupTime;
- }
- return false; // wait until next wakeup
- }
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
- entry->interceptKeyWakeupTime = 0;
- }
-
- // Give the policy a chance to intercept the key.
- if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
- if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
- if (mFocusedWindowHandle != NULL) {
- commandEntry->inputWindowHandle = mFocusedWindowHandle;
- }
- commandEntry->keyEntry = entry;
- entry->refCount += 1;
- return false; // wait for the command to run
- } else {
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
- }
- } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
- if (*dropReason == DROP_REASON_NOT_DROPPED) {
- *dropReason = DROP_REASON_POLICY;
- }
- }
-
- // Clean up if dropping the event.
- if (*dropReason != DROP_REASON_NOT_DROPPED) {
- setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
- ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
- return true;
- }
-
- // Identify targets.
- Vector<InputTarget> inputTargets;
- int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
- entry, inputTargets, nextWakeupTime);
- if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
- return false;
- }
-
- setInjectionResultLocked(entry, injectionResult);
- if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
- return true;
- }
-
- addMonitoringTargetsLocked(inputTargets);
-
- // Dispatch the key.
- dispatchEventLocked(currentTime, entry, inputTargets);
- return true;
-}
-
-void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
- "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
- "repeatCount=%d, downTime=%lld",
- prefix,
- entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
- entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
- entry->repeatCount, entry->downTime);
-#endif
-}
-
-bool InputDispatcher::dispatchMotionLocked(
- nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
- // Preprocessing.
- if (! entry->dispatchInProgress) {
- entry->dispatchInProgress = true;
-
- logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
- }
-
- // Clean up if dropping the event.
- if (*dropReason != DROP_REASON_NOT_DROPPED) {
- setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
- ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
- return true;
- }
-
- bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
-
- // Identify targets.
- Vector<InputTarget> inputTargets;
-
- bool conflictingPointerActions = false;
- int32_t injectionResult;
- if (isPointerEvent) {
- // Pointer event. (eg. touchscreen)
- injectionResult = findTouchedWindowTargetsLocked(currentTime,
- entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
- } else {
- // Non touch event. (eg. trackball)
- injectionResult = findFocusedWindowTargetsLocked(currentTime,
- entry, inputTargets, nextWakeupTime);
- }
- if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
- return false;
- }
-
- setInjectionResultLocked(entry, injectionResult);
- if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
- return true;
- }
-
- // TODO: support sending secondary display events to input monitors
- if (isMainDisplay(entry->displayId)) {
- addMonitoringTargetsLocked(inputTargets);
- }
-
- // Dispatch the motion.
- if (conflictingPointerActions) {
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "conflicting pointer actions");
- synthesizeCancelationEventsForAllConnectionsLocked(options);
- }
- dispatchEventLocked(currentTime, entry, inputTargets);
- return true;
-}
-
-
-void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
- "action=0x%x, flags=0x%x, "
- "metaState=0x%x, buttonState=0x%x, "
- "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
- prefix,
- entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
- entry->action, entry->flags,
- entry->metaState, entry->buttonState,
- entry->edgeFlags, entry->xPrecision, entry->yPrecision,
- entry->downTime);
-
- for (uint32_t i = 0; i < entry->pointerCount; i++) {
- ALOGD(" Pointer %d: id=%d, toolType=%d, "
- "x=%f, y=%f, pressure=%f, size=%f, "
- "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
- "orientation=%f",
- i, entry->pointerProperties[i].id,
- entry->pointerProperties[i].toolType,
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
- entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
- }
-#endif
-}
-
-void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
- EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("dispatchEventToCurrentInputTargets");
-#endif
-
- ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
-
- pokeUserActivityLocked(eventEntry);
-
- for (size_t i = 0; i < inputTargets.size(); i++) {
- const InputTarget& inputTarget = inputTargets.itemAt(i);
-
- ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
- if (connectionIndex >= 0) {
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
- } else {
-#if DEBUG_FOCUS
- ALOGD("Dropping event delivery to target with channel '%s' because it "
- "is no longer registered with the input dispatcher.",
- inputTarget.inputChannel->getName().string());
-#endif
- }
- }
-}
-
-int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
- const EventEntry* entry,
- const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle,
- nsecs_t* nextWakeupTime, const char* reason) {
- if (applicationHandle == NULL && windowHandle == NULL) {
- if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
-#if DEBUG_FOCUS
- ALOGD("Waiting for system to become ready for input. Reason: %s", reason);
-#endif
- mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
- mInputTargetWaitStartTime = currentTime;
- mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
- mInputTargetWaitTimeoutExpired = false;
- mInputTargetWaitApplicationHandle.clear();
- }
- } else {
- if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
-#if DEBUG_FOCUS
- ALOGD("Waiting for application to become ready for input: %s. Reason: %s",
- getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
- reason);
-#endif
- nsecs_t timeout;
- if (windowHandle != NULL) {
- timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
- } else if (applicationHandle != NULL) {
- timeout = applicationHandle->getDispatchingTimeout(
- DEFAULT_INPUT_DISPATCHING_TIMEOUT);
- } else {
- timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
- }
-
- mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
- mInputTargetWaitStartTime = currentTime;
- mInputTargetWaitTimeoutTime = currentTime + timeout;
- mInputTargetWaitTimeoutExpired = false;
- mInputTargetWaitApplicationHandle.clear();
-
- if (windowHandle != NULL) {
- mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
- }
- if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
- mInputTargetWaitApplicationHandle = applicationHandle;
- }
- }
- }
-
- if (mInputTargetWaitTimeoutExpired) {
- return INPUT_EVENT_INJECTION_TIMED_OUT;
- }
-
- if (currentTime >= mInputTargetWaitTimeoutTime) {
- onANRLocked(currentTime, applicationHandle, windowHandle,
- entry->eventTime, mInputTargetWaitStartTime, reason);
-
- // Force poll loop to wake up immediately on next iteration once we get the
- // ANR response back from the policy.
- *nextWakeupTime = LONG_LONG_MIN;
- return INPUT_EVENT_INJECTION_PENDING;
- } else {
- // Force poll loop to wake up when timeout is due.
- if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
- *nextWakeupTime = mInputTargetWaitTimeoutTime;
- }
- return INPUT_EVENT_INJECTION_PENDING;
- }
-}
-
-void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
- const sp<InputChannel>& inputChannel) {
- if (newTimeout > 0) {
- // Extend the timeout.
- mInputTargetWaitTimeoutTime = now() + newTimeout;
- } else {
- // Give up.
- mInputTargetWaitTimeoutExpired = true;
-
- // Input state will not be realistic. Mark it out of sync.
- if (inputChannel.get()) {
- ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
- if (connectionIndex >= 0) {
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
-
- if (windowHandle != NULL) {
- mTouchState.removeWindow(windowHandle);
- }
-
- if (connection->status == Connection::STATUS_NORMAL) {
- CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
- "application not responding");
- synthesizeCancelationEventsForConnectionLocked(connection, options);
- }
- }
- }
- }
-}
-
-nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
- nsecs_t currentTime) {
- if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
- return currentTime - mInputTargetWaitStartTime;
- }
- return 0;
-}
-
-void InputDispatcher::resetANRTimeoutsLocked() {
-#if DEBUG_FOCUS
- ALOGD("Resetting ANR timeouts.");
-#endif
-
- // Reset input target wait timeout.
- mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
- mInputTargetWaitApplicationHandle.clear();
-}
-
-int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
- const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
- int32_t injectionResult;
-
- // If there is no currently focused window and no focused application
- // then drop the event.
- if (mFocusedWindowHandle == NULL) {
- if (mFocusedApplicationHandle != NULL) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- mFocusedApplicationHandle, NULL, nextWakeupTime,
- "Waiting because no window has focus but there is a "
- "focused application that may eventually add a window "
- "when it finishes starting up.");
- goto Unresponsive;
- }
-
- ALOGI("Dropping event because there is no focused window or focused application.");
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
-
- // Check permissions.
- if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
- injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
- goto Failed;
- }
-
- // If the currently focused window is paused then keep waiting.
- if (mFocusedWindowHandle->getInfo()->paused) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
- "Waiting because the focused window is paused.");
- goto Unresponsive;
- }
-
- // If the currently focused window is still working on previous events then keep waiting.
- if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
- "Waiting because the focused window has not finished "
- "processing the input events that were previously delivered to it.");
- goto Unresponsive;
- }
-
- // Success! Output targets.
- injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
- addWindowTargetLocked(mFocusedWindowHandle,
- InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
- inputTargets);
-
- // Done.
-Failed:
-Unresponsive:
- nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
- updateDispatchStatisticsLocked(currentTime, entry,
- injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
- ALOGD("findFocusedWindow finished: injectionResult=%d, "
- "timeSpentWaitingForApplication=%0.1fms",
- injectionResult, timeSpentWaitingForApplication / 1000000.0);
-#endif
- return injectionResult;
-}
-
-int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
- const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
- bool* outConflictingPointerActions) {
- enum InjectionPermission {
- INJECTION_PERMISSION_UNKNOWN,
- INJECTION_PERMISSION_GRANTED,
- INJECTION_PERMISSION_DENIED
- };
-
- // For security reasons, we defer updating the touch state until we are sure that
- // event injection will be allowed.
- //
- // FIXME In the original code, screenWasOff could never be set to true.
- // The reason is that the POLICY_FLAG_WOKE_HERE
- // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
- // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
- // actually enqueued using the policyFlags that appeared in the final EV_SYN
- // events upon which no preprocessing took place. So policyFlags was always 0.
- // In the new native input dispatcher we're a bit more careful about event
- // preprocessing so the touches we receive can actually have non-zero policyFlags.
- // Unfortunately we obtain undesirable behavior.
- //
- // Here's what happens:
- //
- // When the device dims in anticipation of going to sleep, touches
- // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
- // the device to brighten and reset the user activity timer.
- // Touches on other windows (such as the launcher window)
- // are dropped. Then after a moment, the device goes to sleep. Oops.
- //
- // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
- // instead of POLICY_FLAG_WOKE_HERE...
- //
- bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
-
- int32_t displayId = entry->displayId;
- int32_t action = entry->action;
- int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-
- // Update the touch state as needed based on the properties of the touch event.
- int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
- InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- sp<InputWindowHandle> newHoverWindowHandle;
-
- bool isSplit = mTouchState.split;
- bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
- && (mTouchState.deviceId != entry->deviceId
- || mTouchState.source != entry->source
- || mTouchState.displayId != displayId);
- bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
- bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
- || maskedAction == AMOTION_EVENT_ACTION_SCROLL
- || isHoverAction);
- bool wrongDevice = false;
- if (newGesture) {
- bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
- if (switchedDevice && mTouchState.down && !down) {
-#if DEBUG_FOCUS
- ALOGD("Dropping event because a pointer for a different device is already down.");
-#endif
- mTempTouchState.copyFrom(mTouchState);
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- switchedDevice = false;
- wrongDevice = true;
- goto Failed;
- }
- mTempTouchState.reset();
- mTempTouchState.down = down;
- mTempTouchState.deviceId = entry->deviceId;
- mTempTouchState.source = entry->source;
- mTempTouchState.displayId = displayId;
- isSplit = false;
- } else {
- mTempTouchState.copyFrom(mTouchState);
- }
-
- if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
- /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
-
- int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- int32_t x = int32_t(entry->pointerCoords[pointerIndex].
- getAxisValue(AMOTION_EVENT_AXIS_X));
- int32_t y = int32_t(entry->pointerCoords[pointerIndex].
- getAxisValue(AMOTION_EVENT_AXIS_Y));
- sp<InputWindowHandle> newTouchedWindowHandle;
- sp<InputWindowHandle> topErrorWindowHandle;
- bool isTouchModal = false;
-
- // Traverse windows from front to back to find touched window and outside targets.
- size_t numWindows = mWindowHandles.size();
- for (size_t i = 0; i < numWindows; i++) {
- sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
- if (windowInfo->displayId != displayId) {
- continue; // wrong display
- }
-
- int32_t flags = windowInfo->layoutParamsFlags;
- if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
- if (topErrorWindowHandle == NULL) {
- topErrorWindowHandle = windowHandle;
- }
- }
-
- if (windowInfo->visible) {
- if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
- isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
- | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
- if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
- if (! screenWasOff
- || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
- newTouchedWindowHandle = windowHandle;
- }
- break; // found touched window, exit window loop
- }
- }
-
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
- int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
- if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
- outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
- }
-
- mTempTouchState.addOrUpdateWindow(
- windowHandle, outsideTargetFlags, BitSet32(0));
- }
- }
- }
-
- // If there is an error window but it is not taking focus (typically because
- // it is invisible) then wait for it. Any other focused window may in
- // fact be in ANR state.
- if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- NULL, NULL, nextWakeupTime,
- "Waiting because a system error window is about to be displayed.");
- injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- goto Unresponsive;
- }
-
- // Figure out whether splitting will be allowed for this window.
- if (newTouchedWindowHandle != NULL
- && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
- // New window supports splitting.
- isSplit = true;
- } else if (isSplit) {
- // New window does not support splitting but we have already split events.
- // Ignore the new window.
- newTouchedWindowHandle = NULL;
- }
-
- // Handle the case where we did not find a window.
- if (newTouchedWindowHandle == NULL) {
- // Try to assign the pointer to the first foreground window we find, if there is one.
- newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
- if (newTouchedWindowHandle == NULL) {
- // There is no touched window. If this is an initial down event
- // then wait for a window to appear that will handle the touch. This is
- // to ensure that we report an ANR in the case where an application has started
- // but not yet put up a window and the user is starting to get impatient.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- && mFocusedApplicationHandle != NULL) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- mFocusedApplicationHandle, NULL, nextWakeupTime,
- "Waiting because there is no touchable window that can "
- "handle the event but there is focused application that may "
- "eventually add a new window when it finishes starting up.");
- goto Unresponsive;
- }
-
- ALOGI("Dropping event because there is no touched window.");
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
- }
-
- // Set target flags.
- int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
- if (isSplit) {
- targetFlags |= InputTarget::FLAG_SPLIT;
- }
- if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
- targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
- }
-
- // Update hover state.
- if (isHoverAction) {
- newHoverWindowHandle = newTouchedWindowHandle;
- } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
- newHoverWindowHandle = mLastHoverWindowHandle;
- }
-
- // Update the temporary touch state.
- BitSet32 pointerIds;
- if (isSplit) {
- uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
- pointerIds.markBit(pointerId);
- }
- mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
- } else {
- /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
-
- // If the pointer is not currently down, then ignore the event.
- if (! mTempTouchState.down) {
-#if DEBUG_FOCUS
- ALOGD("Dropping event because the pointer is not down or we previously "
- "dropped the pointer down event.");
-#endif
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
-
- // Check whether touches should slip outside of the current foreground window.
- if (maskedAction == AMOTION_EVENT_ACTION_MOVE
- && entry->pointerCount == 1
- && mTempTouchState.isSlippery()) {
- int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
- int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
-
- sp<InputWindowHandle> oldTouchedWindowHandle =
- mTempTouchState.getFirstForegroundWindowHandle();
- sp<InputWindowHandle> newTouchedWindowHandle =
- findTouchedWindowAtLocked(displayId, x, y);
- if (oldTouchedWindowHandle != newTouchedWindowHandle
- && newTouchedWindowHandle != NULL) {
-#if DEBUG_FOCUS
- ALOGD("Touch is slipping out of window %s into window %s.",
- oldTouchedWindowHandle->getName().string(),
- newTouchedWindowHandle->getName().string());
-#endif
- // Make a slippery exit from the old window.
- mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
- InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
-
- // Make a slippery entrance into the new window.
- if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
- isSplit = true;
- }
-
- int32_t targetFlags = InputTarget::FLAG_FOREGROUND
- | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
- if (isSplit) {
- targetFlags |= InputTarget::FLAG_SPLIT;
- }
- if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
- targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
- }
-
- BitSet32 pointerIds;
- if (isSplit) {
- pointerIds.markBit(entry->pointerProperties[0].id);
- }
- mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
- }
- }
- }
-
- if (newHoverWindowHandle != mLastHoverWindowHandle) {
- // Let the previous window know that the hover sequence is over.
- if (mLastHoverWindowHandle != NULL) {
-#if DEBUG_HOVER
- ALOGD("Sending hover exit event to window %s.",
- mLastHoverWindowHandle->getName().string());
-#endif
- mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
- InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
- }
-
- // Let the new window know that the hover sequence is starting.
- if (newHoverWindowHandle != NULL) {
-#if DEBUG_HOVER
- ALOGD("Sending hover enter event to window %s.",
- newHoverWindowHandle->getName().string());
-#endif
- mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
- InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
- }
- }
-
- // Check permission to inject into all touched foreground windows and ensure there
- // is at least one touched foreground window.
- {
- bool haveForegroundWindow = false;
- for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
- if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
- haveForegroundWindow = true;
- if (! checkInjectionPermission(touchedWindow.windowHandle,
- entry->injectionState)) {
- injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
- injectionPermission = INJECTION_PERMISSION_DENIED;
- goto Failed;
- }
- }
- }
- if (! haveForegroundWindow) {
-#if DEBUG_FOCUS
- ALOGD("Dropping event because there is no touched foreground window to receive it.");
-#endif
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
-
- // Permission granted to injection into all touched foreground windows.
- injectionPermission = INJECTION_PERMISSION_GRANTED;
- }
-
- // Check whether windows listening for outside touches are owned by the same UID. If it is
- // set the policy flag that we will not reveal coordinate information to this window.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- sp<InputWindowHandle> foregroundWindowHandle =
- mTempTouchState.getFirstForegroundWindowHandle();
- const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
- for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
- if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
- sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
- if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
- mTempTouchState.addOrUpdateWindow(inputWindowHandle,
- InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
- }
- }
- }
- }
-
- // Ensure all touched foreground windows are ready for new input.
- for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
- if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
- // If the touched window is paused then keep waiting.
- if (touchedWindow.windowHandle->getInfo()->paused) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- NULL, touchedWindow.windowHandle, nextWakeupTime,
- "Waiting because the touched window is paused.");
- goto Unresponsive;
- }
-
- // If the touched window is still working on previous events then keep waiting.
- if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- NULL, touchedWindow.windowHandle, nextWakeupTime,
- "Waiting because the touched window has not finished "
- "processing the input events that were previously delivered to it.");
- goto Unresponsive;
- }
- }
- }
-
- // If this is the first pointer going down and the touched window has a wallpaper
- // then also add the touched wallpaper windows so they are locked in for the duration
- // of the touch gesture.
- // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
- // engine only supports touch events. We would need to add a mechanism similar
- // to View.onGenericMotionEvent to enable wallpapers to handle these events.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- sp<InputWindowHandle> foregroundWindowHandle =
- mTempTouchState.getFirstForegroundWindowHandle();
- if (foregroundWindowHandle->getInfo()->hasWallpaper) {
- for (size_t i = 0; i < mWindowHandles.size(); i++) {
- sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
- const InputWindowInfo* info = windowHandle->getInfo();
- if (info->displayId == displayId
- && windowHandle->getInfo()->layoutParamsType
- == InputWindowInfo::TYPE_WALLPAPER) {
- mTempTouchState.addOrUpdateWindow(windowHandle,
- InputTarget::FLAG_WINDOW_IS_OBSCURED
- | InputTarget::FLAG_DISPATCH_AS_IS,
- BitSet32(0));
- }
- }
- }
- }
-
- // Success! Output targets.
- injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-
- for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
- addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
- touchedWindow.pointerIds, inputTargets);
- }
-
- // Drop the outside or hover touch windows since we will not care about them
- // in the next iteration.
- mTempTouchState.filterNonAsIsTouchWindows();
-
-Failed:
- // Check injection permission once and for all.
- if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
- if (checkInjectionPermission(NULL, entry->injectionState)) {
- injectionPermission = INJECTION_PERMISSION_GRANTED;
- } else {
- injectionPermission = INJECTION_PERMISSION_DENIED;
- }
- }
-
- // Update final pieces of touch state if the injector had permission.
- if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
- if (!wrongDevice) {
- if (switchedDevice) {
-#if DEBUG_FOCUS
- ALOGD("Conflicting pointer actions: Switched to a different device.");
-#endif
- *outConflictingPointerActions = true;
- }
-
- if (isHoverAction) {
- // Started hovering, therefore no longer down.
- if (mTouchState.down) {
-#if DEBUG_FOCUS
- ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
-#endif
- *outConflictingPointerActions = true;
- }
- mTouchState.reset();
- if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
- || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
- mTouchState.deviceId = entry->deviceId;
- mTouchState.source = entry->source;
- mTouchState.displayId = displayId;
- }
- } else if (maskedAction == AMOTION_EVENT_ACTION_UP
- || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
- // All pointers up or canceled.
- mTouchState.reset();
- } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- // First pointer went down.
- if (mTouchState.down) {
-#if DEBUG_FOCUS
- ALOGD("Conflicting pointer actions: Down received while already down.");
-#endif
- *outConflictingPointerActions = true;
- }
- mTouchState.copyFrom(mTempTouchState);
- } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
- // One pointer went up.
- if (isSplit) {
- int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
-
- for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
- TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
- if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
- touchedWindow.pointerIds.clearBit(pointerId);
- if (touchedWindow.pointerIds.isEmpty()) {
- mTempTouchState.windows.removeAt(i);
- continue;
- }
- }
- i += 1;
- }
- }
- mTouchState.copyFrom(mTempTouchState);
- } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
- // Discard temporary touch state since it was only valid for this action.
- } else {
- // Save changes to touch state as-is for all other actions.
- mTouchState.copyFrom(mTempTouchState);
- }
-
- // Update hover state.
- mLastHoverWindowHandle = newHoverWindowHandle;
- }
- } else {
-#if DEBUG_FOCUS
- ALOGD("Not updating touch focus because injection was denied.");
-#endif
- }
-
-Unresponsive:
- // Reset temporary touch state to ensure we release unnecessary references to input channels.
- mTempTouchState.reset();
-
- nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
- updateDispatchStatisticsLocked(currentTime, entry,
- injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
- ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
- "timeSpentWaitingForApplication=%0.1fms",
- injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
-#endif
- return injectionResult;
-}
-
-void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
- int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
- inputTargets.push();
-
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
- InputTarget& target = inputTargets.editTop();
- target.inputChannel = windowInfo->inputChannel;
- target.flags = targetFlags;
- target.xOffset = - windowInfo->frameLeft;
- target.yOffset = - windowInfo->frameTop;
- target.scaleFactor = windowInfo->scaleFactor;
- target.pointerIds = pointerIds;
-}
-
-void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
- for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
- inputTargets.push();
-
- InputTarget& target = inputTargets.editTop();
- target.inputChannel = mMonitoringChannels[i];
- target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
- target.xOffset = 0;
- target.yOffset = 0;
- target.pointerIds.clear();
- target.scaleFactor = 1.0f;
- }
-}
-
-bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
- const InjectionState* injectionState) {
- if (injectionState
- && (windowHandle == NULL
- || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
- && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
- if (windowHandle != NULL) {
- ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
- "owned by uid %d",
- injectionState->injectorPid, injectionState->injectorUid,
- windowHandle->getName().string(),
- windowHandle->getInfo()->ownerUid);
- } else {
- ALOGW("Permission denied: injecting event from pid %d uid %d",
- injectionState->injectorPid, injectionState->injectorUid);
- }
- return false;
- }
- return true;
-}
-
-bool InputDispatcher::isWindowObscuredAtPointLocked(
- const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
- int32_t displayId = windowHandle->getInfo()->displayId;
- size_t numWindows = mWindowHandles.size();
- for (size_t i = 0; i < numWindows; i++) {
- sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
- if (otherHandle == windowHandle) {
- break;
- }
-
- const InputWindowInfo* otherInfo = otherHandle->getInfo();
- if (otherInfo->displayId == displayId
- && otherInfo->visible && !otherInfo->isTrustedOverlay()
- && otherInfo->frameContainsPoint(x, y)) {
- return true;
- }
- }
- return false;
-}
-
-bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
- const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
- ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
- if (connectionIndex >= 0) {
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- if (connection->inputPublisherBlocked) {
- return false;
- }
- if (eventEntry->type == EventEntry::TYPE_KEY) {
- // If the event is a key event, then we must wait for all previous events to
- // complete before delivering it because previous events may have the
- // side-effect of transferring focus to a different window and we want to
- // ensure that the following keys are sent to the new window.
- //
- // Suppose the user touches a button in a window then immediately presses "A".
- // If the button causes a pop-up window to appear then we want to ensure that
- // the "A" key is delivered to the new pop-up window. This is because users
- // often anticipate pending UI changes when typing on a keyboard.
- // To obtain this behavior, we must serialize key events with respect to all
- // prior input events.
- return connection->outboundQueue.isEmpty()
- && connection->waitQueue.isEmpty();
- }
- // Touch events can always be sent to a window immediately because the user intended
- // to touch whatever was visible at the time. Even if focus changes or a new
- // window appears moments later, the touch event was meant to be delivered to
- // whatever window happened to be on screen at the time.
- //
- // Generic motion events, such as trackball or joystick events are a little trickier.
- // Like key events, generic motion events are delivered to the focused window.
- // Unlike key events, generic motion events don't tend to transfer focus to other
- // windows and it is not important for them to be serialized. So we prefer to deliver
- // generic motion events as soon as possible to improve efficiency and reduce lag
- // through batching.
- //
- // The one case where we pause input event delivery is when the wait queue is piling
- // up with lots of events because the application is not responding.
- // This condition ensures that ANRs are detected reliably.
- if (!connection->waitQueue.isEmpty()
- && currentTime >= connection->waitQueue.head->eventEntry->eventTime
- + STREAM_AHEAD_EVENT_TIMEOUT) {
- return false;
- }
- }
- return true;
-}
-
-String8 InputDispatcher::getApplicationWindowLabelLocked(
- const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle) {
- if (applicationHandle != NULL) {
- if (windowHandle != NULL) {
- String8 label(applicationHandle->getName());
- label.append(" - ");
- label.append(windowHandle->getName());
- return label;
- } else {
- return applicationHandle->getName();
- }
- } else if (windowHandle != NULL) {
- return windowHandle->getName();
- } else {
- return String8("<unknown application or window>");
- }
-}
-
-void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
- if (mFocusedWindowHandle != NULL) {
- const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
- if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
-#endif
- return;
- }
- }
-
- int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
- switch (eventEntry->type) {
- case EventEntry::TYPE_MOTION: {
- const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
- if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
- return;
- }
-
- if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
- eventType = USER_ACTIVITY_EVENT_TOUCH;
- }
- break;
- }
- case EventEntry::TYPE_KEY: {
- const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
- if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
- return;
- }
- eventType = USER_ACTIVITY_EVENT_BUTTON;
- break;
- }
- }
-
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doPokeUserActivityLockedInterruptible);
- commandEntry->eventTime = eventEntry->eventTime;
- commandEntry->userActivityEventType = eventType;
-}
-
-void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
- const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
- "xOffset=%f, yOffset=%f, scaleFactor=%f, "
- "pointerIds=0x%x",
- connection->getInputChannelName(), inputTarget->flags,
- inputTarget->xOffset, inputTarget->yOffset,
- inputTarget->scaleFactor, inputTarget->pointerIds.value);
-#endif
-
- // Skip this event if the connection status is not normal.
- // We don't want to enqueue additional outbound events if the connection is broken.
- if (connection->status != Connection::STATUS_NORMAL) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
- connection->getInputChannelName(), connection->getStatusLabel());
-#endif
- return;
- }
-
- // Split a motion event if needed.
- if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
- ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
-
- MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
- if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
- MotionEntry* splitMotionEntry = splitMotionEvent(
- originalMotionEntry, inputTarget->pointerIds);
- if (!splitMotionEntry) {
- return; // split event was dropped
- }
-#if DEBUG_FOCUS
- ALOGD("channel '%s' ~ Split motion event.",
- connection->getInputChannelName());
- logOutboundMotionDetailsLocked(" ", splitMotionEntry);
-#endif
- enqueueDispatchEntriesLocked(currentTime, connection,
- splitMotionEntry, inputTarget);
- splitMotionEntry->release();
- return;
- }
- }
-
- // Not splitting. Enqueue dispatch entries for the event as is.
- enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
-}
-
-void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
- const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
- bool wasEmpty = connection->outboundQueue.isEmpty();
-
- // Enqueue dispatch entries for the requested modes.
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_IS);
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
- enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
- InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
-
- // If the outbound queue was previously empty, start the dispatch cycle going.
- if (wasEmpty && !connection->outboundQueue.isEmpty()) {
- startDispatchCycleLocked(currentTime, connection);
- }
-}
-
-void InputDispatcher::enqueueDispatchEntryLocked(
- const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
- int32_t dispatchMode) {
- int32_t inputTargetFlags = inputTarget->flags;
- if (!(inputTargetFlags & dispatchMode)) {
- return;
- }
- inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
-
- // This is a new event.
- // Enqueue a new dispatch entry onto the outbound queue for this connection.
- DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
- inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
- inputTarget->scaleFactor);
-
- // Apply target flags and update the connection's input state.
- switch (eventEntry->type) {
- case EventEntry::TYPE_KEY: {
- KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
- dispatchEntry->resolvedAction = keyEntry->action;
- dispatchEntry->resolvedFlags = keyEntry->flags;
-
- if (!connection->inputState.trackKey(keyEntry,
- dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
- connection->getInputChannelName());
-#endif
- delete dispatchEntry;
- return; // skip the inconsistent event
- }
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
- MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
- if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
- } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
- } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
- } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
- } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
- } else {
- dispatchEntry->resolvedAction = motionEntry->action;
- }
- if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
- && !connection->inputState.isHovering(
- motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
- connection->getInputChannelName());
-#endif
- dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
- }
-
- dispatchEntry->resolvedFlags = motionEntry->flags;
- if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
- dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
- }
-
- if (!connection->inputState.trackMotion(motionEntry,
- dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
- connection->getInputChannelName());
-#endif
- delete dispatchEntry;
- return; // skip the inconsistent event
- }
- break;
- }
- }
-
- // Remember that we are waiting for this dispatch to complete.
- if (dispatchEntry->hasForegroundTarget()) {
- incrementPendingForegroundDispatchesLocked(eventEntry);
- }
-
- // Enqueue the dispatch entry.
- connection->outboundQueue.enqueueAtTail(dispatchEntry);
- traceOutboundQueueLengthLocked(connection);
-}
-
-void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
- const sp<Connection>& connection) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ startDispatchCycle",
- connection->getInputChannelName());
-#endif
-
- while (connection->status == Connection::STATUS_NORMAL
- && !connection->outboundQueue.isEmpty()) {
- DispatchEntry* dispatchEntry = connection->outboundQueue.head;
- dispatchEntry->deliveryTime = currentTime;
-
- // Publish the event.
- status_t status;
- EventEntry* eventEntry = dispatchEntry->eventEntry;
- switch (eventEntry->type) {
- case EventEntry::TYPE_KEY: {
- KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
-
- // Publish the key event.
- status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
- keyEntry->deviceId, keyEntry->source,
- dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
- keyEntry->keyCode, keyEntry->scanCode,
- keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
- keyEntry->eventTime);
- break;
- }
-
- case EventEntry::TYPE_MOTION: {
- MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
-
- PointerCoords scaledCoords[MAX_POINTERS];
- const PointerCoords* usingCoords = motionEntry->pointerCoords;
-
- // Set the X and Y offset depending on the input source.
- float xOffset, yOffset, scaleFactor;
- if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
- && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
- scaleFactor = dispatchEntry->scaleFactor;
- xOffset = dispatchEntry->xOffset * scaleFactor;
- yOffset = dispatchEntry->yOffset * scaleFactor;
- if (scaleFactor != 1.0f) {
- for (size_t i = 0; i < motionEntry->pointerCount; i++) {
- scaledCoords[i] = motionEntry->pointerCoords[i];
- scaledCoords[i].scale(scaleFactor);
- }
- usingCoords = scaledCoords;
- }
- } else {
- xOffset = 0.0f;
- yOffset = 0.0f;
- scaleFactor = 1.0f;
-
- // We don't want the dispatch target to know.
- if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
- for (size_t i = 0; i < motionEntry->pointerCount; i++) {
- scaledCoords[i].clear();
- }
- usingCoords = scaledCoords;
- }
- }
-
- // Publish the motion event.
- status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
- motionEntry->deviceId, motionEntry->source,
- dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
- motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
- xOffset, yOffset,
- motionEntry->xPrecision, motionEntry->yPrecision,
- motionEntry->downTime, motionEntry->eventTime,
- motionEntry->pointerCount, motionEntry->pointerProperties,
- usingCoords);
- break;
- }
-
- default:
- ALOG_ASSERT(false);
- return;
- }
-
- // Check the result.
- if (status) {
- if (status == WOULD_BLOCK) {
- if (connection->waitQueue.isEmpty()) {
- ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
- "This is unexpected because the wait queue is empty, so the pipe "
- "should be empty and we shouldn't have any problems writing an "
- "event to it, status=%d", connection->getInputChannelName(), status);
- abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
- } else {
- // Pipe is full and we are waiting for the app to finish process some events
- // before sending more events to it.
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
- "waiting for the application to catch up",
- connection->getInputChannelName());
-#endif
- connection->inputPublisherBlocked = true;
- }
- } else {
- ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
- "status=%d", connection->getInputChannelName(), status);
- abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
- }
- return;
- }
-
- // Re-enqueue the event on the wait queue.
- connection->outboundQueue.dequeue(dispatchEntry);
- traceOutboundQueueLengthLocked(connection);
- connection->waitQueue.enqueueAtTail(dispatchEntry);
- traceWaitQueueLengthLocked(connection);
- }
-}
-
-void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
- const sp<Connection>& connection, uint32_t seq, bool handled) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
- connection->getInputChannelName(), seq, toString(handled));
-#endif
-
- connection->inputPublisherBlocked = false;
-
- if (connection->status == Connection::STATUS_BROKEN
- || connection->status == Connection::STATUS_ZOMBIE) {
- return;
- }
-
- // Notify other system components and prepare to start the next dispatch cycle.
- onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
-}
-
-void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
- const sp<Connection>& connection, bool notify) {
-#if DEBUG_DISPATCH_CYCLE
- ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
- connection->getInputChannelName(), toString(notify));
-#endif
-
- // Clear the dispatch queues.
- drainDispatchQueueLocked(&connection->outboundQueue);
- traceOutboundQueueLengthLocked(connection);
- drainDispatchQueueLocked(&connection->waitQueue);
- traceWaitQueueLengthLocked(connection);
-
- // The connection appears to be unrecoverably broken.
- // Ignore already broken or zombie connections.
- if (connection->status == Connection::STATUS_NORMAL) {
- connection->status = Connection::STATUS_BROKEN;
-
- if (notify) {
- // Notify other system components.
- onDispatchCycleBrokenLocked(currentTime, connection);
- }
- }
-}
-
-void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
- while (!queue->isEmpty()) {
- DispatchEntry* dispatchEntry = queue->dequeueAtHead();
- releaseDispatchEntryLocked(dispatchEntry);
- }
-}
-
-void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
- if (dispatchEntry->hasForegroundTarget()) {
- decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
- }
- delete dispatchEntry;
-}
-
-int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
- InputDispatcher* d = static_cast<InputDispatcher*>(data);
-
- { // acquire lock
- AutoMutex _l(d->mLock);
-
- ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
- if (connectionIndex < 0) {
- ALOGE("Received spurious receive callback for unknown input channel. "
- "fd=%d, events=0x%x", fd, events);
- return 0; // remove the callback
- }
-
- bool notify;
- sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
- if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
- if (!(events & ALOOPER_EVENT_INPUT)) {
- ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
- "events=0x%x", connection->getInputChannelName(), events);
- return 1;
- }
-
- nsecs_t currentTime = now();
- bool gotOne = false;
- status_t status;
- for (;;) {
- uint32_t seq;
- bool handled;
- status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
- if (status) {
- break;
- }
- d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
- gotOne = true;
- }
- if (gotOne) {
- d->runCommandsLockedInterruptible();
- if (status == WOULD_BLOCK) {
- return 1;
- }
- }
-
- notify = status != DEAD_OBJECT || !connection->monitor;
- if (notify) {
- ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
- connection->getInputChannelName(), status);
- }
- } else {
- // Monitor channels are never explicitly unregistered.
- // We do it automatically when the remote endpoint is closed so don't warn
- // about them.
- notify = !connection->monitor;
- if (notify) {
- ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
- "events=0x%x", connection->getInputChannelName(), events);
- }
- }
-
- // Unregister the channel.
- d->unregisterInputChannelLocked(connection->inputChannel, notify);
- return 0; // remove the callback
- } // release lock
-}
-
-void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
- const CancelationOptions& options) {
- for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
- synthesizeCancelationEventsForConnectionLocked(
- mConnectionsByFd.valueAt(i), options);
- }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
- const sp<InputChannel>& channel, const CancelationOptions& options) {
- ssize_t index = getConnectionIndexLocked(channel);
- if (index >= 0) {
- synthesizeCancelationEventsForConnectionLocked(
- mConnectionsByFd.valueAt(index), options);
- }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
- const sp<Connection>& connection, const CancelationOptions& options) {
- if (connection->status == Connection::STATUS_BROKEN) {
- return;
- }
-
- nsecs_t currentTime = now();
-
- Vector<EventEntry*> cancelationEvents;
- connection->inputState.synthesizeCancelationEvents(currentTime,
- cancelationEvents, options);
-
- if (!cancelationEvents.isEmpty()) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
- "with reality: %s, mode=%d.",
- connection->getInputChannelName(), cancelationEvents.size(),
- options.reason, options.mode);
-#endif
- for (size_t i = 0; i < cancelationEvents.size(); i++) {
- EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
- switch (cancelationEventEntry->type) {
- case EventEntry::TYPE_KEY:
- logOutboundKeyDetailsLocked("cancel - ",
- static_cast<KeyEntry*>(cancelationEventEntry));
- break;
- case EventEntry::TYPE_MOTION:
- logOutboundMotionDetailsLocked("cancel - ",
- static_cast<MotionEntry*>(cancelationEventEntry));
- break;
- }
-
- InputTarget target;
- sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
- if (windowHandle != NULL) {
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
- target.xOffset = -windowInfo->frameLeft;
- target.yOffset = -windowInfo->frameTop;
- target.scaleFactor = windowInfo->scaleFactor;
- } else {
- target.xOffset = 0;
- target.yOffset = 0;
- target.scaleFactor = 1.0f;
- }
- target.inputChannel = connection->inputChannel;
- target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
-
- enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
- &target, InputTarget::FLAG_DISPATCH_AS_IS);
-
- cancelationEventEntry->release();
- }
-
- startDispatchCycleLocked(currentTime, connection);
- }
-}
-
-InputDispatcher::MotionEntry*
-InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
- ALOG_ASSERT(pointerIds.value != 0);
-
- PointerProperties splitPointerProperties[MAX_POINTERS];
- PointerCoords splitPointerCoords[MAX_POINTERS];
-
- uint32_t originalPointerCount = originalMotionEntry->pointerCount;
- uint32_t splitPointerCount = 0;
-
- for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
- originalPointerIndex++) {
- const PointerProperties& pointerProperties =
- originalMotionEntry->pointerProperties[originalPointerIndex];
- uint32_t pointerId = uint32_t(pointerProperties.id);
- if (pointerIds.hasBit(pointerId)) {
- splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
- splitPointerCoords[splitPointerCount].copyFrom(
- originalMotionEntry->pointerCoords[originalPointerIndex]);
- splitPointerCount += 1;
- }
- }
-
- if (splitPointerCount != pointerIds.count()) {
- // This is bad. We are missing some of the pointers that we expected to deliver.
- // Most likely this indicates that we received an ACTION_MOVE events that has
- // different pointer ids than we expected based on the previous ACTION_DOWN
- // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
- // in this way.
- ALOGW("Dropping split motion event because the pointer count is %d but "
- "we expected there to be %d pointers. This probably means we received "
- "a broken sequence of pointer ids from the input device.",
- splitPointerCount, pointerIds.count());
- return NULL;
- }
-
- int32_t action = originalMotionEntry->action;
- int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
- if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
- || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
- int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
- const PointerProperties& pointerProperties =
- originalMotionEntry->pointerProperties[originalPointerIndex];
- uint32_t pointerId = uint32_t(pointerProperties.id);
- if (pointerIds.hasBit(pointerId)) {
- if (pointerIds.count() == 1) {
- // The first/last pointer went down/up.
- action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
- ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else {
- // A secondary pointer went down/up.
- uint32_t splitPointerIndex = 0;
- while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
- splitPointerIndex += 1;
- }
- action = maskedAction | (splitPointerIndex
- << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- }
- } else {
- // An unrelated pointer changed.
- action = AMOTION_EVENT_ACTION_MOVE;
- }
- }
-
- MotionEntry* splitMotionEntry = new MotionEntry(
- originalMotionEntry->eventTime,
- originalMotionEntry->deviceId,
- originalMotionEntry->source,
- originalMotionEntry->policyFlags,
- action,
- originalMotionEntry->flags,
- originalMotionEntry->metaState,
- originalMotionEntry->buttonState,
- originalMotionEntry->edgeFlags,
- originalMotionEntry->xPrecision,
- originalMotionEntry->yPrecision,
- originalMotionEntry->downTime,
- originalMotionEntry->displayId,
- splitPointerCount, splitPointerProperties, splitPointerCoords);
-
- if (originalMotionEntry->injectionState) {
- splitMotionEntry->injectionState = originalMotionEntry->injectionState;
- splitMotionEntry->injectionState->refCount += 1;
- }
-
- return splitMotionEntry;
-}
-
-void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
-#endif
-
- bool needWake;
- { // acquire lock
- AutoMutex _l(mLock);
-
- ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
- needWake = enqueueInboundEventLocked(newEntry);
- } // release lock
-
- if (needWake) {
- mLooper->wake();
- }
-}
-
-void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
- "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
- args->eventTime, args->deviceId, args->source, args->policyFlags,
- args->action, args->flags, args->keyCode, args->scanCode,
- args->metaState, args->downTime);
-#endif
- if (!validateKeyEvent(args->action)) {
- return;
- }
-
- uint32_t policyFlags = args->policyFlags;
- int32_t flags = args->flags;
- int32_t metaState = args->metaState;
- if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
- policyFlags |= POLICY_FLAG_VIRTUAL;
- flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- }
- if (policyFlags & POLICY_FLAG_ALT) {
- metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
- }
- if (policyFlags & POLICY_FLAG_ALT_GR) {
- metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
- }
- if (policyFlags & POLICY_FLAG_SHIFT) {
- metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
- }
- if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
- metaState |= AMETA_CAPS_LOCK_ON;
- }
- if (policyFlags & POLICY_FLAG_FUNCTION) {
- metaState |= AMETA_FUNCTION_ON;
- }
-
- policyFlags |= POLICY_FLAG_TRUSTED;
-
- KeyEvent event;
- event.initialize(args->deviceId, args->source, args->action,
- flags, args->keyCode, args->scanCode, metaState, 0,
- args->downTime, args->eventTime);
-
- mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
-
- if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- flags |= AKEY_EVENT_FLAG_WOKE_HERE;
- }
-
- bool needWake;
- { // acquire lock
- mLock.lock();
-
- if (shouldSendKeyToInputFilterLocked(args)) {
- mLock.unlock();
-
- policyFlags |= POLICY_FLAG_FILTERED;
- if (!mPolicy->filterInputEvent(&event, policyFlags)) {
- return; // event was consumed by the filter
- }
-
- mLock.lock();
- }
-
- int32_t repeatCount = 0;
- KeyEntry* newEntry = new KeyEntry(args->eventTime,
- args->deviceId, args->source, policyFlags,
- args->action, flags, args->keyCode, args->scanCode,
- metaState, repeatCount, args->downTime);
-
- needWake = enqueueInboundEventLocked(newEntry);
- mLock.unlock();
- } // release lock
-
- if (needWake) {
- mLooper->wake();
- }
-}
-
-bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
- return mInputFilterEnabled;
-}
-
-void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
- "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
- "xPrecision=%f, yPrecision=%f, downTime=%lld",
- args->eventTime, args->deviceId, args->source, args->policyFlags,
- args->action, args->flags, args->metaState, args->buttonState,
- args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
- for (uint32_t i = 0; i < args->pointerCount; i++) {
- ALOGD(" Pointer %d: id=%d, toolType=%d, "
- "x=%f, y=%f, pressure=%f, size=%f, "
- "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
- "orientation=%f",
- i, args->pointerProperties[i].id,
- args->pointerProperties[i].toolType,
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
- args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
- }
-#endif
- if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
- return;
- }
-
- uint32_t policyFlags = args->policyFlags;
- policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
-
- bool needWake;
- { // acquire lock
- mLock.lock();
-
- if (shouldSendMotionToInputFilterLocked(args)) {
- mLock.unlock();
-
- MotionEvent event;
- event.initialize(args->deviceId, args->source, args->action, args->flags,
- args->edgeFlags, args->metaState, args->buttonState, 0, 0,
- args->xPrecision, args->yPrecision,
- args->downTime, args->eventTime,
- args->pointerCount, args->pointerProperties, args->pointerCoords);
-
- policyFlags |= POLICY_FLAG_FILTERED;
- if (!mPolicy->filterInputEvent(&event, policyFlags)) {
- return; // event was consumed by the filter
- }
-
- mLock.lock();
- }
-
- // Just enqueue a new motion event.
- MotionEntry* newEntry = new MotionEntry(args->eventTime,
- args->deviceId, args->source, policyFlags,
- args->action, args->flags, args->metaState, args->buttonState,
- args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
- args->displayId,
- args->pointerCount, args->pointerProperties, args->pointerCoords);
-
- needWake = enqueueInboundEventLocked(newEntry);
- mLock.unlock();
- } // release lock
-
- if (needWake) {
- mLooper->wake();
- }
-}
-
-bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
- // TODO: support sending secondary display events to input filter
- return mInputFilterEnabled && isMainDisplay(args->displayId);
-}
-
-void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchValues=0x%08x, switchMask=0x%08x",
- args->eventTime, args->policyFlags,
- args->switchValues, args->switchMask);
-#endif
-
- uint32_t policyFlags = args->policyFlags;
- policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->notifySwitch(args->eventTime,
- args->switchValues, args->switchMask, policyFlags);
-}
-
-void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
- args->eventTime, args->deviceId);
-#endif
-
- bool needWake;
- { // acquire lock
- AutoMutex _l(mLock);
-
- DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
- needWake = enqueueInboundEventLocked(newEntry);
- } // release lock
-
- if (needWake) {
- mLooper->wake();
- }
-}
-
-int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
- int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
- uint32_t policyFlags) {
-#if DEBUG_INBOUND_EVENT_DETAILS
- ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
- "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
- event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
-#endif
-
- nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
-
- policyFlags |= POLICY_FLAG_INJECTED;
- if (hasInjectionPermission(injectorPid, injectorUid)) {
- policyFlags |= POLICY_FLAG_TRUSTED;
- }
-
- EventEntry* firstInjectedEntry;
- EventEntry* lastInjectedEntry;
- switch (event->getType()) {
- case AINPUT_EVENT_TYPE_KEY: {
- const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
- int32_t action = keyEvent->getAction();
- if (! validateKeyEvent(action)) {
- return INPUT_EVENT_INJECTION_FAILED;
- }
-
- int32_t flags = keyEvent->getFlags();
- if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
- policyFlags |= POLICY_FLAG_VIRTUAL;
- }
-
- if (!(policyFlags & POLICY_FLAG_FILTERED)) {
- mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
- }
-
- if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- flags |= AKEY_EVENT_FLAG_WOKE_HERE;
- }
-
- mLock.lock();
- firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
- keyEvent->getDeviceId(), keyEvent->getSource(),
- policyFlags, action, flags,
- keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
- keyEvent->getRepeatCount(), keyEvent->getDownTime());
- lastInjectedEntry = firstInjectedEntry;
- break;
- }
-
- case AINPUT_EVENT_TYPE_MOTION: {
- const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
- int32_t displayId = ADISPLAY_ID_DEFAULT;
- int32_t action = motionEvent->getAction();
- size_t pointerCount = motionEvent->getPointerCount();
- const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
- if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
- return INPUT_EVENT_INJECTION_FAILED;
- }
-
- if (!(policyFlags & POLICY_FLAG_FILTERED)) {
- nsecs_t eventTime = motionEvent->getEventTime();
- mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
- }
-
- mLock.lock();
- const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
- const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
- firstInjectedEntry = new MotionEntry(*sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
- action, motionEvent->getFlags(),
- motionEvent->getMetaState(), motionEvent->getButtonState(),
- motionEvent->getEdgeFlags(),
- motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), displayId,
- uint32_t(pointerCount), pointerProperties, samplePointerCoords);
- lastInjectedEntry = firstInjectedEntry;
- for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
- sampleEventTimes += 1;
- samplePointerCoords += pointerCount;
- MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
- motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
- action, motionEvent->getFlags(),
- motionEvent->getMetaState(), motionEvent->getButtonState(),
- motionEvent->getEdgeFlags(),
- motionEvent->getXPrecision(), motionEvent->getYPrecision(),
- motionEvent->getDownTime(), displayId,
- uint32_t(pointerCount), pointerProperties, samplePointerCoords);
- lastInjectedEntry->next = nextInjectedEntry;
- lastInjectedEntry = nextInjectedEntry;
- }
- break;
- }
-
- default:
- ALOGW("Cannot inject event of type %d", event->getType());
- return INPUT_EVENT_INJECTION_FAILED;
- }
-
- InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
- if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
- injectionState->injectionIsAsync = true;
- }
-
- injectionState->refCount += 1;
- lastInjectedEntry->injectionState = injectionState;
-
- bool needWake = false;
- for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
- EventEntry* nextEntry = entry->next;
- needWake |= enqueueInboundEventLocked(entry);
- entry = nextEntry;
- }
-
- mLock.unlock();
-
- if (needWake) {
- mLooper->wake();
- }
-
- int32_t injectionResult;
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
- injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
- } else {
- for (;;) {
- injectionResult = injectionState->injectionResult;
- if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
- break;
- }
-
- nsecs_t remainingTimeout = endTime - now();
- if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
- ALOGD("injectInputEvent - Timed out waiting for injection result "
- "to become available.");
-#endif
- injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
- break;
- }
-
- mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
- }
-
- if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
- && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
- while (injectionState->pendingForegroundDispatches != 0) {
-#if DEBUG_INJECTION
- ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
- injectionState->pendingForegroundDispatches);
-#endif
- nsecs_t remainingTimeout = endTime - now();
- if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
- ALOGD("injectInputEvent - Timed out waiting for pending foreground "
- "dispatches to finish.");
-#endif
- injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
- break;
- }
-
- mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
- }
- }
- }
-
- injectionState->release();
- } // release lock
-
-#if DEBUG_INJECTION
- ALOGD("injectInputEvent - Finished with result %d. "
- "injectorPid=%d, injectorUid=%d",
- injectionResult, injectorPid, injectorUid);
-#endif
-
- return injectionResult;
-}
-
-bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
- return injectorUid == 0
- || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
-}
-
-void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
- InjectionState* injectionState = entry->injectionState;
- if (injectionState) {
-#if DEBUG_INJECTION
- ALOGD("Setting input event injection result to %d. "
- "injectorPid=%d, injectorUid=%d",
- injectionResult, injectionState->injectorPid, injectionState->injectorUid);
-#endif
-
- if (injectionState->injectionIsAsync
- && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
- // Log the outcome since the injector did not wait for the injection result.
- switch (injectionResult) {
- case INPUT_EVENT_INJECTION_SUCCEEDED:
- ALOGV("Asynchronous input event injection succeeded.");
- break;
- case INPUT_EVENT_INJECTION_FAILED:
- ALOGW("Asynchronous input event injection failed.");
- break;
- case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
- ALOGW("Asynchronous input event injection permission denied.");
- break;
- case INPUT_EVENT_INJECTION_TIMED_OUT:
- ALOGW("Asynchronous input event injection timed out.");
- break;
- }
- }
-
- injectionState->injectionResult = injectionResult;
- mInjectionResultAvailableCondition.broadcast();
- }
-}
-
-void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
- InjectionState* injectionState = entry->injectionState;
- if (injectionState) {
- injectionState->pendingForegroundDispatches += 1;
- }
-}
-
-void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
- InjectionState* injectionState = entry->injectionState;
- if (injectionState) {
- injectionState->pendingForegroundDispatches -= 1;
-
- if (injectionState->pendingForegroundDispatches == 0) {
- mInjectionSyncFinishedCondition.broadcast();
- }
- }
-}
-
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
- const sp<InputChannel>& inputChannel) const {
- size_t numWindows = mWindowHandles.size();
- for (size_t i = 0; i < numWindows; i++) {
- const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
- if (windowHandle->getInputChannel() == inputChannel) {
- return windowHandle;
- }
- }
- return NULL;
-}
-
-bool InputDispatcher::hasWindowHandleLocked(
- const sp<InputWindowHandle>& windowHandle) const {
- size_t numWindows = mWindowHandles.size();
- for (size_t i = 0; i < numWindows; i++) {
- if (mWindowHandles.itemAt(i) == windowHandle) {
- return true;
- }
- }
- return false;
-}
-
-void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
-#if DEBUG_FOCUS
- ALOGD("setInputWindows");
-#endif
- { // acquire lock
- AutoMutex _l(mLock);
-
- Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
- mWindowHandles = inputWindowHandles;
-
- sp<InputWindowHandle> newFocusedWindowHandle;
- bool foundHoveredWindow = false;
- for (size_t i = 0; i < mWindowHandles.size(); i++) {
- const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
- if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
- mWindowHandles.removeAt(i--);
- continue;
- }
- if (windowHandle->getInfo()->hasFocus) {
- newFocusedWindowHandle = windowHandle;
- }
- if (windowHandle == mLastHoverWindowHandle) {
- foundHoveredWindow = true;
- }
- }
-
- if (!foundHoveredWindow) {
- mLastHoverWindowHandle = NULL;
- }
-
- if (mFocusedWindowHandle != newFocusedWindowHandle) {
- if (mFocusedWindowHandle != NULL) {
-#if DEBUG_FOCUS
- ALOGD("Focus left window: %s",
- mFocusedWindowHandle->getName().string());
-#endif
- sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
- if (focusedInputChannel != NULL) {
- CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
- "focus left window");
- synthesizeCancelationEventsForInputChannelLocked(
- focusedInputChannel, options);
- }
- }
- if (newFocusedWindowHandle != NULL) {
-#if DEBUG_FOCUS
- ALOGD("Focus entered window: %s",
- newFocusedWindowHandle->getName().string());
-#endif
- }
- mFocusedWindowHandle = newFocusedWindowHandle;
- }
-
- for (size_t i = 0; i < mTouchState.windows.size(); i++) {
- TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
- if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
-#if DEBUG_FOCUS
- ALOGD("Touched window was removed: %s",
- touchedWindow.windowHandle->getName().string());
-#endif
- sp<InputChannel> touchedInputChannel =
- touchedWindow.windowHandle->getInputChannel();
- if (touchedInputChannel != NULL) {
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "touched window was removed");
- synthesizeCancelationEventsForInputChannelLocked(
- touchedInputChannel, options);
- }
- mTouchState.windows.removeAt(i--);
- }
- }
-
- // Release information for windows that are no longer present.
- // This ensures that unused input channels are released promptly.
- // Otherwise, they might stick around until the window handle is destroyed
- // which might not happen until the next GC.
- for (size_t i = 0; i < oldWindowHandles.size(); i++) {
- const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
- if (!hasWindowHandleLocked(oldWindowHandle)) {
-#if DEBUG_FOCUS
- ALOGD("Window went away: %s", oldWindowHandle->getName().string());
-#endif
- oldWindowHandle->releaseInfo();
- }
- }
- } // release lock
-
- // Wake up poll loop since it may need to make new input dispatching choices.
- mLooper->wake();
-}
-
-void InputDispatcher::setFocusedApplication(
- const sp<InputApplicationHandle>& inputApplicationHandle) {
-#if DEBUG_FOCUS
- ALOGD("setFocusedApplication");
-#endif
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
- if (mFocusedApplicationHandle != inputApplicationHandle) {
- if (mFocusedApplicationHandle != NULL) {
- resetANRTimeoutsLocked();
- mFocusedApplicationHandle->releaseInfo();
- }
- mFocusedApplicationHandle = inputApplicationHandle;
- }
- } else if (mFocusedApplicationHandle != NULL) {
- resetANRTimeoutsLocked();
- mFocusedApplicationHandle->releaseInfo();
- mFocusedApplicationHandle.clear();
- }
-
-#if DEBUG_FOCUS
- //logDispatchStateLocked();
-#endif
- } // release lock
-
- // Wake up poll loop since it may need to make new input dispatching choices.
- mLooper->wake();
-}
-
-void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
-#if DEBUG_FOCUS
- ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
-#endif
-
- bool changed;
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
- if (mDispatchFrozen && !frozen) {
- resetANRTimeoutsLocked();
- }
-
- if (mDispatchEnabled && !enabled) {
- resetAndDropEverythingLocked("dispatcher is being disabled");
- }
-
- mDispatchEnabled = enabled;
- mDispatchFrozen = frozen;
- changed = true;
- } else {
- changed = false;
- }
-
-#if DEBUG_FOCUS
- //logDispatchStateLocked();
-#endif
- } // release lock
-
- if (changed) {
- // Wake up poll loop since it may need to make new input dispatching choices.
- mLooper->wake();
- }
-}
-
-void InputDispatcher::setInputFilterEnabled(bool enabled) {
-#if DEBUG_FOCUS
- ALOGD("setInputFilterEnabled: enabled=%d", enabled);
-#endif
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mInputFilterEnabled == enabled) {
- return;
- }
-
- mInputFilterEnabled = enabled;
- resetAndDropEverythingLocked("input filter is being enabled or disabled");
- } // release lock
-
- // Wake up poll loop since there might be work to do to drop everything.
- mLooper->wake();
-}
-
-bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
- const sp<InputChannel>& toChannel) {
-#if DEBUG_FOCUS
- ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
- fromChannel->getName().string(), toChannel->getName().string());
-#endif
- { // acquire lock
- AutoMutex _l(mLock);
-
- sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
- sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
- if (fromWindowHandle == NULL || toWindowHandle == NULL) {
-#if DEBUG_FOCUS
- ALOGD("Cannot transfer focus because from or to window not found.");
-#endif
- return false;
- }
- if (fromWindowHandle == toWindowHandle) {
-#if DEBUG_FOCUS
- ALOGD("Trivial transfer to same window.");
-#endif
- return true;
- }
- if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
-#if DEBUG_FOCUS
- ALOGD("Cannot transfer focus because windows are on different displays.");
-#endif
- return false;
- }
-
- bool found = false;
- for (size_t i = 0; i < mTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTouchState.windows[i];
- if (touchedWindow.windowHandle == fromWindowHandle) {
- int32_t oldTargetFlags = touchedWindow.targetFlags;
- BitSet32 pointerIds = touchedWindow.pointerIds;
-
- mTouchState.windows.removeAt(i);
-
- int32_t newTargetFlags = oldTargetFlags
- & (InputTarget::FLAG_FOREGROUND
- | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
- mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
-
- found = true;
- break;
- }
- }
-
- if (! found) {
-#if DEBUG_FOCUS
- ALOGD("Focus transfer failed because from window did not have focus.");
-#endif
- return false;
- }
-
- ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
- ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
- if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
- sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
- sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
-
- fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "transferring touch focus from this window to another window");
- synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
- }
-
-#if DEBUG_FOCUS
- logDispatchStateLocked();
-#endif
- } // release lock
-
- // Wake up poll loop since it may need to make new input dispatching choices.
- mLooper->wake();
- return true;
-}
-
-void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
-#if DEBUG_FOCUS
- ALOGD("Resetting and dropping all events (%s).", reason);
-#endif
-
- CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
- synthesizeCancelationEventsForAllConnectionsLocked(options);
-
- resetKeyRepeatLocked();
- releasePendingEventLocked();
- drainInboundQueueLocked();
- resetANRTimeoutsLocked();
-
- mTouchState.reset();
- mLastHoverWindowHandle.clear();
-}
-
-void InputDispatcher::logDispatchStateLocked() {
- String8 dump;
- dumpDispatchStateLocked(dump);
-
- char* text = dump.lockBuffer(dump.size());
- char* start = text;
- while (*start != '\0') {
- char* end = strchr(start, '\n');
- if (*end == '\n') {
- *(end++) = '\0';
- }
- ALOGD("%s", start);
- start = end;
- }
-}
-
-void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
- dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
- dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
-
- if (mFocusedApplicationHandle != NULL) {
- dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
- mFocusedApplicationHandle->getName().string(),
- mFocusedApplicationHandle->getDispatchingTimeout(
- DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
- } else {
- dump.append(INDENT "FocusedApplication: <null>\n");
- }
- dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
- mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
-
- dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
- dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
- dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
- dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
- dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
- if (!mTouchState.windows.isEmpty()) {
- dump.append(INDENT "TouchedWindows:\n");
- for (size_t i = 0; i < mTouchState.windows.size(); i++) {
- const TouchedWindow& touchedWindow = mTouchState.windows[i];
- dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
- i, touchedWindow.windowHandle->getName().string(),
- touchedWindow.pointerIds.value,
- touchedWindow.targetFlags);
- }
- } else {
- dump.append(INDENT "TouchedWindows: <none>\n");
- }
-
- if (!mWindowHandles.isEmpty()) {
- dump.append(INDENT "Windows:\n");
- for (size_t i = 0; i < mWindowHandles.size(); i++) {
- const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
-
- dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
- "paused=%s, hasFocus=%s, hasWallpaper=%s, "
- "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
- "frame=[%d,%d][%d,%d], scale=%f, "
- "touchableRegion=",
- i, windowInfo->name.string(), windowInfo->displayId,
- toString(windowInfo->paused),
- toString(windowInfo->hasFocus),
- toString(windowInfo->hasWallpaper),
- toString(windowInfo->visible),
- toString(windowInfo->canReceiveKeys),
- windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
- windowInfo->layer,
- windowInfo->frameLeft, windowInfo->frameTop,
- windowInfo->frameRight, windowInfo->frameBottom,
- windowInfo->scaleFactor);
- dumpRegion(dump, windowInfo->touchableRegion);
- dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
- dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
- windowInfo->ownerPid, windowInfo->ownerUid,
- windowInfo->dispatchingTimeout / 1000000.0);
- }
- } else {
- dump.append(INDENT "Windows: <none>\n");
- }
-
- if (!mMonitoringChannels.isEmpty()) {
- dump.append(INDENT "MonitoringChannels:\n");
- for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
- const sp<InputChannel>& channel = mMonitoringChannels[i];
- dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
- }
- } else {
- dump.append(INDENT "MonitoringChannels: <none>\n");
- }
-
- nsecs_t currentTime = now();
-
- if (!mInboundQueue.isEmpty()) {
- dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
- for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
- dump.append(INDENT2);
- entry->appendDescription(dump);
- dump.appendFormat(", age=%0.1fms\n",
- (currentTime - entry->eventTime) * 0.000001f);
- }
- } else {
- dump.append(INDENT "InboundQueue: <empty>\n");
- }
-
- if (!mConnectionsByFd.isEmpty()) {
- dump.append(INDENT "Connections:\n");
- for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
- const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
- dump.appendFormat(INDENT2 "%d: channelName='%s', windowName='%s', "
- "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
- i, connection->getInputChannelName(), connection->getWindowName(),
- connection->getStatusLabel(), toString(connection->monitor),
- toString(connection->inputPublisherBlocked));
-
- if (!connection->outboundQueue.isEmpty()) {
- dump.appendFormat(INDENT3 "OutboundQueue: length=%u\n",
- connection->outboundQueue.count());
- for (DispatchEntry* entry = connection->outboundQueue.head; entry;
- entry = entry->next) {
- dump.append(INDENT4);
- entry->eventEntry->appendDescription(dump);
- dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
- entry->targetFlags, entry->resolvedAction,
- (currentTime - entry->eventEntry->eventTime) * 0.000001f);
- }
- } else {
- dump.append(INDENT3 "OutboundQueue: <empty>\n");
- }
-
- if (!connection->waitQueue.isEmpty()) {
- dump.appendFormat(INDENT3 "WaitQueue: length=%u\n",
- connection->waitQueue.count());
- for (DispatchEntry* entry = connection->waitQueue.head; entry;
- entry = entry->next) {
- dump.append(INDENT4);
- entry->eventEntry->appendDescription(dump);
- dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
- "age=%0.1fms, wait=%0.1fms\n",
- entry->targetFlags, entry->resolvedAction,
- (currentTime - entry->eventEntry->eventTime) * 0.000001f,
- (currentTime - entry->deliveryTime) * 0.000001f);
- }
- } else {
- dump.append(INDENT3 "WaitQueue: <empty>\n");
- }
- }
- } else {
- dump.append(INDENT "Connections: <none>\n");
- }
-
- if (isAppSwitchPendingLocked()) {
- dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
- (mAppSwitchDueTime - now()) / 1000000.0);
- } else {
- dump.append(INDENT "AppSwitch: not pending\n");
- }
-
- dump.append(INDENT "Configuration:\n");
- dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
- mConfig.keyRepeatDelay * 0.000001f);
- dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
- mConfig.keyRepeatTimeout * 0.000001f);
-}
-
-status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
-#if DEBUG_REGISTRATION
- ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
- toString(monitor));
-#endif
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (getConnectionIndexLocked(inputChannel) >= 0) {
- ALOGW("Attempted to register already registered input channel '%s'",
- inputChannel->getName().string());
- return BAD_VALUE;
- }
-
- sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
-
- int fd = inputChannel->getFd();
- mConnectionsByFd.add(fd, connection);
-
- if (monitor) {
- mMonitoringChannels.push(inputChannel);
- }
-
- mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
- } // release lock
-
- // Wake the looper because some connections have changed.
- mLooper->wake();
- return OK;
-}
-
-status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
-#if DEBUG_REGISTRATION
- ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
-#endif
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
- if (status) {
- return status;
- }
- } // release lock
-
- // Wake the poll loop because removing the connection may have changed the current
- // synchronization state.
- mLooper->wake();
- return OK;
-}
-
-status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
- bool notify) {
- ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
- if (connectionIndex < 0) {
- ALOGW("Attempted to unregister already unregistered input channel '%s'",
- inputChannel->getName().string());
- return BAD_VALUE;
- }
-
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- mConnectionsByFd.removeItemsAt(connectionIndex);
-
- if (connection->monitor) {
- removeMonitorChannelLocked(inputChannel);
- }
-
- mLooper->removeFd(inputChannel->getFd());
-
- nsecs_t currentTime = now();
- abortBrokenDispatchCycleLocked(currentTime, connection, notify);
-
- connection->status = Connection::STATUS_ZOMBIE;
- return OK;
-}
-
-void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
- for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
- if (mMonitoringChannels[i] == inputChannel) {
- mMonitoringChannels.removeAt(i);
- break;
- }
- }
-}
-
-ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
- ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
- if (connectionIndex >= 0) {
- sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
- if (connection->inputChannel.get() == inputChannel.get()) {
- return connectionIndex;
- }
- }
-
- return -1;
-}
-
-void InputDispatcher::onDispatchCycleFinishedLocked(
- nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
- commandEntry->connection = connection;
- commandEntry->eventTime = currentTime;
- commandEntry->seq = seq;
- commandEntry->handled = handled;
-}
-
-void InputDispatcher::onDispatchCycleBrokenLocked(
- nsecs_t currentTime, const sp<Connection>& connection) {
- ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
- connection->getInputChannelName());
-
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
- commandEntry->connection = connection;
-}
-
-void InputDispatcher::onANRLocked(
- nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle,
- nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
- float dispatchLatency = (currentTime - eventTime) * 0.000001f;
- float waitDuration = (currentTime - waitStartTime) * 0.000001f;
- ALOGI("Application is not responding: %s. "
- "It has been %0.1fms since event, %0.1fms since wait started. Reason: %s",
- getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
- dispatchLatency, waitDuration, reason);
-
- // Capture a record of the InputDispatcher state at the time of the ANR.
- time_t t = time(NULL);
- struct tm tm;
- localtime_r(&t, &tm);
- char timestr[64];
- strftime(timestr, sizeof(timestr), "%F %T", &tm);
- mLastANRState.clear();
- mLastANRState.append(INDENT "ANR:\n");
- mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
- mLastANRState.appendFormat(INDENT2 "Window: %s\n",
- getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
- mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
- mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
- mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
- dumpDispatchStateLocked(mLastANRState);
-
- CommandEntry* commandEntry = postCommandLocked(
- & InputDispatcher::doNotifyANRLockedInterruptible);
- commandEntry->inputApplicationHandle = applicationHandle;
- commandEntry->inputWindowHandle = windowHandle;
-}
-
-void InputDispatcher::doNotifyConfigurationChangedInterruptible(
- CommandEntry* commandEntry) {
- mLock.unlock();
-
- mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
-
- mLock.lock();
-}
-
-void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
- CommandEntry* commandEntry) {
- sp<Connection> connection = commandEntry->connection;
-
- if (connection->status != Connection::STATUS_ZOMBIE) {
- mLock.unlock();
-
- mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
-
- mLock.lock();
- }
-}
-
-void InputDispatcher::doNotifyANRLockedInterruptible(
- CommandEntry* commandEntry) {
- mLock.unlock();
-
- nsecs_t newTimeout = mPolicy->notifyANR(
- commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
-
- mLock.lock();
-
- resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
- commandEntry->inputWindowHandle != NULL
- ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
-}
-
-void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
- CommandEntry* commandEntry) {
- KeyEntry* entry = commandEntry->keyEntry;
-
- KeyEvent event;
- initializeKeyEvent(&event, entry);
-
- mLock.unlock();
-
- nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
- &event, entry->policyFlags);
-
- mLock.lock();
-
- if (delay < 0) {
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
- } else if (!delay) {
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
- } else {
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
- entry->interceptKeyWakeupTime = now() + delay;
- }
- entry->release();
-}
-
-void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
- CommandEntry* commandEntry) {
- sp<Connection> connection = commandEntry->connection;
- nsecs_t finishTime = commandEntry->eventTime;
- uint32_t seq = commandEntry->seq;
- bool handled = commandEntry->handled;
-
- // Handle post-event policy actions.
- DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
- if (dispatchEntry) {
- nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
- if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
- String8 msg;
- msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
- connection->getWindowName(), eventDuration * 0.000001f);
- dispatchEntry->eventEntry->appendDescription(msg);
- ALOGI("%s", msg.string());
- }
-
- bool restartEvent;
- if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
- KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
- restartEvent = afterKeyEventLockedInterruptible(connection,
- dispatchEntry, keyEntry, handled);
- } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
- MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
- restartEvent = afterMotionEventLockedInterruptible(connection,
- dispatchEntry, motionEntry, handled);
- } else {
- restartEvent = false;
- }
-
- // Dequeue the event and start the next cycle.
- // Note that because the lock might have been released, it is possible that the
- // contents of the wait queue to have been drained, so we need to double-check
- // a few things.
- if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
- connection->waitQueue.dequeue(dispatchEntry);
- traceWaitQueueLengthLocked(connection);
- if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
- connection->outboundQueue.enqueueAtHead(dispatchEntry);
- traceOutboundQueueLengthLocked(connection);
- } else {
- releaseDispatchEntryLocked(dispatchEntry);
- }
- }
-
- // Start the next dispatch cycle for this connection.
- startDispatchCycleLocked(now(), connection);
- }
-}
-
-bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
- DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
- if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
- // Get the fallback key state.
- // Clear it out after dispatching the UP.
- int32_t originalKeyCode = keyEntry->keyCode;
- int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
- if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
- connection->inputState.removeFallbackKey(originalKeyCode);
- }
-
- if (handled || !dispatchEntry->hasForegroundTarget()) {
- // If the application handles the original key for which we previously
- // generated a fallback or if the window is not a foreground window,
- // then cancel the associated fallback key, if any.
- if (fallbackKeyCode != -1) {
- // Dispatch the unhandled key to the policy with the cancel flag.
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
- keyEntry->policyFlags);
-#endif
- KeyEvent event;
- initializeKeyEvent(&event, keyEntry);
- event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
-
- mLock.unlock();
-
- mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
- &event, keyEntry->policyFlags, &event);
-
- mLock.lock();
-
- // Cancel the fallback key.
- if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
- CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
- "application handled the original non-fallback key "
- "or is no longer a foreground target, "
- "canceling previously dispatched fallback key");
- options.keyCode = fallbackKeyCode;
- synthesizeCancelationEventsForConnectionLocked(connection, options);
- }
- connection->inputState.removeFallbackKey(originalKeyCode);
- }
- } else {
- // If the application did not handle a non-fallback key, first check
- // that we are in a good state to perform unhandled key event processing
- // Then ask the policy what to do with it.
- bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
- && keyEntry->repeatCount == 0;
- if (fallbackKeyCode == -1 && !initialDown) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Unhandled key event: Skipping unhandled key event processing "
- "since this is not an initial down. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- originalKeyCode, keyEntry->action, keyEntry->repeatCount,
- keyEntry->policyFlags);
-#endif
- return false;
- }
-
- // Dispatch the unhandled key to the policy.
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Unhandled key event: Asking policy to perform fallback action. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
- keyEntry->policyFlags);
-#endif
- KeyEvent event;
- initializeKeyEvent(&event, keyEntry);
-
- mLock.unlock();
-
- bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
- &event, keyEntry->policyFlags, &event);
-
- mLock.lock();
-
- if (connection->status != Connection::STATUS_NORMAL) {
- connection->inputState.removeFallbackKey(originalKeyCode);
- return false;
- }
-
- // Latch the fallback keycode for this key on an initial down.
- // The fallback keycode cannot change at any other point in the lifecycle.
- if (initialDown) {
- if (fallback) {
- fallbackKeyCode = event.getKeyCode();
- } else {
- fallbackKeyCode = AKEYCODE_UNKNOWN;
- }
- connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
- }
-
- ALOG_ASSERT(fallbackKeyCode != -1);
-
- // Cancel the fallback key if the policy decides not to send it anymore.
- // We will continue to dispatch the key to the policy but we will no
- // longer dispatch a fallback key to the application.
- if (fallbackKeyCode != AKEYCODE_UNKNOWN
- && (!fallback || fallbackKeyCode != event.getKeyCode())) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- if (fallback) {
- ALOGD("Unhandled key event: Policy requested to send key %d"
- "as a fallback for %d, but on the DOWN it had requested "
- "to send %d instead. Fallback canceled.",
- event.getKeyCode(), originalKeyCode, fallbackKeyCode);
- } else {
- ALOGD("Unhandled key event: Policy did not request fallback for %d, "
- "but on the DOWN it had requested to send %d. "
- "Fallback canceled.",
- originalKeyCode, fallbackKeyCode);
- }
-#endif
-
- CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
- "canceling fallback, policy no longer desires it");
- options.keyCode = fallbackKeyCode;
- synthesizeCancelationEventsForConnectionLocked(connection, options);
-
- fallback = false;
- fallbackKeyCode = AKEYCODE_UNKNOWN;
- if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
- connection->inputState.setFallbackKey(originalKeyCode,
- fallbackKeyCode);
- }
- }
-
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- {
- String8 msg;
- const KeyedVector<int32_t, int32_t>& fallbackKeys =
- connection->inputState.getFallbackKeys();
- for (size_t i = 0; i < fallbackKeys.size(); i++) {
- msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
- fallbackKeys.valueAt(i));
- }
- ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
- fallbackKeys.size(), msg.string());
- }
-#endif
-
- if (fallback) {
- // Restart the dispatch cycle using the fallback key.
- keyEntry->eventTime = event.getEventTime();
- keyEntry->deviceId = event.getDeviceId();
- keyEntry->source = event.getSource();
- keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
- keyEntry->keyCode = fallbackKeyCode;
- keyEntry->scanCode = event.getScanCode();
- keyEntry->metaState = event.getMetaState();
- keyEntry->repeatCount = event.getRepeatCount();
- keyEntry->downTime = event.getDownTime();
- keyEntry->syntheticRepeat = false;
-
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Unhandled key event: Dispatching fallback key. "
- "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
- originalKeyCode, fallbackKeyCode, keyEntry->metaState);
-#endif
- return true; // restart the event
- } else {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Unhandled key event: No fallback key.");
-#endif
- }
- }
- }
- return false;
-}
-
-bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
- DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
- return false;
-}
-
-void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
- mLock.unlock();
-
- mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
-
- mLock.lock();
-}
-
-void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
- event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
- entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
- entry->downTime, entry->eventTime);
-}
-
-void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
- int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
- // TODO Write some statistics about how long we spend waiting.
-}
-
-void InputDispatcher::traceInboundQueueLengthLocked() {
-#ifdef HAVE_ANDROID_OS
- if (ATRACE_ENABLED()) {
- ATRACE_INT("iq", mInboundQueue.count());
- }
-#endif
-}
-
-void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
-#ifdef HAVE_ANDROID_OS
- if (ATRACE_ENABLED()) {
- char counterName[40];
- snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName());
- ATRACE_INT(counterName, connection->outboundQueue.count());
- }
-#endif
-}
-
-void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
-#ifdef HAVE_ANDROID_OS
- if (ATRACE_ENABLED()) {
- char counterName[40];
- snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName());
- ATRACE_INT(counterName, connection->waitQueue.count());
- }
-#endif
-}
-
-void InputDispatcher::dump(String8& dump) {
- AutoMutex _l(mLock);
-
- dump.append("Input Dispatcher State:\n");
- dumpDispatchStateLocked(dump);
-
- if (!mLastANRState.isEmpty()) {
- dump.append("\nInput Dispatcher State at time of last ANR:\n");
- dump.append(mLastANRState);
- }
-}
-
-void InputDispatcher::monitor() {
- // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
- mLock.lock();
- mLooper->wake();
- mDispatcherIsAliveCondition.wait(mLock);
- mLock.unlock();
-}
-
-
-// --- InputDispatcher::Queue ---
-
-template <typename T>
-uint32_t InputDispatcher::Queue<T>::count() const {
- uint32_t result = 0;
- for (const T* entry = head; entry; entry = entry->next) {
- result += 1;
- }
- return result;
-}
-
-
-// --- InputDispatcher::InjectionState ---
-
-InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
- refCount(1),
- injectorPid(injectorPid), injectorUid(injectorUid),
- injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
- pendingForegroundDispatches(0) {
-}
-
-InputDispatcher::InjectionState::~InjectionState() {
-}
-
-void InputDispatcher::InjectionState::release() {
- refCount -= 1;
- if (refCount == 0) {
- delete this;
- } else {
- ALOG_ASSERT(refCount > 0);
- }
-}
-
-
-// --- InputDispatcher::EventEntry ---
-
-InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
- refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
- injectionState(NULL), dispatchInProgress(false) {
-}
-
-InputDispatcher::EventEntry::~EventEntry() {
- releaseInjectionState();
-}
-
-void InputDispatcher::EventEntry::release() {
- refCount -= 1;
- if (refCount == 0) {
- delete this;
- } else {
- ALOG_ASSERT(refCount > 0);
- }
-}
-
-void InputDispatcher::EventEntry::releaseInjectionState() {
- if (injectionState) {
- injectionState->release();
- injectionState = NULL;
- }
-}
-
-
-// --- InputDispatcher::ConfigurationChangedEntry ---
-
-InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
- EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
-}
-
-InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
-}
-
-void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
- msg.append("ConfigurationChangedEvent()");
-}
-
-
-// --- InputDispatcher::DeviceResetEntry ---
-
-InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
- EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
- deviceId(deviceId) {
-}
-
-InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
-}
-
-void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
- msg.appendFormat("DeviceResetEvent(deviceId=%d)", deviceId);
-}
-
-
-// --- InputDispatcher::KeyEntry ---
-
-InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime) :
- EventEntry(TYPE_KEY, eventTime, policyFlags),
- deviceId(deviceId), source(source), action(action), flags(flags),
- keyCode(keyCode), scanCode(scanCode), metaState(metaState),
- repeatCount(repeatCount), downTime(downTime),
- syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
- interceptKeyWakeupTime(0) {
-}
-
-InputDispatcher::KeyEntry::~KeyEntry() {
-}
-
-void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
- msg.appendFormat("KeyEvent(action=%d, deviceId=%d, source=0x%08x)",
- action, deviceId, source);
-}
-
-void InputDispatcher::KeyEntry::recycle() {
- releaseInjectionState();
-
- dispatchInProgress = false;
- syntheticRepeat = false;
- interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
- interceptKeyWakeupTime = 0;
-}
-
-
-// --- InputDispatcher::MotionEntry ---
-
-InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, float xPrecision, float yPrecision,
- nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
- EventEntry(TYPE_MOTION, eventTime, policyFlags),
- eventTime(eventTime),
- deviceId(deviceId), source(source), action(action), flags(flags),
- metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
- xPrecision(xPrecision), yPrecision(yPrecision),
- downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
- for (uint32_t i = 0; i < pointerCount; i++) {
- this->pointerProperties[i].copyFrom(pointerProperties[i]);
- this->pointerCoords[i].copyFrom(pointerCoords[i]);
- }
-}
-
-InputDispatcher::MotionEntry::~MotionEntry() {
-}
-
-void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
- msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
- action, deviceId, source, displayId);
-}
-
-
-// --- InputDispatcher::DispatchEntry ---
-
-volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
-
-InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
- seq(nextSeq()),
- eventEntry(eventEntry), targetFlags(targetFlags),
- xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
- deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
- eventEntry->refCount += 1;
-}
-
-InputDispatcher::DispatchEntry::~DispatchEntry() {
- eventEntry->release();
-}
-
-uint32_t InputDispatcher::DispatchEntry::nextSeq() {
- // Sequence number 0 is reserved and will never be returned.
- uint32_t seq;
- do {
- seq = android_atomic_inc(&sNextSeqAtomic);
- } while (!seq);
- return seq;
-}
-
-
-// --- InputDispatcher::InputState ---
-
-InputDispatcher::InputState::InputState() {
-}
-
-InputDispatcher::InputState::~InputState() {
-}
-
-bool InputDispatcher::InputState::isNeutral() const {
- return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
-}
-
-bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
- int32_t displayId) const {
- for (size_t i = 0; i < mMotionMementos.size(); i++) {
- const MotionMemento& memento = mMotionMementos.itemAt(i);
- if (memento.deviceId == deviceId
- && memento.source == source
- && memento.displayId == displayId
- && memento.hovering) {
- return true;
- }
- }
- return false;
-}
-
-bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
- int32_t action, int32_t flags) {
- switch (action) {
- case AKEY_EVENT_ACTION_UP: {
- if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
- for (size_t i = 0; i < mFallbackKeys.size(); ) {
- if (mFallbackKeys.valueAt(i) == entry->keyCode) {
- mFallbackKeys.removeItemsAt(i);
- } else {
- i += 1;
- }
- }
- }
- ssize_t index = findKeyMemento(entry);
- if (index >= 0) {
- mKeyMementos.removeAt(index);
- return true;
- }
- /* FIXME: We can't just drop the key up event because that prevents creating
- * popup windows that are automatically shown when a key is held and then
- * dismissed when the key is released. The problem is that the popup will
- * not have received the original key down, so the key up will be considered
- * to be inconsistent with its observed state. We could perhaps handle this
- * by synthesizing a key down but that will cause other problems.
- *
- * So for now, allow inconsistent key up events to be dispatched.
- *
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
- "keyCode=%d, scanCode=%d",
- entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
-#endif
- return false;
- */
- return true;
- }
-
- case AKEY_EVENT_ACTION_DOWN: {
- ssize_t index = findKeyMemento(entry);
- if (index >= 0) {
- mKeyMementos.removeAt(index);
- }
- addKeyMemento(entry, flags);
- return true;
- }
-
- default:
- return true;
- }
-}
-
-bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
- int32_t action, int32_t flags) {
- int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
- switch (actionMasked) {
- case AMOTION_EVENT_ACTION_UP:
- case AMOTION_EVENT_ACTION_CANCEL: {
- ssize_t index = findMotionMemento(entry, false /*hovering*/);
- if (index >= 0) {
- mMotionMementos.removeAt(index);
- return true;
- }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
- "actionMasked=%d",
- entry->deviceId, entry->source, actionMasked);
-#endif
- return false;
- }
-
- case AMOTION_EVENT_ACTION_DOWN: {
- ssize_t index = findMotionMemento(entry, false /*hovering*/);
- if (index >= 0) {
- mMotionMementos.removeAt(index);
- }
- addMotionMemento(entry, flags, false /*hovering*/);
- return true;
- }
-
- case AMOTION_EVENT_ACTION_POINTER_UP:
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- case AMOTION_EVENT_ACTION_MOVE: {
- ssize_t index = findMotionMemento(entry, false /*hovering*/);
- if (index >= 0) {
- MotionMemento& memento = mMotionMementos.editItemAt(index);
- memento.setPointers(entry);
- return true;
- }
- if (actionMasked == AMOTION_EVENT_ACTION_MOVE
- && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
- | AINPUT_SOURCE_CLASS_NAVIGATION))) {
- // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
- return true;
- }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Dropping inconsistent motion pointer up/down or move event: "
- "deviceId=%d, source=%08x, actionMasked=%d",
- entry->deviceId, entry->source, actionMasked);
-#endif
- return false;
- }
-
- case AMOTION_EVENT_ACTION_HOVER_EXIT: {
- ssize_t index = findMotionMemento(entry, true /*hovering*/);
- if (index >= 0) {
- mMotionMementos.removeAt(index);
- return true;
- }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
- ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
- entry->deviceId, entry->source);
-#endif
- return false;
- }
-
- case AMOTION_EVENT_ACTION_HOVER_ENTER:
- case AMOTION_EVENT_ACTION_HOVER_MOVE: {
- ssize_t index = findMotionMemento(entry, true /*hovering*/);
- if (index >= 0) {
- mMotionMementos.removeAt(index);
- }
- addMotionMemento(entry, flags, true /*hovering*/);
- return true;
- }
-
- default:
- return true;
- }
-}
-
-ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
- for (size_t i = 0; i < mKeyMementos.size(); i++) {
- const KeyMemento& memento = mKeyMementos.itemAt(i);
- if (memento.deviceId == entry->deviceId
- && memento.source == entry->source
- && memento.keyCode == entry->keyCode
- && memento.scanCode == entry->scanCode) {
- return i;
- }
- }
- return -1;
-}
-
-ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
- bool hovering) const {
- for (size_t i = 0; i < mMotionMementos.size(); i++) {
- const MotionMemento& memento = mMotionMementos.itemAt(i);
- if (memento.deviceId == entry->deviceId
- && memento.source == entry->source
- && memento.displayId == entry->displayId
- && memento.hovering == hovering) {
- return i;
- }
- }
- return -1;
-}
-
-void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
- mKeyMementos.push();
- KeyMemento& memento = mKeyMementos.editTop();
- memento.deviceId = entry->deviceId;
- memento.source = entry->source;
- memento.keyCode = entry->keyCode;
- memento.scanCode = entry->scanCode;
- memento.metaState = entry->metaState;
- memento.flags = flags;
- memento.downTime = entry->downTime;
- memento.policyFlags = entry->policyFlags;
-}
-
-void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
- int32_t flags, bool hovering) {
- mMotionMementos.push();
- MotionMemento& memento = mMotionMementos.editTop();
- memento.deviceId = entry->deviceId;
- memento.source = entry->source;
- memento.flags = flags;
- memento.xPrecision = entry->xPrecision;
- memento.yPrecision = entry->yPrecision;
- memento.downTime = entry->downTime;
- memento.displayId = entry->displayId;
- memento.setPointers(entry);
- memento.hovering = hovering;
- memento.policyFlags = entry->policyFlags;
-}
-
-void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
- pointerCount = entry->pointerCount;
- for (uint32_t i = 0; i < entry->pointerCount; i++) {
- pointerProperties[i].copyFrom(entry->pointerProperties[i]);
- pointerCoords[i].copyFrom(entry->pointerCoords[i]);
- }
-}
-
-void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
- Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
- for (size_t i = 0; i < mKeyMementos.size(); i++) {
- const KeyMemento& memento = mKeyMementos.itemAt(i);
- if (shouldCancelKey(memento, options)) {
- outEvents.push(new KeyEntry(currentTime,
- memento.deviceId, memento.source, memento.policyFlags,
- AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
- memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
- }
- }
-
- for (size_t i = 0; i < mMotionMementos.size(); i++) {
- const MotionMemento& memento = mMotionMementos.itemAt(i);
- if (shouldCancelMotion(memento, options)) {
- outEvents.push(new MotionEntry(currentTime,
- memento.deviceId, memento.source, memento.policyFlags,
- memento.hovering
- ? AMOTION_EVENT_ACTION_HOVER_EXIT
- : AMOTION_EVENT_ACTION_CANCEL,
- memento.flags, 0, 0, 0,
- memento.xPrecision, memento.yPrecision, memento.downTime,
- memento.displayId,
- memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
- }
- }
-}
-
-void InputDispatcher::InputState::clear() {
- mKeyMementos.clear();
- mMotionMementos.clear();
- mFallbackKeys.clear();
-}
-
-void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
- for (size_t i = 0; i < mMotionMementos.size(); i++) {
- const MotionMemento& memento = mMotionMementos.itemAt(i);
- if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
- for (size_t j = 0; j < other.mMotionMementos.size(); ) {
- const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
- if (memento.deviceId == otherMemento.deviceId
- && memento.source == otherMemento.source
- && memento.displayId == otherMemento.displayId) {
- other.mMotionMementos.removeAt(j);
- } else {
- j += 1;
- }
- }
- other.mMotionMementos.push(memento);
- }
- }
-}
-
-int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
- ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
- return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
-}
-
-void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
- int32_t fallbackKeyCode) {
- ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
- if (index >= 0) {
- mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
- } else {
- mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
- }
-}
-
-void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
- mFallbackKeys.removeItem(originalKeyCode);
-}
-
-bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
- const CancelationOptions& options) {
- if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
- return false;
- }
-
- if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
- return false;
- }
-
- switch (options.mode) {
- case CancelationOptions::CANCEL_ALL_EVENTS:
- case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
- return true;
- case CancelationOptions::CANCEL_FALLBACK_EVENTS:
- return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
- default:
- return false;
- }
-}
-
-bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
- const CancelationOptions& options) {
- if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
- return false;
- }
-
- switch (options.mode) {
- case CancelationOptions::CANCEL_ALL_EVENTS:
- return true;
- case CancelationOptions::CANCEL_POINTER_EVENTS:
- return memento.source & AINPUT_SOURCE_CLASS_POINTER;
- case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
- return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
- default:
- return false;
- }
-}
-
-
-// --- InputDispatcher::Connection ---
-
-InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
- status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
- monitor(monitor),
- inputPublisher(inputChannel), inputPublisherBlocked(false) {
-}
-
-InputDispatcher::Connection::~Connection() {
-}
-
-const char* InputDispatcher::Connection::getWindowName() const {
- if (inputWindowHandle != NULL) {
- return inputWindowHandle->getName().string();
- }
- if (monitor) {
- return "monitor";
- }
- return "?";
-}
-
-const char* InputDispatcher::Connection::getStatusLabel() const {
- switch (status) {
- case STATUS_NORMAL:
- return "NORMAL";
-
- case STATUS_BROKEN:
- return "BROKEN";
-
- case STATUS_ZOMBIE:
- return "ZOMBIE";
-
- default:
- return "UNKNOWN";
- }
-}
-
-InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
- for (DispatchEntry* entry = waitQueue.head; entry != NULL; entry = entry->next) {
- if (entry->seq == seq) {
- return entry;
- }
- }
- return NULL;
-}
-
-
-// --- InputDispatcher::CommandEntry ---
-
-InputDispatcher::CommandEntry::CommandEntry(Command command) :
- command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0),
- seq(0), handled(false) {
-}
-
-InputDispatcher::CommandEntry::~CommandEntry() {
-}
-
-
-// --- InputDispatcher::TouchState ---
-
-InputDispatcher::TouchState::TouchState() :
- down(false), split(false), deviceId(-1), source(0), displayId(-1) {
-}
-
-InputDispatcher::TouchState::~TouchState() {
-}
-
-void InputDispatcher::TouchState::reset() {
- down = false;
- split = false;
- deviceId = -1;
- source = 0;
- displayId = -1;
- windows.clear();
-}
-
-void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
- down = other.down;
- split = other.split;
- deviceId = other.deviceId;
- source = other.source;
- displayId = other.displayId;
- windows = other.windows;
-}
-
-void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
- int32_t targetFlags, BitSet32 pointerIds) {
- if (targetFlags & InputTarget::FLAG_SPLIT) {
- split = true;
- }
-
- for (size_t i = 0; i < windows.size(); i++) {
- TouchedWindow& touchedWindow = windows.editItemAt(i);
- if (touchedWindow.windowHandle == windowHandle) {
- touchedWindow.targetFlags |= targetFlags;
- if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
- touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
- }
- touchedWindow.pointerIds.value |= pointerIds.value;
- return;
- }
- }
-
- windows.push();
-
- TouchedWindow& touchedWindow = windows.editTop();
- touchedWindow.windowHandle = windowHandle;
- touchedWindow.targetFlags = targetFlags;
- touchedWindow.pointerIds = pointerIds;
-}
-
-void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
- for (size_t i = 0; i < windows.size(); i++) {
- if (windows.itemAt(i).windowHandle == windowHandle) {
- windows.removeAt(i);
- return;
- }
- }
-}
-
-void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
- for (size_t i = 0 ; i < windows.size(); ) {
- TouchedWindow& window = windows.editItemAt(i);
- if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
- | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
- window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
- window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
- i += 1;
- } else {
- windows.removeAt(i);
- }
- }
-}
-
-sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
- for (size_t i = 0; i < windows.size(); i++) {
- const TouchedWindow& window = windows.itemAt(i);
- if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
- return window.windowHandle;
- }
- }
- return NULL;
-}
-
-bool InputDispatcher::TouchState::isSlippery() const {
- // Must have exactly one foreground window.
- bool haveSlipperyForegroundWindow = false;
- for (size_t i = 0; i < windows.size(); i++) {
- const TouchedWindow& window = windows.itemAt(i);
- if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
- if (haveSlipperyForegroundWindow
- || !(window.windowHandle->getInfo()->layoutParamsFlags
- & InputWindowInfo::FLAG_SLIPPERY)) {
- return false;
- }
- haveSlipperyForegroundWindow = true;
- }
- }
- return haveSlipperyForegroundWindow;
-}
-
-
-// --- InputDispatcherThread ---
-
-InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
- Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
-}
-
-InputDispatcherThread::~InputDispatcherThread() {
-}
-
-bool InputDispatcherThread::threadLoop() {
- mDispatcher->dispatchOnce();
- return true;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputDispatcher.h b/widget/gonk/libui/InputDispatcher.h
deleted file mode 100644
index 5453421f6..000000000
--- a/widget/gonk/libui/InputDispatcher.h
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_DISPATCHER_H
-#define _UI_INPUT_DISPATCHER_H
-
-#include "Input.h"
-#include "InputTransport.h"
-#include <utils/KeyedVector.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Looper.h>
-#include <utils/BitSet.h>
-#include <cutils/atomic.h>
-
-#include <stddef.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "InputWindow.h"
-#include "InputApplication.h"
-#include "InputListener.h"
-
-
-namespace android {
-
-/*
- * Constants used to report the outcome of input event injection.
- */
-enum {
- /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
- INPUT_EVENT_INJECTION_PENDING = -1,
-
- /* Injection succeeded. */
- INPUT_EVENT_INJECTION_SUCCEEDED = 0,
-
- /* Injection failed because the injector did not have permission to inject
- * into the application with input focus. */
- INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
-
- /* Injection failed because there were no available input targets. */
- INPUT_EVENT_INJECTION_FAILED = 2,
-
- /* Injection failed due to a timeout. */
- INPUT_EVENT_INJECTION_TIMED_OUT = 3
-};
-
-/*
- * Constants used to determine the input event injection synchronization mode.
- */
-enum {
- /* Injection is asynchronous and is assumed always to be successful. */
- INPUT_EVENT_INJECTION_SYNC_NONE = 0,
-
- /* Waits for previous events to be dispatched so that the input dispatcher can determine
- * whether input event injection willbe permitted based on the current input focus.
- * Does not wait for the input event to finish processing. */
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
-
- /* Waits for the input event to be completely processed. */
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
-};
-
-
-/*
- * An input target specifies how an input event is to be dispatched to a particular window
- * including the window's input channel, control flags, a timeout, and an X / Y offset to
- * be added to input event coordinates to compensate for the absolute position of the
- * window area.
- */
-struct InputTarget {
- enum {
- /* This flag indicates that the event is being delivered to a foreground application. */
- FLAG_FOREGROUND = 1 << 0,
-
- /* This flag indicates that the target of a MotionEvent is partly or wholly
- * obscured by another visible window above it. The motion event should be
- * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
- FLAG_WINDOW_IS_OBSCURED = 1 << 1,
-
- /* This flag indicates that a motion event is being split across multiple windows. */
- FLAG_SPLIT = 1 << 2,
-
- /* This flag indicates that the pointer coordinates dispatched to the application
- * will be zeroed out to avoid revealing information to an application. This is
- * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
- * the same UID from watching all touches. */
- FLAG_ZERO_COORDS = 1 << 3,
-
- /* This flag indicates that the event should be sent as is.
- * Should always be set unless the event is to be transmuted. */
- FLAG_DISPATCH_AS_IS = 1 << 8,
-
- /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
- * of the area of this target and so should instead be delivered as an
- * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
- FLAG_DISPATCH_AS_OUTSIDE = 1 << 9,
-
- /* This flag indicates that a hover sequence is starting in the given window.
- * The event is transmuted into ACTION_HOVER_ENTER. */
- FLAG_DISPATCH_AS_HOVER_ENTER = 1 << 10,
-
- /* This flag indicates that a hover event happened outside of a window which handled
- * previous hover events, signifying the end of the current hover sequence for that
- * window.
- * The event is transmuted into ACTION_HOVER_ENTER. */
- FLAG_DISPATCH_AS_HOVER_EXIT = 1 << 11,
-
- /* This flag indicates that the event should be canceled.
- * It is used to transmute ACTION_MOVE into ACTION_CANCEL when a touch slips
- * outside of a window. */
- FLAG_DISPATCH_AS_SLIPPERY_EXIT = 1 << 12,
-
- /* This flag indicates that the event should be dispatched as an initial down.
- * It is used to transmute ACTION_MOVE into ACTION_DOWN when a touch slips
- * into a new window. */
- FLAG_DISPATCH_AS_SLIPPERY_ENTER = 1 << 13,
-
- /* Mask for all dispatch modes. */
- FLAG_DISPATCH_MASK = FLAG_DISPATCH_AS_IS
- | FLAG_DISPATCH_AS_OUTSIDE
- | FLAG_DISPATCH_AS_HOVER_ENTER
- | FLAG_DISPATCH_AS_HOVER_EXIT
- | FLAG_DISPATCH_AS_SLIPPERY_EXIT
- | FLAG_DISPATCH_AS_SLIPPERY_ENTER,
- };
-
- // The input channel to be targeted.
- sp<InputChannel> inputChannel;
-
- // Flags for the input target.
- int32_t flags;
-
- // The x and y offset to add to a MotionEvent as it is delivered.
- // (ignored for KeyEvents)
- float xOffset, yOffset;
-
- // Scaling factor to apply to MotionEvent as it is delivered.
- // (ignored for KeyEvents)
- float scaleFactor;
-
- // The subset of pointer ids to include in motion events dispatched to this input target
- // if FLAG_SPLIT is set.
- BitSet32 pointerIds;
-};
-
-
-/*
- * Input dispatcher configuration.
- *
- * Specifies various options that modify the behavior of the input dispatcher.
- * The values provided here are merely defaults. The actual values will come from ViewConfiguration
- * and are passed into the dispatcher during initialization.
- */
-struct InputDispatcherConfiguration {
- // The key repeat initial timeout.
- nsecs_t keyRepeatTimeout;
-
- // The key repeat inter-key delay.
- nsecs_t keyRepeatDelay;
-
- InputDispatcherConfiguration() :
- keyRepeatTimeout(500 * 1000000LL),
- keyRepeatDelay(50 * 1000000LL) { }
-};
-
-
-/*
- * Input dispatcher policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI. This interface is also mocked in the unit tests.
- */
-class InputDispatcherPolicyInterface : public virtual RefBase {
-protected:
- InputDispatcherPolicyInterface() { }
- virtual ~InputDispatcherPolicyInterface() { }
-
-public:
- /* Notifies the system that a configuration change has occurred. */
- virtual void notifyConfigurationChanged(nsecs_t when) = 0;
-
- /* Notifies the system that an application is not responding.
- * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
- virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
- const sp<InputWindowHandle>& inputWindowHandle) = 0;
-
- /* Notifies the system that an input channel is unrecoverably broken. */
- virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
-
- /* Gets the input dispatcher configuration. */
- virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
-
- /* Returns true if automatic key repeating is enabled. */
- virtual bool isKeyRepeatEnabled() = 0;
-
- /* Filters an input event.
- * Return true to dispatch the event unmodified, false to consume the event.
- * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
- * to injectInputEvent.
- */
- virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0;
-
- /* Intercepts a key event immediately before queueing it.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing such as updating policy flags.
- *
- * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
- * should be dispatched to applications.
- */
- virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) = 0;
-
- /* Intercepts a touch, trackball or other motion event before queueing it.
- * The policy can use this method as an opportunity to perform power management functions
- * and early event preprocessing such as updating policy flags.
- *
- * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
- * should be dispatched to applications.
- */
- virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
-
- /* Allows the policy a chance to intercept a key before dispatching. */
- virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
- const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
-
- /* Allows the policy a chance to perform default processing for an unhandled key.
- * Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
- virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
- const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
-
- /* Notifies the policy about switch events.
- */
- virtual void notifySwitch(nsecs_t when,
- uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) = 0;
-
- /* Poke user activity for an event dispatched to a window. */
- virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
-
- /* Checks whether a given application pid/uid has permission to inject input events
- * into other applications.
- *
- * This method is special in that its implementation promises to be non-reentrant and
- * is safe to call while holding other locks. (Most other methods make no such guarantees!)
- */
- virtual bool checkInjectEventsPermissionNonReentrant(
- int32_t injectorPid, int32_t injectorUid) = 0;
-};
-
-
-/* Notifies the system about input events generated by the input reader.
- * The dispatcher is expected to be mostly asynchronous. */
-class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
-protected:
- InputDispatcherInterface() { }
- virtual ~InputDispatcherInterface() { }
-
-public:
- /* Dumps the state of the input dispatcher.
- *
- * This method may be called on any thread (usually by the input manager). */
- virtual void dump(String8& dump) = 0;
-
- /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */
- virtual void monitor() = 0;
-
- /* Runs a single iteration of the dispatch loop.
- * Nominally processes one queued event, a timeout, or a response from an input consumer.
- *
- * This method should only be called on the input dispatcher thread.
- */
- virtual void dispatchOnce() = 0;
-
- /* Injects an input event and optionally waits for sync.
- * The synchronization mode determines whether the method blocks while waiting for
- * input injection to proceed.
- * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual int32_t injectInputEvent(const InputEvent* event,
- int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
- uint32_t policyFlags) = 0;
-
- /* Sets the list of input windows.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
-
- /* Sets the focused application.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual void setFocusedApplication(
- const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
-
- /* Sets the input dispatching mode.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
-
- /* Sets whether input event filtering is enabled.
- * When enabled, incoming input events are sent to the policy's filterInputEvent
- * method instead of being dispatched. The filter is expected to use
- * injectInputEvent to inject the events it would like to have dispatched.
- * It should include POLICY_FLAG_FILTERED in the policy flags during injection.
- */
- virtual void setInputFilterEnabled(bool enabled) = 0;
-
- /* Transfers touch focus from the window associated with one channel to the
- * window associated with the other channel.
- *
- * Returns true on success. False if the window did not actually have touch focus.
- */
- virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
- const sp<InputChannel>& toChannel) = 0;
-
- /* Registers or unregister input channels that may be used as targets for input events.
- * If monitor is true, the channel will receive a copy of all input events.
- *
- * These methods may be called on any thread (usually by the input manager).
- */
- virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) = 0;
- virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
-};
-
-/* Dispatches events to input targets. Some functions of the input dispatcher, such as
- * identifying input targets, are controlled by a separate policy object.
- *
- * IMPORTANT INVARIANT:
- * Because the policy can potentially block or cause re-entrance into the input dispatcher,
- * the input dispatcher never calls into the policy while holding its internal locks.
- * The implementation is also carefully designed to recover from scenarios such as an
- * input channel becoming unregistered while identifying input targets or processing timeouts.
- *
- * Methods marked 'Locked' must be called with the lock acquired.
- *
- * Methods marked 'LockedInterruptible' must be called with the lock acquired but
- * may during the course of their execution release the lock, call into the policy, and
- * then reacquire the lock. The caller is responsible for recovering gracefully.
- *
- * A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
- */
-class InputDispatcher : public InputDispatcherInterface {
-protected:
- virtual ~InputDispatcher();
-
-public:
- explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
-
- virtual void dump(String8& dump);
- virtual void monitor();
-
- virtual void dispatchOnce();
-
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
- virtual void notifyKey(const NotifyKeyArgs* args);
- virtual void notifyMotion(const NotifyMotionArgs* args);
- virtual void notifySwitch(const NotifySwitchArgs* args);
- virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
-
- virtual int32_t injectInputEvent(const InputEvent* event,
- int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
- uint32_t policyFlags);
-
- virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
- virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
- virtual void setInputDispatchMode(bool enabled, bool frozen);
- virtual void setInputFilterEnabled(bool enabled);
-
- virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
- const sp<InputChannel>& toChannel);
-
- virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
- virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
-
-private:
- template <typename T>
- struct Link {
- T* next;
- T* prev;
-
- protected:
- inline Link() : next(NULL), prev(NULL) { }
- };
-
- struct InjectionState {
- mutable int32_t refCount;
-
- int32_t injectorPid;
- int32_t injectorUid;
- int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
- bool injectionIsAsync; // set to true if injection is not waiting for the result
- int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
-
- InjectionState(int32_t injectorPid, int32_t injectorUid);
- void release();
-
- private:
- ~InjectionState();
- };
-
- struct EventEntry : Link<EventEntry> {
- enum {
- TYPE_CONFIGURATION_CHANGED,
- TYPE_DEVICE_RESET,
- TYPE_KEY,
- TYPE_MOTION
- };
-
- mutable int32_t refCount;
- int32_t type;
- nsecs_t eventTime;
- uint32_t policyFlags;
- InjectionState* injectionState;
-
- bool dispatchInProgress; // initially false, set to true while dispatching
-
- inline bool isInjected() const { return injectionState != NULL; }
-
- void release();
-
- virtual void appendDescription(String8& msg) const = 0;
-
- protected:
- EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
- virtual ~EventEntry();
- void releaseInjectionState();
- };
-
- struct ConfigurationChangedEntry : EventEntry {
- ConfigurationChangedEntry(nsecs_t eventTime);
- virtual void appendDescription(String8& msg) const;
-
- protected:
- virtual ~ConfigurationChangedEntry();
- };
-
- struct DeviceResetEntry : EventEntry {
- int32_t deviceId;
-
- DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
- virtual void appendDescription(String8& msg) const;
-
- protected:
- virtual ~DeviceResetEntry();
- };
-
- struct KeyEntry : EventEntry {
- int32_t deviceId;
- uint32_t source;
- int32_t action;
- int32_t flags;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- int32_t repeatCount;
- nsecs_t downTime;
-
- bool syntheticRepeat; // set to true for synthetic key repeats
-
- enum InterceptKeyResult {
- INTERCEPT_KEY_RESULT_UNKNOWN,
- INTERCEPT_KEY_RESULT_SKIP,
- INTERCEPT_KEY_RESULT_CONTINUE,
- INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
- };
- InterceptKeyResult interceptKeyResult; // set based on the interception result
- nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
-
- KeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime);
- virtual void appendDescription(String8& msg) const;
- void recycle();
-
- protected:
- virtual ~KeyEntry();
- };
-
- struct MotionEntry : EventEntry {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- int32_t action;
- int32_t flags;
- int32_t metaState;
- int32_t buttonState;
- int32_t edgeFlags;
- float xPrecision;
- float yPrecision;
- nsecs_t downTime;
- int32_t displayId;
- uint32_t pointerCount;
- PointerProperties pointerProperties[MAX_POINTERS];
- PointerCoords pointerCoords[MAX_POINTERS];
-
- MotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags,
- int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- float xPrecision, float yPrecision,
- nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
- virtual void appendDescription(String8& msg) const;
-
- protected:
- virtual ~MotionEntry();
- };
-
- // Tracks the progress of dispatching a particular event to a particular connection.
- struct DispatchEntry : Link<DispatchEntry> {
- const uint32_t seq; // unique sequence number, never 0
-
- EventEntry* eventEntry; // the event to dispatch
- int32_t targetFlags;
- float xOffset;
- float yOffset;
- float scaleFactor;
- nsecs_t deliveryTime; // time when the event was actually delivered
-
- // Set to the resolved action and flags when the event is enqueued.
- int32_t resolvedAction;
- int32_t resolvedFlags;
-
- DispatchEntry(EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
- ~DispatchEntry();
-
- inline bool hasForegroundTarget() const {
- return targetFlags & InputTarget::FLAG_FOREGROUND;
- }
-
- inline bool isSplit() const {
- return targetFlags & InputTarget::FLAG_SPLIT;
- }
-
- private:
- static volatile int32_t sNextSeqAtomic;
-
- static uint32_t nextSeq();
- };
-
- // A command entry captures state and behavior for an action to be performed in the
- // dispatch loop after the initial processing has taken place. It is essentially
- // a kind of continuation used to postpone sensitive policy interactions to a point
- // in the dispatch loop where it is safe to release the lock (generally after finishing
- // the critical parts of the dispatch cycle).
- //
- // The special thing about commands is that they can voluntarily release and reacquire
- // the dispatcher lock at will. Initially when the command starts running, the
- // dispatcher lock is held. However, if the command needs to call into the policy to
- // do some work, it can release the lock, do the work, then reacquire the lock again
- // before returning.
- //
- // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
- // never calls into the policy while holding its lock.
- //
- // Commands are implicitly 'LockedInterruptible'.
- struct CommandEntry;
- typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
-
- class Connection;
- struct CommandEntry : Link<CommandEntry> {
- CommandEntry(Command command);
- ~CommandEntry();
-
- Command command;
-
- // parameters for the command (usage varies by command)
- sp<Connection> connection;
- nsecs_t eventTime;
- KeyEntry* keyEntry;
- sp<InputApplicationHandle> inputApplicationHandle;
- sp<InputWindowHandle> inputWindowHandle;
- int32_t userActivityEventType;
- uint32_t seq;
- bool handled;
- };
-
- // Generic queue implementation.
- template <typename T>
- struct Queue {
- T* head;
- T* tail;
-
- inline Queue() : head(NULL), tail(NULL) {
- }
-
- inline bool isEmpty() const {
- return !head;
- }
-
- inline void enqueueAtTail(T* entry) {
- entry->prev = tail;
- if (tail) {
- tail->next = entry;
- } else {
- head = entry;
- }
- entry->next = NULL;
- tail = entry;
- }
-
- inline void enqueueAtHead(T* entry) {
- entry->next = head;
- if (head) {
- head->prev = entry;
- } else {
- tail = entry;
- }
- entry->prev = NULL;
- head = entry;
- }
-
- inline void dequeue(T* entry) {
- if (entry->prev) {
- entry->prev->next = entry->next;
- } else {
- head = entry->next;
- }
- if (entry->next) {
- entry->next->prev = entry->prev;
- } else {
- tail = entry->prev;
- }
- }
-
- inline T* dequeueAtHead() {
- T* entry = head;
- head = entry->next;
- if (head) {
- head->prev = NULL;
- } else {
- tail = NULL;
- }
- return entry;
- }
-
- uint32_t count() const;
- };
-
- /* Specifies which events are to be canceled and why. */
- struct CancelationOptions {
- enum Mode {
- CANCEL_ALL_EVENTS = 0,
- CANCEL_POINTER_EVENTS = 1,
- CANCEL_NON_POINTER_EVENTS = 2,
- CANCEL_FALLBACK_EVENTS = 3,
- };
-
- // The criterion to use to determine which events should be canceled.
- Mode mode;
-
- // Descriptive reason for the cancelation.
- const char* reason;
-
- // The specific keycode of the key event to cancel, or -1 to cancel any key event.
- int32_t keyCode;
-
- // The specific device id of events to cancel, or -1 to cancel events from any device.
- int32_t deviceId;
-
- CancelationOptions(Mode mode, const char* reason) :
- mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
- };
-
- /* Tracks dispatched key and motion event state so that cancelation events can be
- * synthesized when events are dropped. */
- class InputState {
- public:
- InputState();
- ~InputState();
-
- // Returns true if there is no state to be canceled.
- bool isNeutral() const;
-
- // Returns true if the specified source is known to have received a hover enter
- // motion event.
- bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
-
- // Records tracking information for a key event that has just been published.
- // Returns true if the event should be delivered, false if it is inconsistent
- // and should be skipped.
- bool trackKey(const KeyEntry* entry, int32_t action, int32_t flags);
-
- // Records tracking information for a motion event that has just been published.
- // Returns true if the event should be delivered, false if it is inconsistent
- // and should be skipped.
- bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
-
- // Synthesizes cancelation events for the current state and resets the tracked state.
- void synthesizeCancelationEvents(nsecs_t currentTime,
- Vector<EventEntry*>& outEvents, const CancelationOptions& options);
-
- // Clears the current state.
- void clear();
-
- // Copies pointer-related parts of the input state to another instance.
- void copyPointerStateTo(InputState& other) const;
-
- // Gets the fallback key associated with a keycode.
- // Returns -1 if none.
- // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy.
- int32_t getFallbackKey(int32_t originalKeyCode);
-
- // Sets the fallback key for a particular keycode.
- void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode);
-
- // Removes the fallback key for a particular keycode.
- void removeFallbackKey(int32_t originalKeyCode);
-
- inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const {
- return mFallbackKeys;
- }
-
- private:
- struct KeyMemento {
- int32_t deviceId;
- uint32_t source;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- int32_t flags;
- nsecs_t downTime;
- uint32_t policyFlags;
- };
-
- struct MotionMemento {
- int32_t deviceId;
- uint32_t source;
- int32_t flags;
- float xPrecision;
- float yPrecision;
- nsecs_t downTime;
- int32_t displayId;
- uint32_t pointerCount;
- PointerProperties pointerProperties[MAX_POINTERS];
- PointerCoords pointerCoords[MAX_POINTERS];
- bool hovering;
- uint32_t policyFlags;
-
- void setPointers(const MotionEntry* entry);
- };
-
- Vector<KeyMemento> mKeyMementos;
- Vector<MotionMemento> mMotionMementos;
- KeyedVector<int32_t, int32_t> mFallbackKeys;
-
- ssize_t findKeyMemento(const KeyEntry* entry) const;
- ssize_t findMotionMemento(const MotionEntry* entry, bool hovering) const;
-
- void addKeyMemento(const KeyEntry* entry, int32_t flags);
- void addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering);
-
- static bool shouldCancelKey(const KeyMemento& memento,
- const CancelationOptions& options);
- static bool shouldCancelMotion(const MotionMemento& memento,
- const CancelationOptions& options);
- };
-
- /* Manages the dispatch state associated with a single input channel. */
- class Connection : public RefBase {
- protected:
- virtual ~Connection();
-
- public:
- enum Status {
- // Everything is peachy.
- STATUS_NORMAL,
- // An unrecoverable communication error has occurred.
- STATUS_BROKEN,
- // The input channel has been unregistered.
- STATUS_ZOMBIE
- };
-
- Status status;
- sp<InputChannel> inputChannel; // never null
- sp<InputWindowHandle> inputWindowHandle; // may be null
- bool monitor;
- InputPublisher inputPublisher;
- InputState inputState;
-
- // True if the socket is full and no further events can be published until
- // the application consumes some of the input.
- bool inputPublisherBlocked;
-
- // Queue of events that need to be published to the connection.
- Queue<DispatchEntry> outboundQueue;
-
- // Queue of events that have been published to the connection but that have not
- // yet received a "finished" response from the application.
- Queue<DispatchEntry> waitQueue;
-
- explicit Connection(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
-
- inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
-
- const char* getWindowName() const;
- const char* getStatusLabel() const;
-
- DispatchEntry* findWaitQueueEntry(uint32_t seq);
- };
-
- enum DropReason {
- DROP_REASON_NOT_DROPPED = 0,
- DROP_REASON_POLICY = 1,
- DROP_REASON_APP_SWITCH = 2,
- DROP_REASON_DISABLED = 3,
- DROP_REASON_BLOCKED = 4,
- DROP_REASON_STALE = 5,
- };
-
- sp<InputDispatcherPolicyInterface> mPolicy;
- InputDispatcherConfiguration mConfig;
-
- Mutex mLock;
-
- Condition mDispatcherIsAliveCondition;
-
- sp<Looper> mLooper;
-
- EventEntry* mPendingEvent;
- Queue<EventEntry> mInboundQueue;
- Queue<CommandEntry> mCommandQueue;
-
- void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
-
- // Enqueues an inbound event. Returns true if mLooper->wake() should be called.
- bool enqueueInboundEventLocked(EventEntry* entry);
-
- // Cleans up input state when dropping an inbound event.
- void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
-
- // App switch latency optimization.
- bool mAppSwitchSawKeyDown;
- nsecs_t mAppSwitchDueTime;
-
- static bool isAppSwitchKeyCode(int32_t keyCode);
- bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
- bool isAppSwitchPendingLocked();
- void resetPendingAppSwitchLocked(bool handled);
-
- // Stale event latency optimization.
- static bool isStaleEventLocked(nsecs_t currentTime, EventEntry* entry);
-
- // Blocked event latency optimization. Drops old events when the user intends
- // to transfer focus to a new application.
- EventEntry* mNextUnblockedEvent;
-
- sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
-
- // All registered connections mapped by channel file descriptor.
- KeyedVector<int, sp<Connection> > mConnectionsByFd;
-
- ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel);
-
- // Input channels that will receive a copy of all input events.
- Vector<sp<InputChannel> > mMonitoringChannels;
-
- // Event injection and synchronization.
- Condition mInjectionResultAvailableCondition;
- bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
- void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
-
- Condition mInjectionSyncFinishedCondition;
- void incrementPendingForegroundDispatchesLocked(EventEntry* entry);
- void decrementPendingForegroundDispatchesLocked(EventEntry* entry);
-
- // Key repeat tracking.
- struct KeyRepeatState {
- KeyEntry* lastKeyEntry; // or null if no repeat
- nsecs_t nextRepeatTime;
- } mKeyRepeatState;
-
- void resetKeyRepeatLocked();
- KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
-
- // Deferred command processing.
- bool haveCommandsLocked() const;
- bool runCommandsLockedInterruptible();
- CommandEntry* postCommandLocked(Command command);
-
- // Input filter processing.
- bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
- bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
-
- // Inbound event processing.
- void drainInboundQueueLocked();
- void releasePendingEventLocked();
- void releaseInboundEventLocked(EventEntry* entry);
-
- // Dispatch state.
- bool mDispatchEnabled;
- bool mDispatchFrozen;
- bool mInputFilterEnabled;
-
- Vector<sp<InputWindowHandle> > mWindowHandles;
-
- sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
- bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
-
- // Focus tracking for keys, trackball, etc.
- sp<InputWindowHandle> mFocusedWindowHandle;
-
- // Focus tracking for touch.
- struct TouchedWindow {
- sp<InputWindowHandle> windowHandle;
- int32_t targetFlags;
- BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
- };
- struct TouchState {
- bool down;
- bool split;
- int32_t deviceId; // id of the device that is currently down, others are rejected
- uint32_t source; // source of the device that is current down, others are rejected
- int32_t displayId; // id to the display that currently has a touch, others are rejected
- Vector<TouchedWindow> windows;
-
- TouchState();
- ~TouchState();
- void reset();
- void copyFrom(const TouchState& other);
- void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
- int32_t targetFlags, BitSet32 pointerIds);
- void removeWindow(const sp<InputWindowHandle>& windowHandle);
- void filterNonAsIsTouchWindows();
- sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
- bool isSlippery() const;
- };
-
- TouchState mTouchState;
- TouchState mTempTouchState;
-
- // Focused application.
- sp<InputApplicationHandle> mFocusedApplicationHandle;
-
- // Dispatcher state at time of last ANR.
- String8 mLastANRState;
-
- // Dispatch inbound events.
- bool dispatchConfigurationChangedLocked(
- nsecs_t currentTime, ConfigurationChangedEntry* entry);
- bool dispatchDeviceResetLocked(
- nsecs_t currentTime, DeviceResetEntry* entry);
- bool dispatchKeyLocked(
- nsecs_t currentTime, KeyEntry* entry,
- DropReason* dropReason, nsecs_t* nextWakeupTime);
- bool dispatchMotionLocked(
- nsecs_t currentTime, MotionEntry* entry,
- DropReason* dropReason, nsecs_t* nextWakeupTime);
- void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
- const Vector<InputTarget>& inputTargets);
-
- void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
- void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
-
- // Keeping track of ANR timeouts.
- enum InputTargetWaitCause {
- INPUT_TARGET_WAIT_CAUSE_NONE,
- INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
- INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
- };
-
- InputTargetWaitCause mInputTargetWaitCause;
- nsecs_t mInputTargetWaitStartTime;
- nsecs_t mInputTargetWaitTimeoutTime;
- bool mInputTargetWaitTimeoutExpired;
- sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
-
- // Contains the last window which received a hover event.
- sp<InputWindowHandle> mLastHoverWindowHandle;
-
- // Finding targets for input events.
- int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
- const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle,
- nsecs_t* nextWakeupTime, const char* reason);
- void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
- const sp<InputChannel>& inputChannel);
- nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
- void resetANRTimeoutsLocked();
-
- int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
- Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
- int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
- Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
- bool* outConflictingPointerActions);
-
- void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
- int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
- void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
-
- void pokeUserActivityLocked(const EventEntry* eventEntry);
- bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
- const InjectionState* injectionState);
- bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
- int32_t x, int32_t y) const;
- bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
- const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
- String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle);
-
- // Manage the dispatch cycle for a single connection.
- // These methods are deliberately not Interruptible because doing all of the work
- // with the mutex held makes it easier to ensure that connection invariants are maintained.
- // If needed, the methods post commands to run later once the critical bits are done.
- void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
- EventEntry* eventEntry, const InputTarget* inputTarget);
- void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
- EventEntry* eventEntry, const InputTarget* inputTarget);
- void enqueueDispatchEntryLocked(const sp<Connection>& connection,
- EventEntry* eventEntry, const InputTarget* inputTarget, int32_t dispatchMode);
- void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
- void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
- uint32_t seq, bool handled);
- void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
- bool notify);
- void drainDispatchQueueLocked(Queue<DispatchEntry>* queue);
- void releaseDispatchEntryLocked(DispatchEntry* dispatchEntry);
- static int handleReceiveCallback(int fd, int events, void* data);
-
- void synthesizeCancelationEventsForAllConnectionsLocked(
- const CancelationOptions& options);
- void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
- const CancelationOptions& options);
- void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
- const CancelationOptions& options);
-
- // Splitting motion events across windows.
- MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
-
- // Reset and drop everything the dispatcher is doing.
- void resetAndDropEverythingLocked(const char* reason);
-
- // Dump state.
- void dumpDispatchStateLocked(String8& dump);
- void logDispatchStateLocked();
-
- // Registration.
- void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel);
- status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify);
-
- // Add or remove a connection to the mActiveConnections vector.
- void activateConnectionLocked(Connection* connection);
- void deactivateConnectionLocked(Connection* connection);
-
- // Interesting events that we might like to log or tell the framework about.
- void onDispatchCycleFinishedLocked(
- nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled);
- void onDispatchCycleBrokenLocked(
- nsecs_t currentTime, const sp<Connection>& connection);
- void onANRLocked(
- nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
- const sp<InputWindowHandle>& windowHandle,
- nsecs_t eventTime, nsecs_t waitStartTime, const char* reason);
-
- // Outbound policy interactions.
- void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
- void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
- void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
- void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
- void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry);
- bool afterKeyEventLockedInterruptible(const sp<Connection>& connection,
- DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled);
- bool afterMotionEventLockedInterruptible(const sp<Connection>& connection,
- DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled);
- void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
- void initializeKeyEvent(KeyEvent* event, const KeyEntry* entry);
-
- // Statistics gathering.
- void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
- int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
- void traceInboundQueueLengthLocked();
- void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
- void traceWaitQueueLengthLocked(const sp<Connection>& connection);
-};
-
-/* Enqueues and dispatches input events, endlessly. */
-class InputDispatcherThread : public Thread {
-public:
- explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
- ~InputDispatcherThread();
-
-private:
- virtual bool threadLoop();
-
- sp<InputDispatcherInterface> mDispatcher;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_DISPATCHER_H
diff --git a/widget/gonk/libui/InputListener.cpp b/widget/gonk/libui/InputListener.cpp
deleted file mode 100644
index 3b673f0ad..000000000
--- a/widget/gonk/libui/InputListener.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputListener"
-
-//#define LOG_NDEBUG 0
-
-#include "InputListener.h"
-
-#include "cutils_log.h"
-
-namespace android {
-
-// --- NotifyConfigurationChangedArgs ---
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(nsecs_t eventTime) :
- eventTime(eventTime) {
-}
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
- const NotifyConfigurationChangedArgs& other) :
- eventTime(other.eventTime) {
-}
-
-void NotifyConfigurationChangedArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifyConfigurationChanged(this);
-}
-
-
-// --- NotifyKeyArgs ---
-
-NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags,
- int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
- int32_t metaState, nsecs_t downTime) :
- eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
- action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
- metaState(metaState), downTime(downTime) {
-}
-
-NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
- eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
- policyFlags(other.policyFlags),
- action(other.action), flags(other.flags),
- keyCode(other.keyCode), scanCode(other.scanCode),
- metaState(other.metaState), downTime(other.downTime) {
-}
-
-void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifyKey(this);
-}
-
-
-// --- NotifyMotionArgs ---
-
-NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags,
- int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) :
- eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
- action(action), flags(flags), metaState(metaState), buttonState(buttonState),
- edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
- xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
- for (uint32_t i = 0; i < pointerCount; i++) {
- this->pointerProperties[i].copyFrom(pointerProperties[i]);
- this->pointerCoords[i].copyFrom(pointerCoords[i]);
- }
-}
-
-NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
- eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
- policyFlags(other.policyFlags),
- action(other.action), flags(other.flags),
- metaState(other.metaState), buttonState(other.buttonState),
- edgeFlags(other.edgeFlags), displayId(other.displayId),
- pointerCount(other.pointerCount),
- xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
- for (uint32_t i = 0; i < pointerCount; i++) {
- pointerProperties[i].copyFrom(other.pointerProperties[i]);
- pointerCoords[i].copyFrom(other.pointerCoords[i]);
- }
-}
-
-void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifyMotion(this);
-}
-
-
-// --- NotifySwitchArgs ---
-
-NotifySwitchArgs::NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
- uint32_t switchValues, uint32_t switchMask) :
- eventTime(eventTime), policyFlags(policyFlags),
- switchValues(switchValues), switchMask(switchMask) {
-}
-
-NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
- eventTime(other.eventTime), policyFlags(other.policyFlags),
- switchValues(other.switchValues), switchMask(other.switchMask) {
-}
-
-void NotifySwitchArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifySwitch(this);
-}
-
-
-// --- NotifyDeviceResetArgs ---
-
-NotifyDeviceResetArgs::NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId) :
- eventTime(eventTime), deviceId(deviceId) {
-}
-
-NotifyDeviceResetArgs::NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other) :
- eventTime(other.eventTime), deviceId(other.deviceId) {
-}
-
-void NotifyDeviceResetArgs::notify(const sp<InputListenerInterface>& listener) const {
- listener->notifyDeviceReset(this);
-}
-
-
-// --- QueuedInputListener ---
-
-QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
- mInnerListener(innerListener) {
-}
-
-QueuedInputListener::~QueuedInputListener() {
- size_t count = mArgsQueue.size();
- for (size_t i = 0; i < count; i++) {
- delete mArgsQueue[i];
- }
-}
-
-void QueuedInputListener::notifyConfigurationChanged(
- const NotifyConfigurationChangedArgs* args) {
- mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
-}
-
-void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
- mArgsQueue.push(new NotifyKeyArgs(*args));
-}
-
-void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
- mArgsQueue.push(new NotifyMotionArgs(*args));
-}
-
-void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
- mArgsQueue.push(new NotifySwitchArgs(*args));
-}
-
-void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
- mArgsQueue.push(new NotifyDeviceResetArgs(*args));
-}
-
-void QueuedInputListener::flush() {
- size_t count = mArgsQueue.size();
- for (size_t i = 0; i < count; i++) {
- NotifyArgs* args = mArgsQueue[i];
- args->notify(mInnerListener);
- delete args;
- }
- mArgsQueue.clear();
-}
-
-
-} // namespace android
diff --git a/widget/gonk/libui/InputListener.h b/widget/gonk/libui/InputListener.h
deleted file mode 100644
index de799322f..000000000
--- a/widget/gonk/libui/InputListener.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_LISTENER_H
-#define _UI_INPUT_LISTENER_H
-
-#include "Input.h"
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-class InputListenerInterface;
-
-
-/* Superclass of all input event argument objects */
-struct NotifyArgs {
- virtual ~NotifyArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const = 0;
-};
-
-
-/* Describes a configuration change event. */
-struct NotifyConfigurationChangedArgs : public NotifyArgs {
- nsecs_t eventTime;
-
- inline NotifyConfigurationChangedArgs() { }
-
- NotifyConfigurationChangedArgs(nsecs_t eventTime);
-
- NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
-
- virtual ~NotifyConfigurationChangedArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a key event. */
-struct NotifyKeyArgs : public NotifyArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- nsecs_t downTime;
-
- inline NotifyKeyArgs() { }
-
- NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
- int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
- int32_t metaState, nsecs_t downTime);
-
- NotifyKeyArgs(const NotifyKeyArgs& other);
-
- virtual ~NotifyKeyArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a motion event. */
-struct NotifyMotionArgs : public NotifyArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t metaState;
- int32_t buttonState;
- int32_t edgeFlags;
- int32_t displayId;
- uint32_t pointerCount;
- PointerProperties pointerProperties[MAX_POINTERS];
- PointerCoords pointerCoords[MAX_POINTERS];
- float xPrecision;
- float yPrecision;
- nsecs_t downTime;
-
- inline NotifyMotionArgs() { }
-
- NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
- int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime);
-
- NotifyMotionArgs(const NotifyMotionArgs& other);
-
- virtual ~NotifyMotionArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a switch event. */
-struct NotifySwitchArgs : public NotifyArgs {
- nsecs_t eventTime;
- uint32_t policyFlags;
- uint32_t switchValues;
- uint32_t switchMask;
-
- inline NotifySwitchArgs() { }
-
- NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
- uint32_t switchValues, uint32_t switchMask);
-
- NotifySwitchArgs(const NotifySwitchArgs& other);
-
- virtual ~NotifySwitchArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a device reset event, such as when a device is added,
- * reconfigured, or removed. */
-struct NotifyDeviceResetArgs : public NotifyArgs {
- nsecs_t eventTime;
- int32_t deviceId;
-
- inline NotifyDeviceResetArgs() { }
-
- NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId);
-
- NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other);
-
- virtual ~NotifyDeviceResetArgs() { }
-
- virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/*
- * The interface used by the InputReader to notify the InputListener about input events.
- */
-class InputListenerInterface : public virtual RefBase {
-protected:
- InputListenerInterface() { }
- virtual ~InputListenerInterface() { }
-
-public:
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) = 0;
- virtual void notifyKey(const NotifyKeyArgs* args) = 0;
- virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
- virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
- virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) = 0;
-};
-
-
-/*
- * An implementation of the listener interface that queues up and defers dispatch
- * of decoded events until flushed.
- */
-class QueuedInputListener : public InputListenerInterface {
-protected:
- virtual ~QueuedInputListener();
-
-public:
- QueuedInputListener(const sp<InputListenerInterface>& innerListener);
-
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
- virtual void notifyKey(const NotifyKeyArgs* args);
- virtual void notifyMotion(const NotifyMotionArgs* args);
- virtual void notifySwitch(const NotifySwitchArgs* args);
- virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
-
- void flush();
-
-private:
- sp<InputListenerInterface> mInnerListener;
- Vector<NotifyArgs*> mArgsQueue;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_LISTENER_H
diff --git a/widget/gonk/libui/InputManager.cpp b/widget/gonk/libui/InputManager.cpp
deleted file mode 100644
index 91af056bf..000000000
--- a/widget/gonk/libui/InputManager.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputManager"
-
-//#define LOG_NDEBUG 0
-
-#include "InputManager.h"
-
-#include "cutils_log.h"
-
-namespace android {
-
-InputManager::InputManager(
- const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& readerPolicy,
- const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
- mDispatcher = new InputDispatcher(dispatcherPolicy);
- mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
- initialize();
-}
-
-InputManager::InputManager(
- const sp<InputReaderInterface>& reader,
- const sp<InputDispatcherInterface>& dispatcher) :
- mReader(reader),
- mDispatcher(dispatcher) {
- initialize();
-}
-
-InputManager::~InputManager() {
- stop();
-}
-
-void InputManager::initialize() {
- mReaderThread = new InputReaderThread(mReader);
- mDispatcherThread = new InputDispatcherThread(mDispatcher);
-}
-
-status_t InputManager::start() {
- status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
- if (result) {
- ALOGE("Could not start InputDispatcher thread due to error %d.", result);
- return result;
- }
-
- result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
- if (result) {
- ALOGE("Could not start InputReader thread due to error %d.", result);
-
- mDispatcherThread->requestExit();
- return result;
- }
-
- return OK;
-}
-
-status_t InputManager::stop() {
- status_t result = mReaderThread->requestExitAndWait();
- if (result) {
- ALOGW("Could not stop InputReader thread due to error %d.", result);
- }
-
- result = mDispatcherThread->requestExitAndWait();
- if (result) {
- ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
- }
-
- return OK;
-}
-
-sp<InputReaderInterface> InputManager::getReader() {
- return mReader;
-}
-
-sp<InputDispatcherInterface> InputManager::getDispatcher() {
- return mDispatcher;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputManager.h b/widget/gonk/libui/InputManager.h
deleted file mode 100644
index 15a5176ec..000000000
--- a/widget/gonk/libui/InputManager.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_MANAGER_H
-#define _UI_INPUT_MANAGER_H
-
-/**
- * Native input manager.
- */
-
-#include "EventHub.h"
-#include "InputReader.h"
-#include "InputDispatcher.h"
-
-#include "Input.h"
-#include "InputTransport.h"
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/*
- * The input manager is the core of the system event processing.
- *
- * The input manager uses two threads.
- *
- * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
- * applies policy, and posts messages to a queue managed by the DispatcherThread.
- * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
- * queue and asynchronously dispatches them to applications.
- *
- * By design, the InputReaderThread class and InputDispatcherThread class do not share any
- * internal state. Moreover, all communication is done one way from the InputReaderThread
- * into the InputDispatcherThread and never the reverse. Both classes may interact with the
- * InputDispatchPolicy, however.
- *
- * The InputManager class never makes any calls into Java itself. Instead, the
- * InputDispatchPolicy is responsible for performing all external interactions with the
- * system, including calling DVM services.
- */
-class InputManagerInterface : public virtual RefBase {
-protected:
- InputManagerInterface() { }
- virtual ~InputManagerInterface() { }
-
-public:
- /* Starts the input manager threads. */
- virtual status_t start() = 0;
-
- /* Stops the input manager threads and waits for them to exit. */
- virtual status_t stop() = 0;
-
- /* Gets the input reader. */
- virtual sp<InputReaderInterface> getReader() = 0;
-
- /* Gets the input dispatcher. */
- virtual sp<InputDispatcherInterface> getDispatcher() = 0;
-};
-
-class InputManager : public InputManagerInterface {
-protected:
- virtual ~InputManager();
-
-public:
- InputManager(
- const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& readerPolicy,
- const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
-
- // (used for testing purposes)
- InputManager(
- const sp<InputReaderInterface>& reader,
- const sp<InputDispatcherInterface>& dispatcher);
-
- virtual status_t start();
- virtual status_t stop();
-
- virtual sp<InputReaderInterface> getReader();
- virtual sp<InputDispatcherInterface> getDispatcher();
-
-private:
- sp<InputReaderInterface> mReader;
- sp<InputReaderThread> mReaderThread;
-
- sp<InputDispatcherInterface> mDispatcher;
- sp<InputDispatcherThread> mDispatcherThread;
-
- void initialize();
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_MANAGER_H
diff --git a/widget/gonk/libui/InputReader.cpp b/widget/gonk/libui/InputReader.cpp
deleted file mode 100644
index 3699569aa..000000000
--- a/widget/gonk/libui/InputReader.cpp
+++ /dev/null
@@ -1,6510 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputReader"
-
-//#define LOG_NDEBUG 0
-#include "cutils_log.h"
-
-// Log debug messages for each raw event received from the EventHub.
-#define DEBUG_RAW_EVENTS 0
-
-// Log debug messages about touch screen filtering hacks.
-#define DEBUG_HACKS 0
-
-// Log debug messages about virtual key processing.
-#define DEBUG_VIRTUAL_KEYS 0
-
-// Log debug messages about pointers.
-#define DEBUG_POINTERS 0
-
-// Log debug messages about pointer assignment calculations.
-#define DEBUG_POINTER_ASSIGNMENT 0
-
-// Log debug messages about gesture detection.
-#define DEBUG_GESTURES 0
-
-// Log debug messages about the vibrator.
-#define DEBUG_VIBRATOR 0
-
-#include "InputReader.h"
-
-#include "Keyboard.h"
-#include "VirtualKeyMap.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <math.h>
-
-#define INDENT " "
-#define INDENT2 " "
-#define INDENT3 " "
-#define INDENT4 " "
-#define INDENT5 " "
-
-namespace android {
-
-// --- Constants ---
-
-// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
-static const size_t MAX_SLOTS = 32;
-
-// --- Static Functions ---
-
-template<typename T>
-inline static T abs(const T& value) {
- return value < 0 ? - value : value;
-}
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
- return a < b ? a : b;
-}
-
-template<typename T>
-inline static void swap(T& a, T& b) {
- T temp = a;
- a = b;
- b = temp;
-}
-
-inline static float avg(float x, float y) {
- return (x + y) / 2;
-}
-
-inline static float distance(float x1, float y1, float x2, float y2) {
- return hypotf(x1 - x2, y1 - y2);
-}
-
-inline static int32_t signExtendNybble(int32_t value) {
- return value >= 8 ? value - 16 : value;
-}
-
-static inline const char* toString(bool value) {
- return value ? "true" : "false";
-}
-
-static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
- const int32_t map[][4], size_t mapSize) {
- if (orientation != DISPLAY_ORIENTATION_0) {
- for (size_t i = 0; i < mapSize; i++) {
- if (value == map[i][0]) {
- return map[i][orientation];
- }
- }
- }
- return value;
-}
-
-static const int32_t keyCodeRotationMap[][4] = {
- // key codes enumerated counter-clockwise with the original (unrotated) key first
- // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation
- { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT },
- { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN },
- { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT },
- { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP },
-};
-static const size_t keyCodeRotationMapSize =
- sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
-
-static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
- return rotateValueUsingRotationMap(keyCode, orientation,
- keyCodeRotationMap, keyCodeRotationMapSize);
-}
-
-static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
- float temp;
- switch (orientation) {
- case DISPLAY_ORIENTATION_90:
- temp = *deltaX;
- *deltaX = *deltaY;
- *deltaY = -temp;
- break;
-
- case DISPLAY_ORIENTATION_180:
- *deltaX = -*deltaX;
- *deltaY = -*deltaY;
- break;
-
- case DISPLAY_ORIENTATION_270:
- temp = *deltaX;
- *deltaX = -*deltaY;
- *deltaY = temp;
- break;
- }
-}
-
-static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
- return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
-}
-
-// Returns true if the pointer should be reported as being down given the specified
-// button states. This determines whether the event is reported as a touch event.
-static bool isPointerDown(int32_t buttonState) {
- return buttonState &
- (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
- | AMOTION_EVENT_BUTTON_TERTIARY);
-}
-
-static float calculateCommonVector(float a, float b) {
- if (a > 0 && b > 0) {
- return a < b ? a : b;
- } else if (a < 0 && b < 0) {
- return a > b ? a : b;
- } else {
- return 0;
- }
-}
-
-static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
- nsecs_t when, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
- int32_t buttonState, int32_t keyCode) {
- if (
- (action == AKEY_EVENT_ACTION_DOWN
- && !(lastButtonState & buttonState)
- && (currentButtonState & buttonState))
- || (action == AKEY_EVENT_ACTION_UP
- && (lastButtonState & buttonState)
- && !(currentButtonState & buttonState))) {
- NotifyKeyArgs args(when, deviceId, source, policyFlags,
- action, 0, keyCode, 0, context->getGlobalMetaState(), when);
- context->getListener()->notifyKey(&args);
- }
-}
-
-static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
- nsecs_t when, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
- synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
- lastButtonState, currentButtonState,
- AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
- synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
- lastButtonState, currentButtonState,
- AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
-}
-
-
-// --- InputReaderConfiguration ---
-
-bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
- const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
- if (viewport.displayId >= 0) {
- *outViewport = viewport;
- return true;
- }
- return false;
-}
-
-void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
- DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
- v = viewport;
-}
-
-
-// --- InputReader ---
-
-InputReader::InputReader(const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& policy,
- const sp<InputListenerInterface>& listener) :
- mContext(this), mEventHub(eventHub), mPolicy(policy),
- mGlobalMetaState(0), mGeneration(1),
- mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
- mConfigurationChangesToRefresh(0) {
- mQueuedListener = new QueuedInputListener(listener);
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- refreshConfigurationLocked(0);
- updateGlobalMetaStateLocked();
- } // release lock
-}
-
-InputReader::~InputReader() {
- for (size_t i = 0; i < mDevices.size(); i++) {
- delete mDevices.valueAt(i);
- }
-}
-
-void InputReader::loopOnce() {
- int32_t oldGeneration;
- int32_t timeoutMillis;
- bool inputDevicesChanged = false;
- Vector<InputDeviceInfo> inputDevices;
- { // acquire lock
- AutoMutex _l(mLock);
-
- oldGeneration = mGeneration;
- timeoutMillis = -1;
-
- uint32_t changes = mConfigurationChangesToRefresh;
- if (changes) {
- mConfigurationChangesToRefresh = 0;
- timeoutMillis = 0;
- refreshConfigurationLocked(changes);
- } else if (mNextTimeout != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
- }
- } // release lock
-
- size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
-
- { // acquire lock
- AutoMutex _l(mLock);
- mReaderIsAliveCondition.broadcast();
-
- if (count) {
- processEventsLocked(mEventBuffer, count);
- }
-
- if (mNextTimeout != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- if (now >= mNextTimeout) {
-#if DEBUG_RAW_EVENTS
- ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
-#endif
- mNextTimeout = LLONG_MAX;
- timeoutExpiredLocked(now);
- }
- }
-
- if (oldGeneration != mGeneration) {
- inputDevicesChanged = true;
- getInputDevicesLocked(inputDevices);
- }
- } // release lock
-
- // Send out a message that the describes the changed input devices.
- if (inputDevicesChanged) {
- mPolicy->notifyInputDevicesChanged(inputDevices);
- }
-
- // Flush queued events out to the listener.
- // This must happen outside of the lock because the listener could potentially call
- // back into the InputReader's methods, such as getScanCodeState, or become blocked
- // on another thread similarly waiting to acquire the InputReader lock thereby
- // resulting in a deadlock. This situation is actually quite plausible because the
- // listener is actually the input dispatcher, which calls into the window manager,
- // which occasionally calls into the input reader.
- mQueuedListener->flush();
-}
-
-void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
- for (const RawEvent* rawEvent = rawEvents; count;) {
- int32_t type = rawEvent->type;
- size_t batchSize = 1;
- if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
- int32_t deviceId = rawEvent->deviceId;
- while (batchSize < count) {
- if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
- || rawEvent[batchSize].deviceId != deviceId) {
- break;
- }
- batchSize += 1;
- }
-#if DEBUG_RAW_EVENTS
- ALOGD("BatchSize: %d Count: %d", batchSize, count);
-#endif
- processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
- } else {
- switch (rawEvent->type) {
- case EventHubInterface::DEVICE_ADDED:
- addDeviceLocked(rawEvent->when, rawEvent->deviceId);
- break;
- case EventHubInterface::DEVICE_REMOVED:
- removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
- break;
- case EventHubInterface::FINISHED_DEVICE_SCAN:
- handleConfigurationChangedLocked(rawEvent->when);
- break;
- default:
- ALOG_ASSERT(false); // can't happen
- break;
- }
- }
- count -= batchSize;
- rawEvent += batchSize;
- }
-}
-
-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;
- }
-
- InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
- uint32_t classes = mEventHub->getDeviceClasses(deviceId);
-
- InputDevice* device = createDeviceLocked(deviceId, identifier, classes);
- 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());
- }
-
- mDevices.add(deviceId, device);
- bumpGenerationLocked();
-}
-
-void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
- InputDevice* device = NULL;
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
- return;
- }
-
- device = mDevices.valueAt(deviceIndex);
- mDevices.removeItemsAt(deviceIndex, 1);
- bumpGenerationLocked();
-
- if (device->isIgnored()) {
- ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
- device->getId(), device->getName().string());
- } else {
- ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
- device->getId(), device->getName().string(), device->getSources());
- }
-
- device->reset(when);
- delete device;
-}
-
-InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
- const InputDeviceIdentifier& identifier, uint32_t classes) {
- InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
- identifier, classes);
-
- // External devices.
- if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
- device->setExternal(true);
- }
-
- // Switch-like devices.
- if (classes & INPUT_DEVICE_CLASS_SWITCH) {
- device->addMapper(new SwitchInputMapper(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));
- }
-
- return device;
-}
-
-void InputReader::processEventsForDeviceLocked(int32_t deviceId,
- const RawEvent* rawEvents, size_t count) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- ALOGW("Discarding event for unknown deviceId %d.", deviceId);
- return;
- }
-
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
- return;
- }
-
- device->process(rawEvents, count);
-}
-
-void InputReader::timeoutExpiredLocked(nsecs_t when) {
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (!device->isIgnored()) {
- device->timeoutExpired(when);
- }
- }
-}
-
-void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
- // Reset global meta state because it depends on the list of all configured devices.
- updateGlobalMetaStateLocked();
-
- // Enqueue configuration changed.
- NotifyConfigurationChangedArgs args(when);
- mQueuedListener->notifyConfigurationChanged(&args);
-}
-
-void InputReader::refreshConfigurationLocked(uint32_t changes) {
- mPolicy->getReaderConfiguration(&mConfig);
- mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
-
- if (changes) {
- ALOGI("Reconfiguring input devices. changes=0x%08x", changes);
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
- if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
- mEventHub->requestReopenDevices();
- } else {
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->configure(now, &mConfig, changes);
- }
- }
- }
-}
-
-void InputReader::updateGlobalMetaStateLocked() {
- mGlobalMetaState = 0;
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- mGlobalMetaState |= device->getMetaState();
- }
-}
-
-int32_t InputReader::getGlobalMetaStateLocked() {
- return mGlobalMetaState;
-}
-
-void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
- mDisableVirtualKeysTimeout = time;
-}
-
-bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
- InputDevice* device, int32_t keyCode, int32_t scanCode) {
- if (now < mDisableVirtualKeysTimeout) {
- ALOGI("Dropping virtual key from device %s because virtual keys are "
- "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
- device->getName().string(),
- (mDisableVirtualKeysTimeout - now) * 0.000001,
- keyCode, scanCode);
- return true;
- } else {
- return false;
- }
-}
-
-void InputReader::fadePointerLocked() {
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->fadePointer();
- }
-}
-
-void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
- if (when < mNextTimeout) {
- mNextTimeout = when;
- mEventHub->wake();
- }
-}
-
-int32_t InputReader::bumpGenerationLocked() {
- return ++mGeneration;
-}
-
-void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
- AutoMutex _l(mLock);
- getInputDevicesLocked(outInputDevices);
-}
-
-void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
- outInputDevices.clear();
-
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (!device->isIgnored()) {
- outInputDevices.push();
- device->getDeviceInfo(&outInputDevices.editTop());
- }
- }
-}
-
-int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t keyCode) {
- AutoMutex _l(mLock);
-
- return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
-}
-
-int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t scanCode) {
- AutoMutex _l(mLock);
-
- return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
-}
-
-int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
- AutoMutex _l(mLock);
-
- return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
-}
-
-int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
- GetStateFunc getStateFunc) {
- int32_t result = AKEY_STATE_UNKNOWN;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- }
- }
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
- // value. Otherwise, return AKEY_STATE_UP as long as one device reports it.
- int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
- if (currentResult >= AKEY_STATE_DOWN) {
- return currentResult;
- } else if (currentResult == AKEY_STATE_UP) {
- result = currentResult;
- }
- }
- }
- }
- return result;
-}
-
-bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
- size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
- AutoMutex _l(mLock);
-
- memset(outFlags, 0, numCodes);
- return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
-}
-
-bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
- size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
- bool result = false;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
- }
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result |= device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
- }
- }
- return result;
-}
-
-void InputReader::requestRefreshConfiguration(uint32_t changes) {
- AutoMutex _l(mLock);
-
- if (changes) {
- bool needWake = !mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh |= changes;
-
- if (needWake) {
- mEventHub->wake();
- }
- }
-}
-
-void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
- ssize_t repeat, int32_t token) {
- AutoMutex _l(mLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- device->vibrate(pattern, patternSize, repeat, token);
- }
-}
-
-void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
- AutoMutex _l(mLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- device->cancelVibrate(token);
- }
-}
-
-void InputReader::dump(String8& dump) {
- AutoMutex _l(mLock);
-
- mEventHub->dump(dump);
- dump.append("\n");
-
- dump.append("Input Reader State:\n");
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- mDevices.valueAt(i)->dump(dump);
- }
-
- dump.append(INDENT "Configuration:\n");
- dump.append(INDENT2 "ExcludedDeviceNames: [");
- for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
- if (i != 0) {
- dump.append(", ");
- }
- dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
- }
- dump.append("]\n");
- dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
- mConfig.virtualKeyQuietTime * 0.000001f);
-
- dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
- "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
- mConfig.pointerVelocityControlParameters.scale,
- mConfig.pointerVelocityControlParameters.lowThreshold,
- mConfig.pointerVelocityControlParameters.highThreshold,
- mConfig.pointerVelocityControlParameters.acceleration);
-
- dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
- "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
- mConfig.wheelVelocityControlParameters.scale,
- mConfig.wheelVelocityControlParameters.lowThreshold,
- mConfig.wheelVelocityControlParameters.highThreshold,
- mConfig.wheelVelocityControlParameters.acceleration);
-
- dump.appendFormat(INDENT2 "PointerGesture:\n");
- dump.appendFormat(INDENT3 "Enabled: %s\n",
- toString(mConfig.pointerGesturesEnabled));
- dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
- mConfig.pointerGestureQuietInterval * 0.000001f);
- dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
- mConfig.pointerGestureDragMinSwitchSpeed);
- dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
- mConfig.pointerGestureTapInterval * 0.000001f);
- dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
- mConfig.pointerGestureTapDragInterval * 0.000001f);
- dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
- mConfig.pointerGestureTapSlop);
- dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
- mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
- dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
- mConfig.pointerGestureMultitouchMinDistance);
- dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
- mConfig.pointerGestureSwipeTransitionAngleCosine);
- dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
- mConfig.pointerGestureSwipeMaxWidthRatio);
- dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
- mConfig.pointerGestureMovementSpeedRatio);
- dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
- mConfig.pointerGestureZoomSpeedRatio);
-}
-
-void InputReader::monitor() {
- // Acquire and release the lock to ensure that the reader has not deadlocked.
- mLock.lock();
- mEventHub->wake();
- mReaderIsAliveCondition.wait(mLock);
- mLock.unlock();
-
- // Check the EventHub
- mEventHub->monitor();
-}
-
-
-// --- InputReader::ContextImpl ---
-
-InputReader::ContextImpl::ContextImpl(InputReader* reader) :
- mReader(reader) {
-}
-
-void InputReader::ContextImpl::updateGlobalMetaState() {
- // lock is already held by the input loop
- mReader->updateGlobalMetaStateLocked();
-}
-
-int32_t InputReader::ContextImpl::getGlobalMetaState() {
- // lock is already held by the input loop
- return mReader->getGlobalMetaStateLocked();
-}
-
-void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
- // lock is already held by the input loop
- mReader->disableVirtualKeysUntilLocked(time);
-}
-
-bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
- InputDevice* device, int32_t keyCode, int32_t scanCode) {
- // lock is already held by the input loop
- return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
-}
-
-void InputReader::ContextImpl::fadePointer() {
- // lock is already held by the input loop
- mReader->fadePointerLocked();
-}
-
-void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
- // lock is already held by the input loop
- mReader->requestTimeoutAtTimeLocked(when);
-}
-
-int32_t InputReader::ContextImpl::bumpGeneration() {
- // lock is already held by the input loop
- return mReader->bumpGenerationLocked();
-}
-
-InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
- return mReader->mPolicy.get();
-}
-
-InputListenerInterface* InputReader::ContextImpl::getListener() {
- return mReader->mQueuedListener.get();
-}
-
-EventHubInterface* InputReader::ContextImpl::getEventHub() {
- return mReader->mEventHub.get();
-}
-
-
-// --- InputReaderThread ---
-
-InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
- Thread(/*canCallJava*/ true), mReader(reader) {
-}
-
-InputReaderThread::~InputReaderThread() {
-}
-
-bool InputReaderThread::threadLoop() {
- mReader->loopOnce();
- return true;
-}
-
-
-// --- InputDevice ---
-
-InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- const InputDeviceIdentifier& identifier, uint32_t classes) :
- mContext(context), mId(id), mGeneration(generation),
- mIdentifier(identifier), mClasses(classes),
- mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
-}
-
-InputDevice::~InputDevice() {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- delete mMappers[i];
- }
- mMappers.clear();
-}
-
-void InputDevice::dump(String8& dump) {
- InputDeviceInfo deviceInfo;
- getDeviceInfo(& deviceInfo);
-
- dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
- deviceInfo.getDisplayName().string());
- dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
- dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
- dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
- dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
-
- const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
- if (!ranges.isEmpty()) {
- dump.append(INDENT2 "Motion Ranges:\n");
- for (size_t i = 0; i < ranges.size(); i++) {
- const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
- const char* label = getAxisLabel(range.axis);
- char name[32];
- if (label) {
- strncpy(name, label, sizeof(name));
- name[sizeof(name) - 1] = '\0';
- } else {
- snprintf(name, sizeof(name), "%d", range.axis);
- }
- dump.appendFormat(INDENT3 "%s: source=0x%08x, "
- "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
- name, range.source, range.min, range.max, range.flat, range.fuzz,
- range.resolution);
- }
- }
-
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->dump(dump);
- }
-}
-
-void InputDevice::addMapper(InputMapper* mapper) {
- mMappers.add(mapper);
-}
-
-void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
- mSources = 0;
-
- if (!isIgnored()) {
- if (!changes) { // first time only
- mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
- if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
- sp<KeyCharacterMap> keyboardLayout =
- mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
- if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
- bumpGeneration();
- }
- }
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
- if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
- String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
- if (mAlias != alias) {
- mAlias = alias;
- bumpGeneration();
- }
- }
- }
-
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->configure(when, config, changes);
- mSources |= mapper->getSources();
- }
- }
-}
-
-void InputDevice::reset(nsecs_t when) {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->reset(when);
- }
-
- mContext->updateGlobalMetaState();
-
- notifyReset(when);
-}
-
-void InputDevice::process(const RawEvent* rawEvents, size_t count) {
- // Process all of the events in order for each mapper.
- // We cannot simply ask each mapper to process them in bulk because mappers may
- // have side-effects that must be interleaved. For example, joystick movement events and
- // gamepad button presses are handled by different mappers but they should be dispatched
- // in the order received.
- size_t numMappers = mMappers.size();
- for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
-#if DEBUG_RAW_EVENTS
- ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
- rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
- rawEvent->when);
-#endif
-
- if (mDropUntilNextSync) {
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
- mDropUntilNextSync = false;
-#if DEBUG_RAW_EVENTS
- ALOGD("Recovered from input event buffer overrun.");
-#endif
- } else {
-#if DEBUG_RAW_EVENTS
- ALOGD("Dropped input event while waiting for next input sync.");
-#endif
- }
- } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
- ALOGI("Detected input event buffer overrun for device %s.", getName().string());
- mDropUntilNextSync = true;
- reset(rawEvent->when);
- } else {
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->process(rawEvent);
- }
- }
- }
-}
-
-void InputDevice::timeoutExpired(nsecs_t when) {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->timeoutExpired(when);
- }
-}
-
-void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
- outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal);
-
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->populateDeviceInfo(outDeviceInfo);
- }
-}
-
-int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
-}
-
-int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
-}
-
-int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
- return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
-}
-
-int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
- int32_t result = AKEY_STATE_UNKNOWN;
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
- // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
- // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
- int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
- if (currentResult >= AKEY_STATE_DOWN) {
- return currentResult;
- } else if (currentResult == AKEY_STATE_UP) {
- result = currentResult;
- }
- }
- }
- return result;
-}
-
-bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- bool result = false;
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
- result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
- }
- }
- return result;
-}
-
-void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token) {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->vibrate(pattern, patternSize, repeat, token);
- }
-}
-
-void InputDevice::cancelVibrate(int32_t token) {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->cancelVibrate(token);
- }
-}
-
-int32_t InputDevice::getMetaState() {
- int32_t result = 0;
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- result |= mapper->getMetaState();
- }
- return result;
-}
-
-void InputDevice::fadePointer() {
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->fadePointer();
- }
-}
-
-void InputDevice::bumpGeneration() {
- mGeneration = mContext->bumpGeneration();
-}
-
-void InputDevice::notifyReset(nsecs_t when) {
- NotifyDeviceResetArgs args(when, mId);
- mContext->getListener()->notifyDeviceReset(&args);
-}
-
-
-// --- CursorButtonAccumulator ---
-
-CursorButtonAccumulator::CursorButtonAccumulator() {
- clearButtons();
-}
-
-void CursorButtonAccumulator::reset(InputDevice* device) {
- mBtnLeft = device->isKeyPressed(BTN_LEFT);
- mBtnRight = device->isKeyPressed(BTN_RIGHT);
- mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
- mBtnBack = device->isKeyPressed(BTN_BACK);
- mBtnSide = device->isKeyPressed(BTN_SIDE);
- mBtnForward = device->isKeyPressed(BTN_FORWARD);
- mBtnExtra = device->isKeyPressed(BTN_EXTRA);
- mBtnTask = device->isKeyPressed(BTN_TASK);
-}
-
-void CursorButtonAccumulator::clearButtons() {
- mBtnLeft = 0;
- mBtnRight = 0;
- mBtnMiddle = 0;
- mBtnBack = 0;
- mBtnSide = 0;
- mBtnForward = 0;
- mBtnExtra = 0;
- mBtnTask = 0;
-}
-
-void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_KEY) {
- switch (rawEvent->code) {
- case BTN_LEFT:
- mBtnLeft = rawEvent->value;
- break;
- case BTN_RIGHT:
- mBtnRight = rawEvent->value;
- break;
- case BTN_MIDDLE:
- mBtnMiddle = rawEvent->value;
- break;
- case BTN_BACK:
- mBtnBack = rawEvent->value;
- break;
- case BTN_SIDE:
- mBtnSide = rawEvent->value;
- break;
- case BTN_FORWARD:
- mBtnForward = rawEvent->value;
- break;
- case BTN_EXTRA:
- mBtnExtra = rawEvent->value;
- break;
- case BTN_TASK:
- mBtnTask = rawEvent->value;
- break;
- }
- }
-}
-
-uint32_t CursorButtonAccumulator::getButtonState() const {
- uint32_t result = 0;
- if (mBtnLeft) {
- result |= AMOTION_EVENT_BUTTON_PRIMARY;
- }
- if (mBtnRight) {
- result |= AMOTION_EVENT_BUTTON_SECONDARY;
- }
- if (mBtnMiddle) {
- result |= AMOTION_EVENT_BUTTON_TERTIARY;
- }
- if (mBtnBack || mBtnSide) {
- result |= AMOTION_EVENT_BUTTON_BACK;
- }
- if (mBtnForward || mBtnExtra) {
- result |= AMOTION_EVENT_BUTTON_FORWARD;
- }
- return result;
-}
-
-
-// --- CursorMotionAccumulator ---
-
-CursorMotionAccumulator::CursorMotionAccumulator() {
- clearRelativeAxes();
-}
-
-void CursorMotionAccumulator::reset(InputDevice* device) {
- clearRelativeAxes();
-}
-
-void CursorMotionAccumulator::clearRelativeAxes() {
- mRelX = 0;
- mRelY = 0;
-}
-
-void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_REL) {
- switch (rawEvent->code) {
- case REL_X:
- mRelX = rawEvent->value;
- break;
- case REL_Y:
- mRelY = rawEvent->value;
- break;
- }
- }
-}
-
-void CursorMotionAccumulator::finishSync() {
- clearRelativeAxes();
-}
-
-
-// --- CursorScrollAccumulator ---
-
-CursorScrollAccumulator::CursorScrollAccumulator() :
- mHaveRelWheel(false), mHaveRelHWheel(false) {
- clearRelativeAxes();
-}
-
-void CursorScrollAccumulator::configure(InputDevice* device) {
- mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
- mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
-}
-
-void CursorScrollAccumulator::reset(InputDevice* device) {
- clearRelativeAxes();
-}
-
-void CursorScrollAccumulator::clearRelativeAxes() {
- mRelWheel = 0;
- mRelHWheel = 0;
-}
-
-void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_REL) {
- switch (rawEvent->code) {
- case REL_WHEEL:
- mRelWheel = rawEvent->value;
- break;
- case REL_HWHEEL:
- mRelHWheel = rawEvent->value;
- break;
- }
- }
-}
-
-void CursorScrollAccumulator::finishSync() {
- clearRelativeAxes();
-}
-
-
-// --- TouchButtonAccumulator ---
-
-TouchButtonAccumulator::TouchButtonAccumulator() :
- mHaveBtnTouch(false), mHaveStylus(false) {
- clearButtons();
-}
-
-void TouchButtonAccumulator::configure(InputDevice* device) {
- mHaveBtnTouch = device->hasKey(BTN_TOUCH);
- mHaveStylus = device->hasKey(BTN_TOOL_PEN)
- || device->hasKey(BTN_TOOL_RUBBER)
- || device->hasKey(BTN_TOOL_BRUSH)
- || device->hasKey(BTN_TOOL_PENCIL)
- || device->hasKey(BTN_TOOL_AIRBRUSH);
-}
-
-void TouchButtonAccumulator::reset(InputDevice* device) {
- mBtnTouch = device->isKeyPressed(BTN_TOUCH);
- mBtnStylus = device->isKeyPressed(BTN_STYLUS);
- mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
- mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
- mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
- mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
- mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
- mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
- mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
- mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
- mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
- mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
- mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
- mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
-}
-
-void TouchButtonAccumulator::clearButtons() {
- mBtnTouch = 0;
- mBtnStylus = 0;
- mBtnStylus2 = 0;
- mBtnToolFinger = 0;
- mBtnToolPen = 0;
- mBtnToolRubber = 0;
- mBtnToolBrush = 0;
- mBtnToolPencil = 0;
- mBtnToolAirbrush = 0;
- mBtnToolMouse = 0;
- mBtnToolLens = 0;
- mBtnToolDoubleTap = 0;
- mBtnToolTripleTap = 0;
- mBtnToolQuadTap = 0;
-}
-
-void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_KEY) {
- switch (rawEvent->code) {
- case BTN_TOUCH:
- mBtnTouch = rawEvent->value;
- break;
- case BTN_STYLUS:
- mBtnStylus = rawEvent->value;
- break;
- case BTN_STYLUS2:
- mBtnStylus2 = rawEvent->value;
- break;
- case BTN_TOOL_FINGER:
- mBtnToolFinger = rawEvent->value;
- break;
- case BTN_TOOL_PEN:
- mBtnToolPen = rawEvent->value;
- break;
- case BTN_TOOL_RUBBER:
- mBtnToolRubber = rawEvent->value;
- break;
- case BTN_TOOL_BRUSH:
- mBtnToolBrush = rawEvent->value;
- break;
- case BTN_TOOL_PENCIL:
- mBtnToolPencil = rawEvent->value;
- break;
- case BTN_TOOL_AIRBRUSH:
- mBtnToolAirbrush = rawEvent->value;
- break;
- case BTN_TOOL_MOUSE:
- mBtnToolMouse = rawEvent->value;
- break;
- case BTN_TOOL_LENS:
- mBtnToolLens = rawEvent->value;
- break;
- case BTN_TOOL_DOUBLETAP:
- mBtnToolDoubleTap = rawEvent->value;
- break;
- case BTN_TOOL_TRIPLETAP:
- mBtnToolTripleTap = rawEvent->value;
- break;
- case BTN_TOOL_QUADTAP:
- mBtnToolQuadTap = rawEvent->value;
- break;
- }
- }
-}
-
-uint32_t TouchButtonAccumulator::getButtonState() const {
- uint32_t result = 0;
- if (mBtnStylus) {
- result |= AMOTION_EVENT_BUTTON_SECONDARY;
- }
- if (mBtnStylus2) {
- result |= AMOTION_EVENT_BUTTON_TERTIARY;
- }
- return result;
-}
-
-int32_t TouchButtonAccumulator::getToolType() const {
- if (mBtnToolMouse || mBtnToolLens) {
- return AMOTION_EVENT_TOOL_TYPE_MOUSE;
- }
- if (mBtnToolRubber) {
- return AMOTION_EVENT_TOOL_TYPE_ERASER;
- }
- if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
- return AMOTION_EVENT_TOOL_TYPE_STYLUS;
- }
- if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
- return AMOTION_EVENT_TOOL_TYPE_FINGER;
- }
- return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-bool TouchButtonAccumulator::isToolActive() const {
- return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
- || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
- || mBtnToolMouse || mBtnToolLens
- || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
-}
-
-bool TouchButtonAccumulator::isHovering() const {
- return mHaveBtnTouch && !mBtnTouch;
-}
-
-bool TouchButtonAccumulator::hasStylus() const {
- return mHaveStylus;
-}
-
-
-// --- RawPointerAxes ---
-
-RawPointerAxes::RawPointerAxes() {
- clear();
-}
-
-void RawPointerAxes::clear() {
- x.clear();
- y.clear();
- pressure.clear();
- touchMajor.clear();
- touchMinor.clear();
- toolMajor.clear();
- toolMinor.clear();
- orientation.clear();
- distance.clear();
- tiltX.clear();
- tiltY.clear();
- trackingId.clear();
- slot.clear();
-}
-
-
-// --- RawPointerData ---
-
-RawPointerData::RawPointerData() {
- clear();
-}
-
-void RawPointerData::clear() {
- pointerCount = 0;
- clearIdBits();
-}
-
-void RawPointerData::copyFrom(const RawPointerData& other) {
- pointerCount = other.pointerCount;
- hoveringIdBits = other.hoveringIdBits;
- touchingIdBits = other.touchingIdBits;
-
- for (uint32_t i = 0; i < pointerCount; i++) {
- pointers[i] = other.pointers[i];
-
- int id = pointers[i].id;
- idToIndex[id] = other.idToIndex[id];
- }
-}
-
-void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
- float x = 0, y = 0;
- uint32_t count = touchingIdBits.count();
- if (count) {
- for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- const Pointer& pointer = pointerForId(id);
- x += pointer.x;
- y += pointer.y;
- }
- x /= count;
- y /= count;
- }
- *outX = x;
- *outY = y;
-}
-
-
-// --- CookedPointerData ---
-
-CookedPointerData::CookedPointerData() {
- clear();
-}
-
-void CookedPointerData::clear() {
- pointerCount = 0;
- hoveringIdBits.clear();
- touchingIdBits.clear();
-}
-
-void CookedPointerData::copyFrom(const CookedPointerData& other) {
- pointerCount = other.pointerCount;
- hoveringIdBits = other.hoveringIdBits;
- touchingIdBits = other.touchingIdBits;
-
- for (uint32_t i = 0; i < pointerCount; i++) {
- pointerProperties[i].copyFrom(other.pointerProperties[i]);
- pointerCoords[i].copyFrom(other.pointerCoords[i]);
-
- int id = pointerProperties[i].id;
- idToIndex[id] = other.idToIndex[id];
- }
-}
-
-
-// --- SingleTouchMotionAccumulator ---
-
-SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
- clearAbsoluteAxes();
-}
-
-void SingleTouchMotionAccumulator::reset(InputDevice* device) {
- mAbsX = device->getAbsoluteAxisValue(ABS_X);
- mAbsY = device->getAbsoluteAxisValue(ABS_Y);
- mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
- mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
- mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
- mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
- mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
-}
-
-void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
- mAbsX = 0;
- mAbsY = 0;
- mAbsPressure = 0;
- mAbsToolWidth = 0;
- mAbsDistance = 0;
- mAbsTiltX = 0;
- mAbsTiltY = 0;
-}
-
-void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_ABS) {
- switch (rawEvent->code) {
- case ABS_X:
- mAbsX = rawEvent->value;
- break;
- case ABS_Y:
- mAbsY = rawEvent->value;
- break;
- case ABS_PRESSURE:
- mAbsPressure = rawEvent->value;
- break;
- case ABS_TOOL_WIDTH:
- mAbsToolWidth = rawEvent->value;
- break;
- case ABS_DISTANCE:
- mAbsDistance = rawEvent->value;
- break;
- case ABS_TILT_X:
- mAbsTiltX = rawEvent->value;
- break;
- case ABS_TILT_Y:
- mAbsTiltY = rawEvent->value;
- break;
- }
- }
-}
-
-
-// --- MultiTouchMotionAccumulator ---
-
-MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
- mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
- mHaveStylus(false) {
-}
-
-MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
- delete[] mSlots;
-}
-
-void MultiTouchMotionAccumulator::configure(InputDevice* device,
- size_t slotCount, bool usingSlotsProtocol) {
- mSlotCount = slotCount;
- mUsingSlotsProtocol = usingSlotsProtocol;
- mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
-
- delete[] mSlots;
- mSlots = new Slot[slotCount];
-}
-
-void MultiTouchMotionAccumulator::reset(InputDevice* device) {
- // Unfortunately there is no way to read the initial contents of the slots.
- // So when we reset the accumulator, we must assume they are all zeroes.
- if (mUsingSlotsProtocol) {
- // Query the driver for the current slot index and use it as the initial slot
- // before we start reading events from the device. It is possible that the
- // current slot index will not be the same as it was when the first event was
- // written into the evdev buffer, which means the input mapper could start
- // out of sync with the initial state of the events in the evdev buffer.
- // In the extremely unlikely case that this happens, the data from
- // two slots will be confused until the next ABS_MT_SLOT event is received.
- // This can cause the touch point to "jump", but at least there will be
- // no stuck touches.
- int32_t initialSlot;
- status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
- ABS_MT_SLOT, &initialSlot);
- if (status) {
- ALOGD("Could not retrieve current multitouch slot index. status=%d", status);
- initialSlot = -1;
- }
- clearSlots(initialSlot);
- } else {
- clearSlots(-1);
- }
-}
-
-void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
- if (mSlots) {
- for (size_t i = 0; i < mSlotCount; i++) {
- mSlots[i].clear();
- }
- }
- mCurrentSlot = initialSlot;
-}
-
-void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
- if (rawEvent->type == EV_ABS) {
-#if DEBUG_POINTERS
- bool newSlot = false;
-#endif
- if (mUsingSlotsProtocol) {
- if (rawEvent->code == ABS_MT_SLOT) {
- mCurrentSlot = rawEvent->value;
-#if DEBUG_POINTERS
- newSlot = true;
-#endif
- }
- } else if (mCurrentSlot < 0) {
- mCurrentSlot = 0;
- }
-
- if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
-#if DEBUG_POINTERS
- if (newSlot) {
- ALOGW("MultiTouch device emitted invalid slot index %d but it "
- "should be between 0 and %d; ignoring this slot.",
- mCurrentSlot, mSlotCount - 1);
- }
-#endif
- } else {
- Slot* slot = &mSlots[mCurrentSlot];
-
- switch (rawEvent->code) {
- case ABS_MT_POSITION_X:
- slot->mInUse = true;
- slot->mAbsMTPositionX = rawEvent->value;
- break;
- case ABS_MT_POSITION_Y:
- slot->mInUse = true;
- slot->mAbsMTPositionY = rawEvent->value;
- break;
- case ABS_MT_TOUCH_MAJOR:
- slot->mInUse = true;
- slot->mAbsMTTouchMajor = rawEvent->value;
- break;
- case ABS_MT_TOUCH_MINOR:
- slot->mInUse = true;
- slot->mAbsMTTouchMinor = rawEvent->value;
- slot->mHaveAbsMTTouchMinor = true;
- break;
- case ABS_MT_WIDTH_MAJOR:
- slot->mInUse = true;
- slot->mAbsMTWidthMajor = rawEvent->value;
- break;
- case ABS_MT_WIDTH_MINOR:
- slot->mInUse = true;
- slot->mAbsMTWidthMinor = rawEvent->value;
- slot->mHaveAbsMTWidthMinor = true;
- break;
- case ABS_MT_ORIENTATION:
- slot->mInUse = true;
- slot->mAbsMTOrientation = rawEvent->value;
- break;
- case ABS_MT_TRACKING_ID:
- if (mUsingSlotsProtocol && rawEvent->value < 0) {
- // The slot is no longer in use but it retains its previous contents,
- // which may be reused for subsequent touches.
- slot->mInUse = false;
- } else {
- slot->mInUse = true;
- slot->mAbsMTTrackingId = rawEvent->value;
- }
- break;
- case ABS_MT_PRESSURE:
- slot->mInUse = true;
- slot->mAbsMTPressure = rawEvent->value;
- break;
- case ABS_MT_DISTANCE:
- slot->mInUse = true;
- slot->mAbsMTDistance = rawEvent->value;
- break;
- case ABS_MT_TOOL_TYPE:
- slot->mInUse = true;
- slot->mAbsMTToolType = rawEvent->value;
- slot->mHaveAbsMTToolType = true;
- break;
- }
- }
- } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
- // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
- mCurrentSlot += 1;
- }
-}
-
-void MultiTouchMotionAccumulator::finishSync() {
- if (!mUsingSlotsProtocol) {
- clearSlots(-1);
- }
-}
-
-bool MultiTouchMotionAccumulator::hasStylus() const {
- return mHaveStylus;
-}
-
-
-// --- MultiTouchMotionAccumulator::Slot ---
-
-MultiTouchMotionAccumulator::Slot::Slot() {
- clear();
-}
-
-void MultiTouchMotionAccumulator::Slot::clear() {
- mInUse = false;
- mHaveAbsMTTouchMinor = false;
- mHaveAbsMTWidthMinor = false;
- mHaveAbsMTToolType = false;
- mAbsMTPositionX = 0;
- mAbsMTPositionY = 0;
- mAbsMTTouchMajor = 0;
- mAbsMTTouchMinor = 0;
- mAbsMTWidthMajor = 0;
- mAbsMTWidthMinor = 0;
- mAbsMTOrientation = 0;
- mAbsMTTrackingId = -1;
- mAbsMTPressure = 0;
- mAbsMTDistance = 0;
- mAbsMTToolType = 0;
-}
-
-int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
- if (mHaveAbsMTToolType) {
- switch (mAbsMTToolType) {
- case MT_TOOL_FINGER:
- return AMOTION_EVENT_TOOL_TYPE_FINGER;
- case MT_TOOL_PEN:
- return AMOTION_EVENT_TOOL_TYPE_STYLUS;
- }
- }
- return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-
-// --- InputMapper ---
-
-InputMapper::InputMapper(InputDevice* device) :
- mDevice(device), mContext(device->getContext()) {
-}
-
-InputMapper::~InputMapper() {
-}
-
-void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- info->addSource(getSources());
-}
-
-void InputMapper::dump(String8& dump) {
-}
-
-void InputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config, uint32_t changes) {
-}
-
-void InputMapper::reset(nsecs_t when) {
-}
-
-void InputMapper::timeoutExpired(nsecs_t when) {
-}
-
-int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
- return AKEY_STATE_UNKNOWN;
-}
-
-bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- return false;
-}
-
-void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token) {
-}
-
-void InputMapper::cancelVibrate(int32_t token) {
-}
-
-int32_t InputMapper::getMetaState() {
- return 0;
-}
-
-void InputMapper::fadePointer() {
-}
-
-status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
- return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
-}
-
-void InputMapper::bumpGeneration() {
- mDevice->bumpGeneration();
-}
-
-void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
- const RawAbsoluteAxisInfo& axis, const char* name) {
- if (axis.valid) {
- dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
- name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
- } else {
- dump.appendFormat(INDENT4 "%s: unknown range\n", name);
- }
-}
-
-
-// --- SwitchInputMapper ---
-
-SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
- InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
-}
-
-SwitchInputMapper::~SwitchInputMapper() {
-}
-
-uint32_t SwitchInputMapper::getSources() {
- return AINPUT_SOURCE_SWITCH;
-}
-
-void SwitchInputMapper::process(const RawEvent* rawEvent) {
- switch (rawEvent->type) {
- case EV_SW:
- processSwitch(rawEvent->code, rawEvent->value);
- break;
-
- case EV_SYN:
- if (rawEvent->code == SYN_REPORT) {
- sync(rawEvent->when);
- }
- }
-}
-
-void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
- if (switchCode >= 0 && switchCode < 32) {
- if (switchValue) {
- mUpdatedSwitchValues |= 1 << switchCode;
- }
- mUpdatedSwitchMask |= 1 << switchCode;
- }
-}
-
-void SwitchInputMapper::sync(nsecs_t when) {
- if (mUpdatedSwitchMask) {
- NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
- getListener()->notifySwitch(&args);
-
- mUpdatedSwitchValues = 0;
- mUpdatedSwitchMask = 0;
- }
-}
-
-int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
- return getEventHub()->getSwitchState(getDeviceId(), switchCode);
-}
-
-
-// --- VibratorInputMapper ---
-
-VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
- InputMapper(device), mVibrating(false) {
-}
-
-VibratorInputMapper::~VibratorInputMapper() {
-}
-
-uint32_t VibratorInputMapper::getSources() {
- return 0;
-}
-
-void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- InputMapper::populateDeviceInfo(info);
-
- info->setVibrator(true);
-}
-
-void VibratorInputMapper::process(const RawEvent* rawEvent) {
- // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
-}
-
-void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token) {
-#if DEBUG_VIBRATOR
- String8 patternStr;
- for (size_t i = 0; i < patternSize; i++) {
- if (i != 0) {
- patternStr.append(", ");
- }
- patternStr.appendFormat("%lld", pattern[i]);
- }
- ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
- getDeviceId(), patternStr.string(), repeat, token);
-#endif
-
- mVibrating = true;
- memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
- mPatternSize = patternSize;
- mRepeat = repeat;
- mToken = token;
- mIndex = -1;
-
- nextStep();
-}
-
-void VibratorInputMapper::cancelVibrate(int32_t token) {
-#if DEBUG_VIBRATOR
- ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
-#endif
-
- if (mVibrating && mToken == token) {
- stopVibrating();
- }
-}
-
-void VibratorInputMapper::timeoutExpired(nsecs_t when) {
- if (mVibrating) {
- if (when >= mNextStepTime) {
- nextStep();
- } else {
- getContext()->requestTimeoutAtTime(mNextStepTime);
- }
- }
-}
-
-void VibratorInputMapper::nextStep() {
- mIndex += 1;
- if (size_t(mIndex) >= mPatternSize) {
- if (mRepeat < 0) {
- // We are done.
- stopVibrating();
- return;
- }
- mIndex = mRepeat;
- }
-
- bool vibratorOn = mIndex & 1;
- nsecs_t duration = mPattern[mIndex];
- if (vibratorOn) {
-#if DEBUG_VIBRATOR
- ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
- getDeviceId(), duration);
-#endif
- getEventHub()->vibrate(getDeviceId(), duration);
- } else {
-#if DEBUG_VIBRATOR
- ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
-#endif
- getEventHub()->cancelVibrate(getDeviceId());
- }
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- mNextStepTime = now + duration;
- getContext()->requestTimeoutAtTime(mNextStepTime);
-#if DEBUG_VIBRATOR
- ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
-#endif
-}
-
-void VibratorInputMapper::stopVibrating() {
- mVibrating = false;
-#if DEBUG_VIBRATOR
- ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
-#endif
- getEventHub()->cancelVibrate(getDeviceId());
-}
-
-void VibratorInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Vibrator Input Mapper:\n");
- dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
-}
-
-
-// --- KeyboardInputMapper ---
-
-KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
- uint32_t source, int32_t keyboardType) :
- InputMapper(device), mSource(source),
- mKeyboardType(keyboardType) {
-}
-
-KeyboardInputMapper::~KeyboardInputMapper() {
-}
-
-uint32_t KeyboardInputMapper::getSources() {
- return mSource;
-}
-
-void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- InputMapper::populateDeviceInfo(info);
-
- info->setKeyboardType(mKeyboardType);
- info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
-}
-
-void KeyboardInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Keyboard Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
- dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
- dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
- dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
-}
-
-
-void KeyboardInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config, uint32_t changes) {
- InputMapper::configure(when, config, changes);
-
- if (!changes) { // first time only
- // Configure basic parameters.
- configureParameters();
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- DisplayViewport v;
- if (config->getDisplayInfo(false /*external*/, &v)) {
- mOrientation = v.orientation;
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
- }
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
- }
- }
-}
-
-void KeyboardInputMapper::configureParameters() {
- mParameters.orientationAware = false;
- getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
- mParameters.orientationAware);
-
- mParameters.hasAssociatedDisplay = false;
- if (mParameters.orientationAware) {
- mParameters.hasAssociatedDisplay = true;
- }
-}
-
-void KeyboardInputMapper::dumpParameters(String8& dump) {
- dump.append(INDENT3 "Parameters:\n");
- dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
- toString(mParameters.hasAssociatedDisplay));
- dump.appendFormat(INDENT4 "OrientationAware: %s\n",
- toString(mParameters.orientationAware));
-}
-
-void KeyboardInputMapper::reset(nsecs_t when) {
- mMetaState = AMETA_NONE;
- mDownTime = 0;
- mKeyDowns.clear();
- mCurrentHidUsage = 0;
-
- resetLedState();
-
- InputMapper::reset(when);
-}
-
-void KeyboardInputMapper::process(const RawEvent* rawEvent) {
- switch (rawEvent->type) {
- case EV_KEY: {
- int32_t scanCode = rawEvent->code;
- int32_t usageCode = mCurrentHidUsage;
- mCurrentHidUsage = 0;
-
- if (isKeyboardOrGamepadKey(scanCode)) {
- int32_t keyCode;
- uint32_t flags;
- if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
- keyCode = AKEYCODE_UNKNOWN;
- flags = 0;
- }
- processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
- }
- break;
- }
- case EV_MSC: {
- if (rawEvent->code == MSC_SCAN) {
- mCurrentHidUsage = rawEvent->value;
- }
- break;
- }
- case EV_SYN: {
- if (rawEvent->code == SYN_REPORT) {
- mCurrentHidUsage = 0;
- }
- }
- }
-}
-
-bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
- return scanCode < BTN_MOUSE
- || scanCode >= KEY_OK
- || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
- || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
-}
-
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
- int32_t scanCode, uint32_t policyFlags) {
-
- if (down) {
- // Rotate key codes according to orientation if needed.
- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- keyCode = rotateKeyCode(keyCode, mOrientation);
- }
-
- // Add key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
- } else {
- // key down
- if ((policyFlags & POLICY_FLAG_VIRTUAL)
- && mContext->shouldDropVirtualKey(when,
- getDevice(), keyCode, scanCode)) {
- return;
- }
-
- mKeyDowns.push();
- KeyDown& keyDown = mKeyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
- }
-
- mDownTime = when;
- } else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDown(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
- mKeyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- ALOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
- return;
- }
- }
-
- bool metaStateChanged = false;
- int32_t oldMetaState = mMetaState;
- int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mMetaState = newMetaState;
- metaStateChanged = true;
- updateLedState(false);
- }
-
- nsecs_t downTime = mDownTime;
-
- // Key down on external an keyboard should wake the device.
- // We don't do this for internal keyboards to prevent them from waking up in your pocket.
- // For internal keyboards, the key layout file should specify the policy flags for
- // each wake key individually.
- // TODO: Use the input device configuration to control this behavior more finely.
- if (down && getDevice()->isExternal()
- && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
- policyFlags |= POLICY_FLAG_WAKE_DROPPED;
- }
-
- if (metaStateChanged) {
- getContext()->updateGlobalMetaState();
- }
-
- if (down && !isMetaKey(keyCode)) {
- getContext()->fadePointer();
- }
-
- NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
- down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
- AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
- getListener()->notifyKey(&args);
-}
-
-ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
- size_t n = mKeyDowns.size();
- for (size_t i = 0; i < n; i++) {
- if (mKeyDowns[i].scanCode == scanCode) {
- return i;
- }
- }
- return -1;
-}
-
-int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
-}
-
-int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
-}
-
-bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
-}
-
-int32_t KeyboardInputMapper::getMetaState() {
- return mMetaState;
-}
-
-void KeyboardInputMapper::resetLedState() {
- initializeLedState(mCapsLockLedState, LED_CAPSL);
- initializeLedState(mNumLockLedState, LED_NUML);
- initializeLedState(mScrollLockLedState, LED_SCROLLL);
-
- updateLedState(true);
-}
-
-void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
- ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
- ledState.on = false;
-}
-
-void KeyboardInputMapper::updateLedState(bool reset) {
- updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
- AMETA_CAPS_LOCK_ON, reset);
- updateLedStateForModifier(mNumLockLedState, LED_NUML,
- AMETA_NUM_LOCK_ON, reset);
- updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
- AMETA_SCROLL_LOCK_ON, reset);
-}
-
-void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
- int32_t led, int32_t modifier, bool reset) {
- if (ledState.avail) {
- bool desiredState = (mMetaState & modifier) != 0;
- if (reset || ledState.on != desiredState) {
- getEventHub()->setLedState(getDeviceId(), led, desiredState);
- ledState.on = desiredState;
- }
- }
-}
-
-
-// --- CursorInputMapper ---
-
-CursorInputMapper::CursorInputMapper(InputDevice* device) :
- InputMapper(device) {
-}
-
-CursorInputMapper::~CursorInputMapper() {
-}
-
-uint32_t CursorInputMapper::getSources() {
- return mSource;
-}
-
-void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- InputMapper::populateDeviceInfo(info);
-
- if (mParameters.mode == Parameters::MODE_POINTER) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
- }
- } else {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
- }
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
-
- if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
- }
- if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
- }
-}
-
-void CursorInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Cursor Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
- dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
- dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
- dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
- dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
- toString(mCursorScrollAccumulator.haveRelativeVWheel()));
- dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
- toString(mCursorScrollAccumulator.haveRelativeHWheel()));
- dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
- dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
- dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
- dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
- dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
-}
-
-void CursorInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config, uint32_t changes) {
- InputMapper::configure(when, config, changes);
-
- if (!changes) { // first time only
- mCursorScrollAccumulator.configure(getDevice());
-
- // Configure basic parameters.
- configureParameters();
-
- // Configure device mode.
- switch (mParameters.mode) {
- case Parameters::MODE_POINTER:
- mSource = AINPUT_SOURCE_MOUSE;
- mXPrecision = 1.0f;
- mYPrecision = 1.0f;
- mXScale = 1.0f;
- mYScale = 1.0f;
- mPointerController = getPolicy()->obtainPointerController(getDeviceId());
- break;
- case Parameters::MODE_NAVIGATION:
- mSource = AINPUT_SOURCE_TRACKBALL;
- mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
- mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
- mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- break;
- }
-
- mVWheelScale = 1.0f;
- mHWheelScale = 1.0f;
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
- mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
- DisplayViewport v;
- if (config->getDisplayInfo(false /*external*/, &v)) {
- mOrientation = v.orientation;
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
- }
- } else {
- mOrientation = DISPLAY_ORIENTATION_0;
- }
- bumpGeneration();
- }
-}
-
-void CursorInputMapper::configureParameters() {
- mParameters.mode = Parameters::MODE_POINTER;
- String8 cursorModeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
- if (cursorModeString == "navigation") {
- mParameters.mode = Parameters::MODE_NAVIGATION;
- } else if (cursorModeString != "pointer" && cursorModeString != "default") {
- ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
- }
- }
-
- mParameters.orientationAware = false;
- getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
- mParameters.orientationAware);
-
- mParameters.hasAssociatedDisplay = false;
- if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
- mParameters.hasAssociatedDisplay = true;
- }
-}
-
-void CursorInputMapper::dumpParameters(String8& dump) {
- dump.append(INDENT3 "Parameters:\n");
- dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
- toString(mParameters.hasAssociatedDisplay));
-
- switch (mParameters.mode) {
- case Parameters::MODE_POINTER:
- dump.append(INDENT4 "Mode: pointer\n");
- break;
- case Parameters::MODE_NAVIGATION:
- dump.append(INDENT4 "Mode: navigation\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- dump.appendFormat(INDENT4 "OrientationAware: %s\n",
- toString(mParameters.orientationAware));
-}
-
-void CursorInputMapper::reset(nsecs_t when) {
- mButtonState = 0;
- mDownTime = 0;
-
- mPointerVelocityControl.reset();
- mWheelXVelocityControl.reset();
- mWheelYVelocityControl.reset();
-
- mCursorButtonAccumulator.reset(getDevice());
- mCursorMotionAccumulator.reset(getDevice());
- mCursorScrollAccumulator.reset(getDevice());
-
- InputMapper::reset(when);
-}
-
-void CursorInputMapper::process(const RawEvent* rawEvent) {
- mCursorButtonAccumulator.process(rawEvent);
- mCursorMotionAccumulator.process(rawEvent);
- mCursorScrollAccumulator.process(rawEvent);
-
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
- sync(rawEvent->when);
- }
-}
-
-void CursorInputMapper::sync(nsecs_t when) {
- int32_t lastButtonState = mButtonState;
- int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
- mButtonState = currentButtonState;
-
- bool wasDown = isPointerDown(lastButtonState);
- bool down = isPointerDown(currentButtonState);
- bool downChanged;
- if (!wasDown && down) {
- mDownTime = when;
- downChanged = true;
- } else if (wasDown && !down) {
- downChanged = true;
- } else {
- downChanged = false;
- }
- nsecs_t downTime = mDownTime;
- bool buttonsChanged = currentButtonState != lastButtonState;
- bool buttonsPressed = currentButtonState & ~lastButtonState;
-
- float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
- float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
- bool moved = deltaX != 0 || deltaY != 0;
-
- // Rotate delta according to orientation if needed.
- if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
- && (deltaX != 0.0f || deltaY != 0.0f)) {
- rotateDelta(mOrientation, &deltaX, &deltaY);
- }
-
- // Move the pointer.
- PointerProperties pointerProperties;
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
-
- PointerCoords pointerCoords;
- pointerCoords.clear();
-
- float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
- float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
- bool scrolled = vscroll != 0 || hscroll != 0;
-
- mWheelYVelocityControl.move(when, NULL, &vscroll);
- mWheelXVelocityControl.move(when, &hscroll, NULL);
-
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
- int32_t displayId;
- if (mPointerController != NULL) {
- if (moved || scrolled || buttonsChanged) {
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
-
- if (moved) {
- mPointerController->move(deltaX, deltaY);
- }
-
- if (buttonsChanged) {
- mPointerController->setButtonState(currentButtonState);
- }
-
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- }
-
- float x, y;
- mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- displayId = ADISPLAY_ID_DEFAULT;
- } else {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
- displayId = ADISPLAY_ID_NONE;
- }
-
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
-
- // Moving an external trackball or mouse should wake the device.
- // We don't do this for internal cursor devices to prevent them from waking up
- // the device in your pocket.
- // TODO: Use the input device configuration to control this behavior more finely.
- uint32_t policyFlags = 0;
- if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
- policyFlags |= POLICY_FLAG_WAKE_DROPPED;
- }
-
- // Synthesize key down from buttons if needed.
- synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
- policyFlags, lastButtonState, currentButtonState);
-
- // Send motion event.
- if (downChanged || moved || scrolled || buttonsChanged) {
- int32_t metaState = mContext->getGlobalMetaState();
- int32_t motionEventAction;
- if (downChanged) {
- motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else if (down || mPointerController == NULL) {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
- }
-
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- motionEventAction, 0, metaState, currentButtonState, 0,
- displayId, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime);
- getListener()->notifyMotion(&args);
-
- // Send hover move after UP to tell the application that the mouse is hovering now.
- if (motionEventAction == AMOTION_EVENT_ACTION_UP
- && mPointerController != NULL) {
- NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime);
- getListener()->notifyMotion(&hoverArgs);
- }
-
- // Send scroll events.
- if (scrolled) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
-
- NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- displayId, 1, &pointerProperties, &pointerCoords,
- mXPrecision, mYPrecision, downTime);
- getListener()->notifyMotion(&scrollArgs);
- }
- }
-
- // Synthesize key up from buttons if needed.
- synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
- policyFlags, lastButtonState, currentButtonState);
-
- mCursorMotionAccumulator.finishSync();
- mCursorScrollAccumulator.finishSync();
-}
-
-int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
- return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
- } else {
- return AKEY_STATE_UNKNOWN;
- }
-}
-
-void CursorInputMapper::fadePointer() {
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
-}
-
-
-// --- TouchInputMapper ---
-
-TouchInputMapper::TouchInputMapper(InputDevice* device) :
- InputMapper(device),
- mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
- mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
- mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
-}
-
-TouchInputMapper::~TouchInputMapper() {
-}
-
-uint32_t TouchInputMapper::getSources() {
- return mSource;
-}
-
-void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- InputMapper::populateDeviceInfo(info);
-
- if (mDeviceMode != DEVICE_MODE_DISABLED) {
- info->addMotionRange(mOrientedRanges.x);
- info->addMotionRange(mOrientedRanges.y);
- info->addMotionRange(mOrientedRanges.pressure);
-
- if (mOrientedRanges.haveSize) {
- info->addMotionRange(mOrientedRanges.size);
- }
-
- if (mOrientedRanges.haveTouchSize) {
- info->addMotionRange(mOrientedRanges.touchMajor);
- info->addMotionRange(mOrientedRanges.touchMinor);
- }
-
- if (mOrientedRanges.haveToolSize) {
- info->addMotionRange(mOrientedRanges.toolMajor);
- info->addMotionRange(mOrientedRanges.toolMinor);
- }
-
- if (mOrientedRanges.haveOrientation) {
- info->addMotionRange(mOrientedRanges.orientation);
- }
-
- if (mOrientedRanges.haveDistance) {
- info->addMotionRange(mOrientedRanges.distance);
- }
-
- if (mOrientedRanges.haveTilt) {
- info->addMotionRange(mOrientedRanges.tilt);
- }
-
- if (mCursorScrollAccumulator.haveRelativeVWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
- 0.0f);
- }
- if (mCursorScrollAccumulator.haveRelativeHWheel()) {
- info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
- 0.0f);
- }
- if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
- const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
- const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
- info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
- x.fuzz, x.resolution);
- info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
- y.fuzz, y.resolution);
- info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
- x.fuzz, x.resolution);
- info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
- y.fuzz, y.resolution);
- }
- }
-}
-
-void TouchInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Touch Input Mapper:\n");
- dumpParameters(dump);
- dumpVirtualKeys(dump);
- dumpRawPointerAxes(dump);
- dumpCalibration(dump);
- dumpSurface(dump);
-
- dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
- dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
- dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
- dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
- dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
- dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
- dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
- dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
- dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
- dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
- dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
- dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
- dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
- dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
- dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
- dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
- dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
-
- dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
-
- dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
- mLastRawPointerData.pointerCount);
- for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
- const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
- dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
- "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
- "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
- "toolType=%d, isHovering=%s\n", i,
- pointer.id, pointer.x, pointer.y, pointer.pressure,
- pointer.touchMajor, pointer.touchMinor,
- pointer.toolMajor, pointer.toolMinor,
- pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
- pointer.toolType, toString(pointer.isHovering));
- }
-
- dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
- mLastCookedPointerData.pointerCount);
- for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
- const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
- const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
- dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
- "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
- "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
- "toolType=%d, isHovering=%s\n", i,
- pointerProperties.id,
- pointerCoords.getX(),
- pointerCoords.getY(),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
- pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
- pointerProperties.toolType,
- toString(mLastCookedPointerData.isHovering(i)));
- }
-
- if (mDeviceMode == DEVICE_MODE_POINTER) {
- dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
- dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
- mPointerXMovementScale);
- dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
- mPointerYMovementScale);
- dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
- mPointerXZoomScale);
- dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
- mPointerYZoomScale);
- dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
- mPointerGestureMaxSwipeWidth);
- }
-}
-
-void TouchInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config, uint32_t changes) {
- InputMapper::configure(when, config, changes);
-
- mConfig = *config;
-
- if (!changes) { // first time only
- // Configure basic parameters.
- configureParameters();
-
- // Configure common accumulators.
- mCursorScrollAccumulator.configure(getDevice());
- mTouchButtonAccumulator.configure(getDevice());
-
- // Configure absolute axis information.
- configureRawPointerAxes();
-
- // Prepare input device calibration.
- parseCalibration();
- resolveCalibration();
- }
-
- if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
- // Update pointer speed.
- mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
- }
-
- bool resetNeeded = false;
- if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
- | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
- | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
- // Configure device sources, surface dimensions, orientation and
- // scaling factors.
- configureSurface(when, &resetNeeded);
- }
-
- if (changes && resetNeeded) {
- // Send reset, unless this is the first time the device has been configured,
- // in which case the reader will call reset itself after all mappers are ready.
- getDevice()->notifyReset(when);
- }
-}
-
-void TouchInputMapper::configureParameters() {
- // Use the pointer presentation mode for devices that do not support distinct
- // multitouch. The spot-based presentation relies on being able to accurately
- // locate two or more fingers on the touch pad.
- mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
- ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
-
- String8 gestureModeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
- gestureModeString)) {
- if (gestureModeString == "pointer") {
- mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
- } else if (gestureModeString == "spots") {
- mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
- } else if (gestureModeString != "default") {
- ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
- }
- }
-
- if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
- // The device is a touch screen.
- mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
- // The device is a pointing device like a track pad.
- mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
- } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
- || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
- // The device is a cursor device with a touch pad attached.
- // By default don't use the touch pad to move the pointer.
- mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
- } else {
- // The device is a touch pad of unknown purpose.
- mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
- }
-
- String8 deviceTypeString;
- if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
- deviceTypeString)) {
- if (deviceTypeString == "touchScreen") {
- mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- } else if (deviceTypeString == "touchPad") {
- mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
- } else if (deviceTypeString == "touchNavigation") {
- mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
- } else if (deviceTypeString == "pointer") {
- mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
- } else if (deviceTypeString != "default") {
- ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
- }
- }
-
- mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
- getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
- mParameters.orientationAware);
-
- mParameters.hasAssociatedDisplay = false;
- mParameters.associatedDisplayIsExternal = false;
- if (mParameters.orientationAware
- || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
- || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- mParameters.hasAssociatedDisplay = true;
- mParameters.associatedDisplayIsExternal =
- mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
- && getDevice()->isExternal();
- }
-}
-
-void TouchInputMapper::dumpParameters(String8& dump) {
- dump.append(INDENT3 "Parameters:\n");
-
- switch (mParameters.gestureMode) {
- case Parameters::GESTURE_MODE_POINTER:
- dump.append(INDENT4 "GestureMode: pointer\n");
- break;
- case Parameters::GESTURE_MODE_SPOTS:
- dump.append(INDENT4 "GestureMode: spots\n");
- break;
- default:
- assert(false);
- }
-
- switch (mParameters.deviceType) {
- case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
- dump.append(INDENT4 "DeviceType: touchScreen\n");
- break;
- case Parameters::DEVICE_TYPE_TOUCH_PAD:
- dump.append(INDENT4 "DeviceType: touchPad\n");
- break;
- case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
- dump.append(INDENT4 "DeviceType: touchNavigation\n");
- break;
- case Parameters::DEVICE_TYPE_POINTER:
- dump.append(INDENT4 "DeviceType: pointer\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
- toString(mParameters.hasAssociatedDisplay),
- toString(mParameters.associatedDisplayIsExternal));
- dump.appendFormat(INDENT4 "OrientationAware: %s\n",
- toString(mParameters.orientationAware));
-}
-
-void TouchInputMapper::configureRawPointerAxes() {
- mRawPointerAxes.clear();
-}
-
-void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
- dump.append(INDENT3 "Raw Touch Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
- dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
-}
-
-void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
- int32_t oldDeviceMode = mDeviceMode;
-
- // Determine device mode.
- if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
- && mConfig.pointerGesturesEnabled) {
- mSource = AINPUT_SOURCE_MOUSE;
- mDeviceMode = DEVICE_MODE_POINTER;
- if (hasStylus()) {
- mSource |= AINPUT_SOURCE_STYLUS;
- }
- } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
- && mParameters.hasAssociatedDisplay) {
- mSource = AINPUT_SOURCE_TOUCHSCREEN;
- mDeviceMode = DEVICE_MODE_DIRECT;
- if (hasStylus()) {
- mSource |= AINPUT_SOURCE_STYLUS;
- }
- } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
- mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
- mDeviceMode = DEVICE_MODE_NAVIGATION;
- } else {
- mSource = AINPUT_SOURCE_TOUCHPAD;
- mDeviceMode = DEVICE_MODE_UNSCALED;
- }
-
- // Ensure we have valid X and Y axes.
- if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
- ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis! "
- "The device will be inoperable.", getDeviceName().string());
- mDeviceMode = DEVICE_MODE_DISABLED;
- return;
- }
-
- // Raw width and height in the natural orientation.
- int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
- int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
-
- // Get associated display dimensions.
- bool viewportChanged = false;
- DisplayViewport newViewport;
- if (mParameters.hasAssociatedDisplay) {
- if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
- ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
- "display. The device will be inoperable until the display size "
- "becomes available.",
- getDeviceName().string());
- mDeviceMode = DEVICE_MODE_DISABLED;
- return;
- }
- } else {
- newViewport.setNonDisplayViewport(rawWidth, rawHeight);
- }
- if (mViewport != newViewport) {
- mViewport = newViewport;
- viewportChanged = true;
-
- if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
- // Convert rotated viewport to natural surface coordinates.
- int32_t naturalLogicalWidth, naturalLogicalHeight;
- int32_t naturalPhysicalWidth, naturalPhysicalHeight;
- int32_t naturalPhysicalLeft, naturalPhysicalTop;
- int32_t naturalDeviceWidth, naturalDeviceHeight;
- switch (mViewport.orientation) {
- case DISPLAY_ORIENTATION_90:
- naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
- naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
- naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
- naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
- naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
- naturalPhysicalTop = mViewport.physicalLeft;
- naturalDeviceWidth = mViewport.deviceHeight;
- naturalDeviceHeight = mViewport.deviceWidth;
- break;
- case DISPLAY_ORIENTATION_180:
- naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
- naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
- naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
- naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
- naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
- naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
- naturalDeviceWidth = mViewport.deviceWidth;
- naturalDeviceHeight = mViewport.deviceHeight;
- break;
- case DISPLAY_ORIENTATION_270:
- naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
- naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
- naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
- naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
- naturalPhysicalLeft = mViewport.physicalTop;
- naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
- naturalDeviceWidth = mViewport.deviceHeight;
- naturalDeviceHeight = mViewport.deviceWidth;
- break;
- case DISPLAY_ORIENTATION_0:
- default:
- naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
- naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
- naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
- naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
- naturalPhysicalLeft = mViewport.physicalLeft;
- naturalPhysicalTop = mViewport.physicalTop;
- naturalDeviceWidth = mViewport.deviceWidth;
- naturalDeviceHeight = mViewport.deviceHeight;
- break;
- }
-
- mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
- mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
- mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
- mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
-
- mSurfaceOrientation = mParameters.orientationAware ?
- mViewport.orientation : DISPLAY_ORIENTATION_0;
- } else {
- mSurfaceWidth = rawWidth;
- mSurfaceHeight = rawHeight;
- mSurfaceLeft = 0;
- mSurfaceTop = 0;
- mSurfaceOrientation = DISPLAY_ORIENTATION_0;
- }
- }
-
- // If moving between pointer modes, need to reset some state.
- bool deviceModeChanged = mDeviceMode != oldDeviceMode;
- if (deviceModeChanged) {
- mOrientedRanges.clear();
- }
-
- // Create pointer controller if needed.
- if (mDeviceMode == DEVICE_MODE_POINTER ||
- (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
- if (mPointerController == NULL) {
- mPointerController = getPolicy()->obtainPointerController(getDeviceId());
- }
- } else {
- mPointerController.clear();
- }
-
- if (viewportChanged || deviceModeChanged) {
- ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
- "display id %d",
- getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
- mSurfaceOrientation, mDeviceMode, mViewport.displayId);
-
- // Configure X and Y factors.
- mXScale = float(mSurfaceWidth) / rawWidth;
- mYScale = float(mSurfaceHeight) / rawHeight;
- mXTranslate = -mSurfaceLeft;
- mYTranslate = -mSurfaceTop;
- mXPrecision = 1.0f / mXScale;
- mYPrecision = 1.0f / mYScale;
-
- mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
- mOrientedRanges.x.source = mSource;
- mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
- mOrientedRanges.y.source = mSource;
-
- configureVirtualKeys();
-
- // Scale factor for terms that are not oriented in a particular axis.
- // If the pixels are square then xScale == yScale otherwise we fake it
- // by choosing an average.
- mGeometricScale = avg(mXScale, mYScale);
-
- // Size of diagonal axis.
- float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
-
- // Size factors.
- if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
- if (mRawPointerAxes.touchMajor.valid
- && mRawPointerAxes.touchMajor.maxValue != 0) {
- mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
- } else if (mRawPointerAxes.toolMajor.valid
- && mRawPointerAxes.toolMajor.maxValue != 0) {
- mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
- } else {
- mSizeScale = 0.0f;
- }
-
- mOrientedRanges.haveTouchSize = true;
- mOrientedRanges.haveToolSize = true;
- mOrientedRanges.haveSize = true;
-
- mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
- mOrientedRanges.touchMajor.source = mSource;
- mOrientedRanges.touchMajor.min = 0;
- mOrientedRanges.touchMajor.max = diagonalSize;
- mOrientedRanges.touchMajor.flat = 0;
- mOrientedRanges.touchMajor.fuzz = 0;
- mOrientedRanges.touchMajor.resolution = 0;
-
- mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
- mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
-
- mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
- mOrientedRanges.toolMajor.source = mSource;
- mOrientedRanges.toolMajor.min = 0;
- mOrientedRanges.toolMajor.max = diagonalSize;
- mOrientedRanges.toolMajor.flat = 0;
- mOrientedRanges.toolMajor.fuzz = 0;
- mOrientedRanges.toolMajor.resolution = 0;
-
- mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
- mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
-
- mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
- mOrientedRanges.size.source = mSource;
- mOrientedRanges.size.min = 0;
- mOrientedRanges.size.max = 1.0;
- mOrientedRanges.size.flat = 0;
- mOrientedRanges.size.fuzz = 0;
- mOrientedRanges.size.resolution = 0;
- } else {
- mSizeScale = 0.0f;
- }
-
- // Pressure factors.
- mPressureScale = 0;
- if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
- || mCalibration.pressureCalibration
- == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
- if (mCalibration.havePressureScale) {
- mPressureScale = mCalibration.pressureScale;
- } else if (mRawPointerAxes.pressure.valid
- && mRawPointerAxes.pressure.maxValue != 0) {
- mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
- }
- }
-
- mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
- mOrientedRanges.pressure.source = mSource;
- mOrientedRanges.pressure.min = 0;
- mOrientedRanges.pressure.max = 1.0;
- mOrientedRanges.pressure.flat = 0;
- mOrientedRanges.pressure.fuzz = 0;
- mOrientedRanges.pressure.resolution = 0;
-
- // Tilt
- mTiltXCenter = 0;
- mTiltXScale = 0;
- mTiltYCenter = 0;
- mTiltYScale = 0;
- mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
- if (mHaveTilt) {
- mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
- mRawPointerAxes.tiltX.maxValue);
- mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
- mRawPointerAxes.tiltY.maxValue);
- mTiltXScale = M_PI / 180;
- mTiltYScale = M_PI / 180;
-
- mOrientedRanges.haveTilt = true;
-
- mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
- mOrientedRanges.tilt.source = mSource;
- mOrientedRanges.tilt.min = 0;
- mOrientedRanges.tilt.max = M_PI_2;
- mOrientedRanges.tilt.flat = 0;
- mOrientedRanges.tilt.fuzz = 0;
- mOrientedRanges.tilt.resolution = 0;
- }
-
- // Orientation
- mOrientationScale = 0;
- if (mHaveTilt) {
- mOrientedRanges.haveOrientation = true;
-
- mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
- mOrientedRanges.orientation.source = mSource;
- mOrientedRanges.orientation.min = -M_PI;
- mOrientedRanges.orientation.max = M_PI;
- mOrientedRanges.orientation.flat = 0;
- mOrientedRanges.orientation.fuzz = 0;
- mOrientedRanges.orientation.resolution = 0;
- } else if (mCalibration.orientationCalibration !=
- Calibration::ORIENTATION_CALIBRATION_NONE) {
- if (mCalibration.orientationCalibration
- == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
- if (mRawPointerAxes.orientation.valid) {
- if (mRawPointerAxes.orientation.maxValue > 0) {
- mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
- } else if (mRawPointerAxes.orientation.minValue < 0) {
- mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
- } else {
- mOrientationScale = 0;
- }
- }
- }
-
- mOrientedRanges.haveOrientation = true;
-
- mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
- mOrientedRanges.orientation.source = mSource;
- mOrientedRanges.orientation.min = -M_PI_2;
- mOrientedRanges.orientation.max = M_PI_2;
- mOrientedRanges.orientation.flat = 0;
- mOrientedRanges.orientation.fuzz = 0;
- mOrientedRanges.orientation.resolution = 0;
- }
-
- // Distance
- mDistanceScale = 0;
- if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
- if (mCalibration.distanceCalibration
- == Calibration::DISTANCE_CALIBRATION_SCALED) {
- if (mCalibration.haveDistanceScale) {
- mDistanceScale = mCalibration.distanceScale;
- } else {
- mDistanceScale = 1.0f;
- }
- }
-
- mOrientedRanges.haveDistance = true;
-
- mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
- mOrientedRanges.distance.source = mSource;
- mOrientedRanges.distance.min =
- mRawPointerAxes.distance.minValue * mDistanceScale;
- mOrientedRanges.distance.max =
- mRawPointerAxes.distance.maxValue * mDistanceScale;
- mOrientedRanges.distance.flat = 0;
- mOrientedRanges.distance.fuzz =
- mRawPointerAxes.distance.fuzz * mDistanceScale;
- mOrientedRanges.distance.resolution = 0;
- }
-
- // Compute oriented precision, scales and ranges.
- // Note that the maximum value reported is an inclusive maximum value so it is one
- // unit less than the total width or height of surface.
- switch (mSurfaceOrientation) {
- case DISPLAY_ORIENTATION_90:
- case DISPLAY_ORIENTATION_270:
- mOrientedXPrecision = mYPrecision;
- mOrientedYPrecision = mXPrecision;
-
- mOrientedRanges.x.min = mYTranslate;
- mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
- mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = 0;
- mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
-
- mOrientedRanges.y.min = mXTranslate;
- mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
- mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = 0;
- mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
- break;
-
- default:
- mOrientedXPrecision = mXPrecision;
- mOrientedYPrecision = mYPrecision;
-
- mOrientedRanges.x.min = mXTranslate;
- mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
- mOrientedRanges.x.flat = 0;
- mOrientedRanges.x.fuzz = 0;
- mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
-
- mOrientedRanges.y.min = mYTranslate;
- mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
- mOrientedRanges.y.flat = 0;
- mOrientedRanges.y.fuzz = 0;
- mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
- break;
- }
-
- if (mDeviceMode == DEVICE_MODE_POINTER) {
- // Compute pointer gesture detection parameters.
- float rawDiagonal = hypotf(rawWidth, rawHeight);
- float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
-
- // Scale movements such that one whole swipe of the touch pad covers a
- // given area relative to the diagonal size of the display when no acceleration
- // is applied.
- // Assume that the touch pad has a square aspect ratio such that movements in
- // X and Y of the same number of raw units cover the same physical distance.
- mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
- * displayDiagonal / rawDiagonal;
- mPointerYMovementScale = mPointerXMovementScale;
-
- // Scale zooms to cover a smaller range of the display than movements do.
- // This value determines the area around the pointer that is affected by freeform
- // pointer gestures.
- mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
- * displayDiagonal / rawDiagonal;
- mPointerYZoomScale = mPointerXZoomScale;
-
- // Max width between pointers to detect a swipe gesture is more than some fraction
- // of the diagonal axis of the touch pad. Touches that are wider than this are
- // translated into freeform gestures.
- mPointerGestureMaxSwipeWidth =
- mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
-
- // Abort current pointer usages because the state has changed.
- abortPointerUsage(when, 0 /*policyFlags*/);
- }
-
- // Inform the dispatcher about the changes.
- *outResetNeeded = true;
- bumpGeneration();
- }
-}
-
-void TouchInputMapper::dumpSurface(String8& dump) {
- dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
- "logicalFrame=[%d, %d, %d, %d], "
- "physicalFrame=[%d, %d, %d, %d], "
- "deviceSize=[%d, %d]\n",
- mViewport.displayId, mViewport.orientation,
- mViewport.logicalLeft, mViewport.logicalTop,
- mViewport.logicalRight, mViewport.logicalBottom,
- mViewport.physicalLeft, mViewport.physicalTop,
- mViewport.physicalRight, mViewport.physicalBottom,
- mViewport.deviceWidth, mViewport.deviceHeight);
-
- dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
- dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
- dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
- dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
- dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
-}
-
-void TouchInputMapper::configureVirtualKeys() {
- Vector<VirtualKeyDefinition> virtualKeyDefinitions;
- getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
-
- mVirtualKeys.clear();
-
- if (virtualKeyDefinitions.size() == 0) {
- return;
- }
-
- mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
-
- int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
- int32_t touchScreenTop = mRawPointerAxes.y.minValue;
- int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
- int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
-
- for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
- const VirtualKeyDefinition& virtualKeyDefinition =
- virtualKeyDefinitions[i];
-
- mVirtualKeys.add();
- VirtualKey& virtualKey = mVirtualKeys.editTop();
-
- virtualKey.scanCode = virtualKeyDefinition.scanCode;
- int32_t keyCode;
- uint32_t flags;
- if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
- ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
- virtualKey.scanCode);
- mVirtualKeys.pop(); // drop the key
- continue;
- }
-
- virtualKey.keyCode = keyCode;
- virtualKey.flags = flags;
-
- // convert the key definition's display coordinates into touch coordinates for a hit box
- int32_t halfWidth = virtualKeyDefinition.width / 2;
- int32_t halfHeight = virtualKeyDefinition.height / 2;
-
- virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
- virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
- virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mSurfaceHeight + touchScreenTop;
- }
-}
-
-void TouchInputMapper::dumpVirtualKeys(String8& dump) {
- if (!mVirtualKeys.isEmpty()) {
- dump.append(INDENT3 "Virtual Keys:\n");
-
- for (size_t i = 0; i < mVirtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
- dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
- "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
- i, virtualKey.scanCode, virtualKey.keyCode,
- virtualKey.hitLeft, virtualKey.hitRight,
- virtualKey.hitTop, virtualKey.hitBottom);
- }
- }
-}
-
-void TouchInputMapper::parseCalibration() {
- const PropertyMap& in = getDevice()->getConfiguration();
- Calibration& out = mCalibration;
-
- // Size
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
- String8 sizeCalibrationString;
- if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
- if (sizeCalibrationString == "none") {
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
- } else if (sizeCalibrationString == "geometric") {
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
- } else if (sizeCalibrationString == "diameter") {
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
- } else if (sizeCalibrationString == "box") {
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
- } else if (sizeCalibrationString == "area") {
- out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
- } else if (sizeCalibrationString != "default") {
- ALOGW("Invalid value for touch.size.calibration: '%s'",
- sizeCalibrationString.string());
- }
- }
-
- out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
- out.sizeScale);
- out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
- out.sizeBias);
- out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
- out.sizeIsSummed);
-
- // Pressure
- out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
- String8 pressureCalibrationString;
- if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
- if (pressureCalibrationString == "none") {
- out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
- } else if (pressureCalibrationString == "physical") {
- out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
- } else if (pressureCalibrationString == "amplitude") {
- out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
- } else if (pressureCalibrationString != "default") {
- ALOGW("Invalid value for touch.pressure.calibration: '%s'",
- pressureCalibrationString.string());
- }
- }
-
- out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
- out.pressureScale);
-
- // Orientation
- out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
- String8 orientationCalibrationString;
- if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
- if (orientationCalibrationString == "none") {
- out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
- } else if (orientationCalibrationString == "interpolated") {
- out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
- } else if (orientationCalibrationString == "vector") {
- out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
- } else if (orientationCalibrationString != "default") {
- ALOGW("Invalid value for touch.orientation.calibration: '%s'",
- orientationCalibrationString.string());
- }
- }
-
- // Distance
- out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
- String8 distanceCalibrationString;
- if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
- if (distanceCalibrationString == "none") {
- out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
- } else if (distanceCalibrationString == "scaled") {
- out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
- } else if (distanceCalibrationString != "default") {
- ALOGW("Invalid value for touch.distance.calibration: '%s'",
- distanceCalibrationString.string());
- }
- }
-
- out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
- out.distanceScale);
-
- out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
- String8 coverageCalibrationString;
- if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
- if (coverageCalibrationString == "none") {
- out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
- } else if (coverageCalibrationString == "box") {
- out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
- } else if (coverageCalibrationString != "default") {
- ALOGW("Invalid value for touch.coverage.calibration: '%s'",
- coverageCalibrationString.string());
- }
- }
-}
-
-void TouchInputMapper::resolveCalibration() {
- // Size
- if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
- if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
- mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
- }
- } else {
- mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
- }
-
- // Pressure
- if (mRawPointerAxes.pressure.valid) {
- if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
- mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
- }
- } else {
- mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
- }
-
- // Orientation
- if (mRawPointerAxes.orientation.valid) {
- if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
- mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
- }
- } else {
- mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
- }
-
- // Distance
- if (mRawPointerAxes.distance.valid) {
- if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
- mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
- }
- } else {
- mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
- }
-
- // Coverage
- if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
- mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
- }
-}
-
-void TouchInputMapper::dumpCalibration(String8& dump) {
- dump.append(INDENT3 "Calibration:\n");
-
- // Size
- switch (mCalibration.sizeCalibration) {
- case Calibration::SIZE_CALIBRATION_NONE:
- dump.append(INDENT4 "touch.size.calibration: none\n");
- break;
- case Calibration::SIZE_CALIBRATION_GEOMETRIC:
- dump.append(INDENT4 "touch.size.calibration: geometric\n");
- break;
- case Calibration::SIZE_CALIBRATION_DIAMETER:
- dump.append(INDENT4 "touch.size.calibration: diameter\n");
- break;
- case Calibration::SIZE_CALIBRATION_BOX:
- dump.append(INDENT4 "touch.size.calibration: box\n");
- break;
- case Calibration::SIZE_CALIBRATION_AREA:
- dump.append(INDENT4 "touch.size.calibration: area\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- if (mCalibration.haveSizeScale) {
- dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
- mCalibration.sizeScale);
- }
-
- if (mCalibration.haveSizeBias) {
- dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
- mCalibration.sizeBias);
- }
-
- if (mCalibration.haveSizeIsSummed) {
- dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
- toString(mCalibration.sizeIsSummed));
- }
-
- // Pressure
- switch (mCalibration.pressureCalibration) {
- case Calibration::PRESSURE_CALIBRATION_NONE:
- dump.append(INDENT4 "touch.pressure.calibration: none\n");
- break;
- case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
- dump.append(INDENT4 "touch.pressure.calibration: physical\n");
- break;
- case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
- dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- if (mCalibration.havePressureScale) {
- dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
- mCalibration.pressureScale);
- }
-
- // Orientation
- switch (mCalibration.orientationCalibration) {
- case Calibration::ORIENTATION_CALIBRATION_NONE:
- dump.append(INDENT4 "touch.orientation.calibration: none\n");
- break;
- case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
- dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
- break;
- case Calibration::ORIENTATION_CALIBRATION_VECTOR:
- dump.append(INDENT4 "touch.orientation.calibration: vector\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- // Distance
- switch (mCalibration.distanceCalibration) {
- case Calibration::DISTANCE_CALIBRATION_NONE:
- dump.append(INDENT4 "touch.distance.calibration: none\n");
- break;
- case Calibration::DISTANCE_CALIBRATION_SCALED:
- dump.append(INDENT4 "touch.distance.calibration: scaled\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-
- if (mCalibration.haveDistanceScale) {
- dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
- mCalibration.distanceScale);
- }
-
- switch (mCalibration.coverageCalibration) {
- case Calibration::COVERAGE_CALIBRATION_NONE:
- dump.append(INDENT4 "touch.coverage.calibration: none\n");
- break;
- case Calibration::COVERAGE_CALIBRATION_BOX:
- dump.append(INDENT4 "touch.coverage.calibration: box\n");
- break;
- default:
- ALOG_ASSERT(false);
- }
-}
-
-void TouchInputMapper::reset(nsecs_t when) {
- mCursorButtonAccumulator.reset(getDevice());
- mCursorScrollAccumulator.reset(getDevice());
- mTouchButtonAccumulator.reset(getDevice());
-
- mPointerVelocityControl.reset();
- mWheelXVelocityControl.reset();
- mWheelYVelocityControl.reset();
-
- mCurrentRawPointerData.clear();
- mLastRawPointerData.clear();
- mCurrentCookedPointerData.clear();
- mLastCookedPointerData.clear();
- mCurrentButtonState = 0;
- mLastButtonState = 0;
- mCurrentRawVScroll = 0;
- mCurrentRawHScroll = 0;
- mCurrentFingerIdBits.clear();
- mLastFingerIdBits.clear();
- mCurrentStylusIdBits.clear();
- mLastStylusIdBits.clear();
- mCurrentMouseIdBits.clear();
- mLastMouseIdBits.clear();
- mPointerUsage = POINTER_USAGE_NONE;
- mSentHoverEnter = false;
- mDownTime = 0;
-
- mCurrentVirtualKey.down = false;
-
- mPointerGesture.reset();
- mPointerSimple.reset();
-
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- mPointerController->clearSpots();
- }
-
- InputMapper::reset(when);
-}
-
-void TouchInputMapper::process(const RawEvent* rawEvent) {
- mCursorButtonAccumulator.process(rawEvent);
- mCursorScrollAccumulator.process(rawEvent);
- mTouchButtonAccumulator.process(rawEvent);
-
- if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
- sync(rawEvent->when);
- }
-}
-
-void TouchInputMapper::sync(nsecs_t when) {
- // Sync button state.
- mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
- | mCursorButtonAccumulator.getButtonState();
-
- // Sync scroll state.
- mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
- mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
- mCursorScrollAccumulator.finishSync();
-
- // Sync touch state.
- bool havePointerIds = true;
- mCurrentRawPointerData.clear();
- syncTouch(when, &havePointerIds);
-
-#if DEBUG_RAW_EVENTS
- if (!havePointerIds) {
- ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
- mLastRawPointerData.pointerCount,
- mCurrentRawPointerData.pointerCount);
- } else {
- ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
- "hovering ids 0x%08x -> 0x%08x",
- mLastRawPointerData.pointerCount,
- mCurrentRawPointerData.pointerCount,
- mLastRawPointerData.touchingIdBits.value,
- mCurrentRawPointerData.touchingIdBits.value,
- mLastRawPointerData.hoveringIdBits.value,
- mCurrentRawPointerData.hoveringIdBits.value);
- }
-#endif
-
- // Reset state that we will compute below.
- mCurrentFingerIdBits.clear();
- mCurrentStylusIdBits.clear();
- mCurrentMouseIdBits.clear();
- mCurrentCookedPointerData.clear();
-
- if (mDeviceMode == DEVICE_MODE_DISABLED) {
- // Drop all input if the device is disabled.
- mCurrentRawPointerData.clear();
- mCurrentButtonState = 0;
- } else {
- // Preprocess pointer data.
- if (!havePointerIds) {
- assignPointerIds();
- }
-
- // Handle policy on initial down or hover events.
- uint32_t policyFlags = 0;
- bool initialDown = mLastRawPointerData.pointerCount == 0
- && mCurrentRawPointerData.pointerCount != 0;
- bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
- if (initialDown || buttonsPressed) {
- // If this is a touch screen, hide the pointer on an initial down.
- if (mDeviceMode == DEVICE_MODE_DIRECT) {
- getContext()->fadePointer();
- }
-
- // Initial downs on external touch devices should wake the device.
- // We don't do this for internal touch screens to prevent them from waking
- // up in your pocket.
- // TODO: Use the input device configuration to control this behavior more finely.
- if (getDevice()->isExternal()) {
- policyFlags |= POLICY_FLAG_WAKE_DROPPED;
- }
- }
-
- // Synthesize key down from raw buttons if needed.
- synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
- policyFlags, mLastButtonState, mCurrentButtonState);
-
- // Consume raw off-screen touches before cooking pointer data.
- // If touches are consumed, subsequent code will not receive any pointer data.
- if (consumeRawTouches(when, policyFlags)) {
- mCurrentRawPointerData.clear();
- }
-
- // Cook pointer data. This call populates the mCurrentCookedPointerData structure
- // with cooked pointer data that has the same ids and indices as the raw data.
- // The following code can use either the raw or cooked data, as needed.
- cookPointerData();
-
- // Dispatch the touches either directly or by translation through a pointer on screen.
- if (mDeviceMode == DEVICE_MODE_POINTER) {
- for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
- if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
- || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
- mCurrentStylusIdBits.markBit(id);
- } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
- || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- mCurrentFingerIdBits.markBit(id);
- } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
- mCurrentMouseIdBits.markBit(id);
- }
- }
- for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
- if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
- || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
- mCurrentStylusIdBits.markBit(id);
- }
- }
-
- // Stylus takes precedence over all tools, then mouse, then finger.
- PointerUsage pointerUsage = mPointerUsage;
- if (!mCurrentStylusIdBits.isEmpty()) {
- mCurrentMouseIdBits.clear();
- mCurrentFingerIdBits.clear();
- pointerUsage = POINTER_USAGE_STYLUS;
- } else if (!mCurrentMouseIdBits.isEmpty()) {
- mCurrentFingerIdBits.clear();
- pointerUsage = POINTER_USAGE_MOUSE;
- } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
- pointerUsage = POINTER_USAGE_GESTURES;
- }
-
- dispatchPointerUsage(when, policyFlags, pointerUsage);
- } else {
- if (mDeviceMode == DEVICE_MODE_DIRECT
- && mConfig.showTouches && mPointerController != NULL) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-
- mPointerController->setButtonState(mCurrentButtonState);
- mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- mCurrentCookedPointerData.touchingIdBits);
- }
-
- dispatchHoverExit(when, policyFlags);
- dispatchTouches(when, policyFlags);
- dispatchHoverEnterAndMove(when, policyFlags);
- }
-
- // Synthesize key up from raw buttons if needed.
- synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
- policyFlags, mLastButtonState, mCurrentButtonState);
- }
-
- // Copy current touch to last touch in preparation for the next cycle.
- mLastRawPointerData.copyFrom(mCurrentRawPointerData);
- mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
- mLastButtonState = mCurrentButtonState;
- mLastFingerIdBits = mCurrentFingerIdBits;
- mLastStylusIdBits = mCurrentStylusIdBits;
- mLastMouseIdBits = mCurrentMouseIdBits;
-
- // Clear some transient state.
- mCurrentRawVScroll = 0;
- mCurrentRawHScroll = 0;
-}
-
-void TouchInputMapper::timeoutExpired(nsecs_t when) {
- if (mDeviceMode == DEVICE_MODE_POINTER) {
- if (mPointerUsage == POINTER_USAGE_GESTURES) {
- dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
- }
- }
-}
-
-bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
- // Check for release of a virtual key.
- if (mCurrentVirtualKey.down) {
- if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
- // Pointer went up while virtual key was down.
- mCurrentVirtualKey.down = false;
- if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
- ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
- mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
-#endif
- dispatchVirtualKey(when, policyFlags,
- AKEY_EVENT_ACTION_UP,
- AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
- }
- return true;
- }
-
- if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
- uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
- const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
- if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
- // Pointer is still within the space of the virtual key.
- return true;
- }
- }
-
- // Pointer left virtual key area or another pointer also went down.
- // Send key cancellation but do not consume the touch yet.
- // This is useful when the user swipes through from the virtual key area
- // into the main display surface.
- mCurrentVirtualKey.down = false;
- if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
- ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
- mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
-#endif
- dispatchVirtualKey(when, policyFlags,
- AKEY_EVENT_ACTION_UP,
- AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
- | AKEY_EVENT_FLAG_CANCELED);
- }
- }
-
- if (mLastRawPointerData.touchingIdBits.isEmpty()
- && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
- // Pointer just went down. Check for virtual key press or off-screen touches.
- uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
- if (!isPointInsideSurface(pointer.x, pointer.y)) {
- // If exactly one pointer went down, check for virtual key hit.
- // Otherwise we will drop the entire stroke.
- if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
- if (virtualKey) {
- mCurrentVirtualKey.down = true;
- mCurrentVirtualKey.downTime = when;
- mCurrentVirtualKey.keyCode = virtualKey->keyCode;
- mCurrentVirtualKey.scanCode = virtualKey->scanCode;
- mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
- when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
-
- if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
- ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
- mCurrentVirtualKey.keyCode,
- mCurrentVirtualKey.scanCode);
-#endif
- dispatchVirtualKey(when, policyFlags,
- AKEY_EVENT_ACTION_DOWN,
- AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
- }
- }
- }
- return true;
- }
- }
-
- // Disable all virtual key touches that happen within a short time interval of the
- // most recent touch within the screen area. The idea is to filter out stray
- // virtual key presses when interacting with the touch screen.
- //
- // Problems we're trying to solve:
- //
- // 1. While scrolling a list or dragging the window shade, the user swipes down into a
- // virtual key area that is implemented by a separate touch panel and accidentally
- // triggers a virtual key.
- //
- // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
- // area and accidentally triggers a virtual key. This often happens when virtual keys
- // are layed out below the screen near to where the on screen keyboard's space bar
- // is displayed.
- if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
- mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
- }
- return false;
-}
-
-void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
- int32_t keyEventAction, int32_t keyEventFlags) {
- int32_t keyCode = mCurrentVirtualKey.keyCode;
- int32_t scanCode = mCurrentVirtualKey.scanCode;
- nsecs_t downTime = mCurrentVirtualKey.downTime;
- int32_t metaState = mContext->getGlobalMetaState();
- policyFlags |= POLICY_FLAG_VIRTUAL;
-
- NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
- getListener()->notifyKey(&args);
-}
-
-void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
- BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
- BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
- int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentButtonState;
-
- if (currentIdBits == lastIdBits) {
- if (!currentIdBits.isEmpty()) {
- // No pointer id changes so this is a move event.
- // The listener takes care of batching moves so we don't have to deal with that here.
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- currentIdBits, -1,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- }
- } else {
- // There may be pointers going up and pointers going down and pointers moving
- // all at the same time.
- BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
- BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
- BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
- BitSet32 dispatchedIdBits(lastIdBits.value);
-
- // Update last coordinates of pointers that have moved so that we observe the new
- // pointer positions at the same time as other pointers that have just gone up.
- bool moveNeeded = updateMovedPointers(
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- mLastCookedPointerData.pointerProperties,
- mLastCookedPointerData.pointerCoords,
- mLastCookedPointerData.idToIndex,
- moveIdBits);
- if (buttonState != mLastButtonState) {
- moveNeeded = true;
- }
-
- // Dispatch pointer up events.
- while (!upIdBits.isEmpty()) {
- uint32_t upId = upIdBits.clearFirstMarkedBit();
-
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
- mLastCookedPointerData.pointerProperties,
- mLastCookedPointerData.pointerCoords,
- mLastCookedPointerData.idToIndex,
- dispatchedIdBits, upId,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- dispatchedIdBits.clearBit(upId);
- }
-
- // Dispatch move events if any of the remaining pointers moved from their old locations.
- // Although applications receive new locations as part of individual pointer up
- // events, they do not generally handle them except when presented in a move event.
- if (moveNeeded) {
- ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- dispatchedIdBits, -1,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- }
-
- // Dispatch pointer down events using the new pointer locations.
- while (!downIdBits.isEmpty()) {
- uint32_t downId = downIdBits.clearFirstMarkedBit();
- dispatchedIdBits.markBit(downId);
-
- if (dispatchedIdBits.count() == 1) {
- // First pointer is going down. Set down time.
- mDownTime = when;
- }
-
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- dispatchedIdBits, downId,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- }
- }
-}
-
-void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
- if (mSentHoverEnter &&
- (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
- || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
- int32_t metaState = getContext()->getGlobalMetaState();
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
- mLastCookedPointerData.pointerProperties,
- mLastCookedPointerData.pointerCoords,
- mLastCookedPointerData.idToIndex,
- mLastCookedPointerData.hoveringIdBits, -1,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- mSentHoverEnter = false;
- }
-}
-
-void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
- if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
- && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
- int32_t metaState = getContext()->getGlobalMetaState();
- if (!mSentHoverEnter) {
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- mCurrentCookedPointerData.hoveringIdBits, -1,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- mSentHoverEnter = true;
- }
-
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
- mCurrentCookedPointerData.pointerProperties,
- mCurrentCookedPointerData.pointerCoords,
- mCurrentCookedPointerData.idToIndex,
- mCurrentCookedPointerData.hoveringIdBits, -1,
- mOrientedXPrecision, mOrientedYPrecision, mDownTime);
- }
-}
-
-void TouchInputMapper::cookPointerData() {
- uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
-
- mCurrentCookedPointerData.clear();
- mCurrentCookedPointerData.pointerCount = currentPointerCount;
- mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
- mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
-
- // Walk through the the active pointers and map device coordinates onto
- // surface coordinates and adjust for display orientation.
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
-
- // Size
- float touchMajor, touchMinor, toolMajor, toolMinor, size;
- switch (mCalibration.sizeCalibration) {
- case Calibration::SIZE_CALIBRATION_GEOMETRIC:
- case Calibration::SIZE_CALIBRATION_DIAMETER:
- case Calibration::SIZE_CALIBRATION_BOX:
- case Calibration::SIZE_CALIBRATION_AREA:
- if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
- touchMajor = in.touchMajor;
- touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
- toolMajor = in.toolMajor;
- toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
- size = mRawPointerAxes.touchMinor.valid
- ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
- } else if (mRawPointerAxes.touchMajor.valid) {
- toolMajor = touchMajor = in.touchMajor;
- toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
- ? in.touchMinor : in.touchMajor;
- size = mRawPointerAxes.touchMinor.valid
- ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
- } else if (mRawPointerAxes.toolMajor.valid) {
- touchMajor = toolMajor = in.toolMajor;
- touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
- ? in.toolMinor : in.toolMajor;
- size = mRawPointerAxes.toolMinor.valid
- ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
- } else {
- ALOG_ASSERT(false, "No touch or tool axes. "
- "Size calibration should have been resolved to NONE.");
- touchMajor = 0;
- touchMinor = 0;
- toolMajor = 0;
- toolMinor = 0;
- size = 0;
- }
-
- if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
- uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
- if (touchingCount > 1) {
- touchMajor /= touchingCount;
- touchMinor /= touchingCount;
- toolMajor /= touchingCount;
- toolMinor /= touchingCount;
- size /= touchingCount;
- }
- }
-
- if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
- touchMajor *= mGeometricScale;
- touchMinor *= mGeometricScale;
- toolMajor *= mGeometricScale;
- toolMinor *= mGeometricScale;
- } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
- touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
- touchMinor = touchMajor;
- toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
- toolMinor = toolMajor;
- } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
- touchMinor = touchMajor;
- toolMinor = toolMajor;
- }
-
- mCalibration.applySizeScaleAndBias(&touchMajor);
- mCalibration.applySizeScaleAndBias(&touchMinor);
- mCalibration.applySizeScaleAndBias(&toolMajor);
- mCalibration.applySizeScaleAndBias(&toolMinor);
- size *= mSizeScale;
- break;
- default:
- touchMajor = 0;
- touchMinor = 0;
- toolMajor = 0;
- toolMinor = 0;
- size = 0;
- break;
- }
-
- // Pressure
- float pressure;
- switch (mCalibration.pressureCalibration) {
- case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
- case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
- pressure = in.pressure * mPressureScale;
- break;
- default:
- pressure = in.isHovering ? 0 : 1;
- break;
- }
-
- // Tilt and Orientation
- float tilt;
- float orientation;
- if (mHaveTilt) {
- float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
- float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
- orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
- tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
- } else {
- tilt = 0;
-
- switch (mCalibration.orientationCalibration) {
- case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
- orientation = in.orientation * mOrientationScale;
- break;
- case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
- int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
- int32_t c2 = signExtendNybble(in.orientation & 0x0f);
- if (c1 != 0 || c2 != 0) {
- orientation = atan2f(c1, c2) * 0.5f;
- float confidence = hypotf(c1, c2);
- float scale = 1.0f + confidence / 16.0f;
- touchMajor *= scale;
- touchMinor /= scale;
- toolMajor *= scale;
- toolMinor /= scale;
- } else {
- orientation = 0;
- }
- break;
- }
- default:
- orientation = 0;
- }
- }
-
- // Distance
- float distance;
- switch (mCalibration.distanceCalibration) {
- case Calibration::DISTANCE_CALIBRATION_SCALED:
- distance = in.distance * mDistanceScale;
- break;
- default:
- distance = 0;
- }
-
- // Coverage
- int32_t rawLeft, rawTop, rawRight, rawBottom;
- switch (mCalibration.coverageCalibration) {
- case Calibration::COVERAGE_CALIBRATION_BOX:
- rawLeft = (in.toolMinor & 0xffff0000) >> 16;
- rawRight = in.toolMinor & 0x0000ffff;
- rawBottom = in.toolMajor & 0x0000ffff;
- rawTop = (in.toolMajor & 0xffff0000) >> 16;
- break;
- default:
- rawLeft = rawTop = rawRight = rawBottom = 0;
- break;
- }
-
- // X, Y, and the bounding box for coverage information
- // Adjust coords for surface orientation.
- float x, y, left, top, right, bottom;
- switch (mSurfaceOrientation) {
- case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
- left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
- top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
- orientation -= M_PI_2;
- if (orientation < - M_PI_2) {
- orientation += M_PI;
- }
- break;
- case DISPLAY_ORIENTATION_180:
- x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
- y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
- left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
- right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
- bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
- top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
- break;
- case DISPLAY_ORIENTATION_270:
- x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
- y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
- right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
- bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- orientation += M_PI_2;
- if (orientation > M_PI_2) {
- orientation -= M_PI;
- }
- break;
- default:
- x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
- bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
- break;
- }
-
- // Write output coords.
- PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
- out.clear();
- out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
- out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
- out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
- out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
- out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
- out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
- out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
- if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
- out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
- out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
- out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
- out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
- } else {
- out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
- out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
- }
-
- // Write output properties.
- PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
- uint32_t id = in.id;
- properties.clear();
- properties.id = id;
- properties.toolType = in.toolType;
-
- // Write id index.
- mCurrentCookedPointerData.idToIndex[id] = i;
- }
-}
-
-void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
- PointerUsage pointerUsage) {
- if (pointerUsage != mPointerUsage) {
- abortPointerUsage(when, policyFlags);
- mPointerUsage = pointerUsage;
- }
-
- switch (mPointerUsage) {
- case POINTER_USAGE_GESTURES:
- dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
- break;
- case POINTER_USAGE_STYLUS:
- dispatchPointerStylus(when, policyFlags);
- break;
- case POINTER_USAGE_MOUSE:
- dispatchPointerMouse(when, policyFlags);
- break;
- default:
- break;
- }
-}
-
-void TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
- switch (mPointerUsage) {
- case POINTER_USAGE_GESTURES:
- abortPointerGestures(when, policyFlags);
- break;
- case POINTER_USAGE_STYLUS:
- abortPointerStylus(when, policyFlags);
- break;
- case POINTER_USAGE_MOUSE:
- abortPointerMouse(when, policyFlags);
- break;
- default:
- break;
- }
-
- mPointerUsage = POINTER_USAGE_NONE;
-}
-
-void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
- bool isTimeout) {
- // Update current gesture coordinates.
- bool cancelPreviousGesture, finishPreviousGesture;
- bool sendEvents = preparePointerGestures(when,
- &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
- if (!sendEvents) {
- return;
- }
- if (finishPreviousGesture) {
- cancelPreviousGesture = false;
- }
-
- // Update the pointer presentation and spots.
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
- if (finishPreviousGesture || cancelPreviousGesture) {
- mPointerController->clearSpots();
- }
- mPointerController->setSpots(mPointerGesture.currentGestureCoords,
- mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.currentGestureIdBits);
- } else {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
- }
-
- // Show or hide the pointer if needed.
- switch (mPointerGesture.currentGestureMode) {
- case PointerGesture::NEUTRAL:
- case PointerGesture::QUIET:
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
- && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
- || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
- // Remind the user of where the pointer is after finishing a gesture with spots.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- break;
- case PointerGesture::TAP:
- case PointerGesture::TAP_DRAG:
- case PointerGesture::BUTTON_CLICK_OR_DRAG:
- case PointerGesture::HOVER:
- case PointerGesture::PRESS:
- // Unfade the pointer when the current gesture manipulates the
- // area directly under the pointer.
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- break;
- case PointerGesture::SWIPE:
- case PointerGesture::FREEFORM:
- // Fade the pointer when the current gesture manipulates a different
- // area and there are spots to guide the user experience.
- if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- } else {
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- }
- break;
- }
-
- // Send events!
- int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentButtonState;
-
- // Update last coordinates of pointers that have moved so that we observe the new
- // pointer positions at the same time as other pointers that have just gone up.
- bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
- || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
- || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
- || mPointerGesture.currentGestureMode == PointerGesture::PRESS
- || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
- || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
- bool moveNeeded = false;
- if (down && !cancelPreviousGesture && !finishPreviousGesture
- && !mPointerGesture.lastGestureIdBits.isEmpty()
- && !mPointerGesture.currentGestureIdBits.isEmpty()) {
- BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
- & mPointerGesture.lastGestureIdBits.value);
- moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.lastGestureProperties,
- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
- movedGestureIdBits);
- if (buttonState != mLastButtonState) {
- moveNeeded = true;
- }
- }
-
- // Send motion events for all pointers that went up or were canceled.
- BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
- if (!dispatchedGestureIdBits.isEmpty()) {
- if (cancelPreviousGesture) {
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.lastGestureProperties,
- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
- dispatchedGestureIdBits, -1,
- 0, 0, mPointerGesture.downTime);
-
- dispatchedGestureIdBits.clear();
- } else {
- BitSet32 upGestureIdBits;
- if (finishPreviousGesture) {
- upGestureIdBits = dispatchedGestureIdBits;
- } else {
- upGestureIdBits.value = dispatchedGestureIdBits.value
- & ~mPointerGesture.currentGestureIdBits.value;
- }
- while (!upGestureIdBits.isEmpty()) {
- uint32_t id = upGestureIdBits.clearFirstMarkedBit();
-
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_UP, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.lastGestureProperties,
- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
- dispatchedGestureIdBits, id,
- 0, 0, mPointerGesture.downTime);
-
- dispatchedGestureIdBits.clearBit(id);
- }
- }
- }
-
- // Send motion events for all pointers that moved.
- if (moveNeeded) {
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.currentGestureProperties,
- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
- dispatchedGestureIdBits, -1,
- 0, 0, mPointerGesture.downTime);
- }
-
- // Send motion events for all pointers that went down.
- if (down) {
- BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
- & ~dispatchedGestureIdBits.value);
- while (!downGestureIdBits.isEmpty()) {
- uint32_t id = downGestureIdBits.clearFirstMarkedBit();
- dispatchedGestureIdBits.markBit(id);
-
- if (dispatchedGestureIdBits.count() == 1) {
- mPointerGesture.downTime = when;
- }
-
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
- mPointerGesture.currentGestureProperties,
- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
- dispatchedGestureIdBits, id,
- 0, 0, mPointerGesture.downTime);
- }
- }
-
- // Send motion events for hover.
- if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.currentGestureProperties,
- mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.currentGestureIdBits, -1,
- 0, 0, mPointerGesture.downTime);
- } else if (dispatchedGestureIdBits.isEmpty()
- && !mPointerGesture.lastGestureIdBits.isEmpty()) {
- // Synthesize a hover move event after all pointers go up to indicate that
- // the pointer is hovering again even if the user is not currently touching
- // the touch pad. This ensures that a view will receive a fresh hover enter
- // event after a tap.
- float x, y;
- mPointerController->getPosition(&x, &y);
-
- PointerProperties pointerProperties;
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-
- PointerCoords pointerCoords;
- pointerCoords.clear();
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- mViewport.displayId, 1, &pointerProperties, &pointerCoords,
- 0, 0, mPointerGesture.downTime);
- getListener()->notifyMotion(&args);
- }
-
- // Update state.
- mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
- if (!down) {
- mPointerGesture.lastGestureIdBits.clear();
- } else {
- mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
- for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
- mPointerGesture.lastGestureProperties[index].copyFrom(
- mPointerGesture.currentGestureProperties[index]);
- mPointerGesture.lastGestureCoords[index].copyFrom(
- mPointerGesture.currentGestureCoords[index]);
- mPointerGesture.lastGestureIdToIndex[id] = index;
- }
- }
-}
-
-void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
- // Cancel previously dispatches pointers.
- if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
- int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentButtonState;
- dispatchMotion(when, policyFlags, mSource,
- AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mPointerGesture.lastGestureProperties,
- mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
- mPointerGesture.lastGestureIdBits, -1,
- 0, 0, mPointerGesture.downTime);
- }
-
- // Reset the current pointer gesture.
- mPointerGesture.reset();
- mPointerVelocityControl.reset();
-
- // Remove any current spots.
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- mPointerController->clearSpots();
- }
-}
-
-bool TouchInputMapper::preparePointerGestures(nsecs_t when,
- bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
- *outCancelPreviousGesture = false;
- *outFinishPreviousGesture = false;
-
- // Handle TAP timeout.
- if (isTimeout) {
-#if DEBUG_GESTURES
- ALOGD("Gestures: Processing timeout");
-#endif
-
- if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
- if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
- // The tap/drag timeout has not yet expired.
- getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
- + mConfig.pointerGestureTapDragInterval);
- } else {
- // The tap is finished.
-#if DEBUG_GESTURES
- ALOGD("Gestures: TAP finished");
-#endif
- *outFinishPreviousGesture = true;
-
- mPointerGesture.activeGestureId = -1;
- mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
- mPointerGesture.currentGestureIdBits.clear();
-
- mPointerVelocityControl.reset();
- return true;
- }
- }
-
- // We did not handle this timeout.
- return false;
- }
-
- const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
- const uint32_t lastFingerCount = mLastFingerIdBits.count();
-
- // Update the velocity tracker.
- {
- VelocityTracker::Position positions[MAX_POINTERS];
- uint32_t count = 0;
- for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
- uint32_t id = idBits.clearFirstMarkedBit();
- const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
- positions[count].x = pointer.x * mPointerXMovementScale;
- positions[count].y = pointer.y * mPointerYMovementScale;
- }
- mPointerGesture.velocityTracker.addMovement(when,
- mCurrentFingerIdBits, positions);
- }
-
- // Pick a new active touch id if needed.
- // Choose an arbitrary pointer that just went down, if there is one.
- // Otherwise choose an arbitrary remaining pointer.
- // This guarantees we always have an active touch id when there is at least one pointer.
- // We keep the same active touch id for as long as possible.
- int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
- int32_t activeTouchId = lastActiveTouchId;
- if (activeTouchId < 0) {
- if (!mCurrentFingerIdBits.isEmpty()) {
- activeTouchId = mPointerGesture.activeTouchId =
- mCurrentFingerIdBits.firstMarkedBit();
- mPointerGesture.firstTouchTime = when;
- }
- } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
- if (!mCurrentFingerIdBits.isEmpty()) {
- activeTouchId = mPointerGesture.activeTouchId =
- mCurrentFingerIdBits.firstMarkedBit();
- } else {
- activeTouchId = mPointerGesture.activeTouchId = -1;
- }
- }
-
- // Determine whether we are in quiet time.
- bool isQuietTime = false;
- if (activeTouchId < 0) {
- mPointerGesture.resetQuietTime();
- } else {
- isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
- if (!isQuietTime) {
- if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
- || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
- || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
- && currentFingerCount < 2) {
- // Enter quiet time when exiting swipe or freeform state.
- // This is to prevent accidentally entering the hover state and flinging the
- // pointer when finishing a swipe and there is still one pointer left onscreen.
- isQuietTime = true;
- } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
- && currentFingerCount >= 2
- && !isPointerDown(mCurrentButtonState)) {
- // Enter quiet time when releasing the button and there are still two or more
- // fingers down. This may indicate that one finger was used to press the button
- // but it has not gone up yet.
- isQuietTime = true;
- }
- if (isQuietTime) {
- mPointerGesture.quietTime = when;
- }
- }
- }
-
- // Switch states based on button and pointer state.
- if (isQuietTime) {
- // Case 1: Quiet time. (QUIET)
-#if DEBUG_GESTURES
- ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
- + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
-#endif
- if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
- *outFinishPreviousGesture = true;
- }
-
- mPointerGesture.activeGestureId = -1;
- mPointerGesture.currentGestureMode = PointerGesture::QUIET;
- mPointerGesture.currentGestureIdBits.clear();
-
- mPointerVelocityControl.reset();
- } else if (isPointerDown(mCurrentButtonState)) {
- // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
- // The pointer follows the active touch point.
- // Emit DOWN, MOVE, UP events at the pointer location.
- //
- // Only the active touch matters; other fingers are ignored. This policy helps
- // to handle the case where the user places a second finger on the touch pad
- // to apply the necessary force to depress an integrated button below the surface.
- // We don't want the second finger to be delivered to applications.
- //
- // For this to work well, we need to make sure to track the pointer that is really
- // active. If the user first puts one finger down to click then adds another
- // finger to drag then the active pointer should switch to the finger that is
- // being dragged.
-#if DEBUG_GESTURES
- ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
- "currentFingerCount=%d", activeTouchId, currentFingerCount);
-#endif
- // Reset state when just starting.
- if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
- *outFinishPreviousGesture = true;
- mPointerGesture.activeGestureId = 0;
- }
-
- // Switch pointers if needed.
- // Find the fastest pointer and follow it.
- if (activeTouchId >= 0 && currentFingerCount > 1) {
- int32_t bestId = -1;
- float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
- for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- float vx, vy;
- if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
- float speed = hypotf(vx, vy);
- if (speed > bestSpeed) {
- bestId = id;
- bestSpeed = speed;
- }
- }
- }
- if (bestId >= 0 && bestId != activeTouchId) {
- mPointerGesture.activeTouchId = activeTouchId = bestId;
-#if DEBUG_GESTURES
- ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
- "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
-#endif
- }
- }
-
- if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
- const RawPointerData::Pointer& currentPointer =
- mCurrentRawPointerData.pointerForId(activeTouchId);
- const RawPointerData::Pointer& lastPointer =
- mLastRawPointerData.pointerForId(activeTouchId);
- float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
- float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
-
- rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
- // Move the pointer using a relative motion.
- // When using spots, the click will occur at the position of the anchor
- // spot and all other spots will move there.
- mPointerController->move(deltaX, deltaY);
- } else {
- mPointerVelocityControl.reset();
- }
-
- float x, y;
- mPointerController->getPosition(&x, &y);
-
- mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
- mPointerGesture.currentGestureIdBits.clear();
- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
- mPointerGesture.currentGestureProperties[0].clear();
- mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
- mPointerGesture.currentGestureCoords[0].clear();
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- } else if (currentFingerCount == 0) {
- // Case 3. No fingers down and button is not pressed. (NEUTRAL)
- if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
- *outFinishPreviousGesture = true;
- }
-
- // Watch for taps coming out of HOVER or TAP_DRAG mode.
- // Checking for taps after TAP_DRAG allows us to detect double-taps.
- bool tapped = false;
- if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
- || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
- && lastFingerCount == 1) {
- if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
- float x, y;
- mPointerController->getPosition(&x, &y);
- if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
- && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
-#if DEBUG_GESTURES
- ALOGD("Gestures: TAP");
-#endif
-
- mPointerGesture.tapUpTime = when;
- getContext()->requestTimeoutAtTime(when
- + mConfig.pointerGestureTapDragInterval);
-
- mPointerGesture.activeGestureId = 0;
- mPointerGesture.currentGestureMode = PointerGesture::TAP;
- mPointerGesture.currentGestureIdBits.clear();
- mPointerGesture.currentGestureIdBits.markBit(
- mPointerGesture.activeGestureId);
- mPointerGesture.currentGestureIdToIndex[
- mPointerGesture.activeGestureId] = 0;
- mPointerGesture.currentGestureProperties[0].clear();
- mPointerGesture.currentGestureProperties[0].id =
- mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType =
- AMOTION_EVENT_TOOL_TYPE_FINGER;
- mPointerGesture.currentGestureCoords[0].clear();
- mPointerGesture.currentGestureCoords[0].setAxisValue(
- AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
- mPointerGesture.currentGestureCoords[0].setAxisValue(
- AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
- mPointerGesture.currentGestureCoords[0].setAxisValue(
- AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-
- tapped = true;
- } else {
-#if DEBUG_GESTURES
- ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
- x - mPointerGesture.tapX,
- y - mPointerGesture.tapY);
-#endif
- }
- } else {
-#if DEBUG_GESTURES
- ALOGD("Gestures: Not a TAP, %0.3fms since down",
- (when - mPointerGesture.tapDownTime) * 0.000001f);
-#endif
- }
- }
-
- mPointerVelocityControl.reset();
-
- if (!tapped) {
-#if DEBUG_GESTURES
- ALOGD("Gestures: NEUTRAL");
-#endif
- mPointerGesture.activeGestureId = -1;
- mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
- mPointerGesture.currentGestureIdBits.clear();
- }
- } else if (currentFingerCount == 1) {
- // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
- // The pointer follows the active touch point.
- // When in HOVER, emit HOVER_MOVE events at the pointer location.
- // When in TAP_DRAG, emit MOVE events at the pointer location.
- ALOG_ASSERT(activeTouchId >= 0);
-
- mPointerGesture.currentGestureMode = PointerGesture::HOVER;
- if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
- if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
- float x, y;
- mPointerController->getPosition(&x, &y);
- if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
- && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
- mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
- } else {
-#if DEBUG_GESTURES
- ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
- x - mPointerGesture.tapX,
- y - mPointerGesture.tapY);
-#endif
- }
- } else {
-#if DEBUG_GESTURES
- ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
- (when - mPointerGesture.tapUpTime) * 0.000001f);
-#endif
- }
- } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
- mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
- }
-
- if (mLastFingerIdBits.hasBit(activeTouchId)) {
- const RawPointerData::Pointer& currentPointer =
- mCurrentRawPointerData.pointerForId(activeTouchId);
- const RawPointerData::Pointer& lastPointer =
- mLastRawPointerData.pointerForId(activeTouchId);
- float deltaX = (currentPointer.x - lastPointer.x)
- * mPointerXMovementScale;
- float deltaY = (currentPointer.y - lastPointer.y)
- * mPointerYMovementScale;
-
- rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
- // Move the pointer using a relative motion.
- // When using spots, the hover or drag will occur at the position of the anchor spot.
- mPointerController->move(deltaX, deltaY);
- } else {
- mPointerVelocityControl.reset();
- }
-
- bool down;
- if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
-#if DEBUG_GESTURES
- ALOGD("Gestures: TAP_DRAG");
-#endif
- down = true;
- } else {
-#if DEBUG_GESTURES
- ALOGD("Gestures: HOVER");
-#endif
- if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
- *outFinishPreviousGesture = true;
- }
- mPointerGesture.activeGestureId = 0;
- down = false;
- }
-
- float x, y;
- mPointerController->getPosition(&x, &y);
-
- mPointerGesture.currentGestureIdBits.clear();
- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
- mPointerGesture.currentGestureProperties[0].clear();
- mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType =
- AMOTION_EVENT_TOOL_TYPE_FINGER;
- mPointerGesture.currentGestureCoords[0].clear();
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
- down ? 1.0f : 0.0f);
-
- if (lastFingerCount == 0 && currentFingerCount != 0) {
- mPointerGesture.resetTap();
- mPointerGesture.tapDownTime = when;
- mPointerGesture.tapX = x;
- mPointerGesture.tapY = y;
- }
- } else {
- // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
- // We need to provide feedback for each finger that goes down so we cannot wait
- // for the fingers to move before deciding what to do.
- //
- // The ambiguous case is deciding what to do when there are two fingers down but they
- // have not moved enough to determine whether they are part of a drag or part of a
- // freeform gesture, or just a press or long-press at the pointer location.
- //
- // When there are two fingers we start with the PRESS hypothesis and we generate a
- // down at the pointer location.
- //
- // When the two fingers move enough or when additional fingers are added, we make
- // a decision to transition into SWIPE or FREEFORM mode accordingly.
- ALOG_ASSERT(activeTouchId >= 0);
-
- bool settled = when >= mPointerGesture.firstTouchTime
- + mConfig.pointerGestureMultitouchSettleInterval;
- if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
- && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
- && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
- *outFinishPreviousGesture = true;
- } else if (!settled && currentFingerCount > lastFingerCount) {
- // Additional pointers have gone down but not yet settled.
- // Reset the gesture.
-#if DEBUG_GESTURES
- ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
- "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
- + mConfig.pointerGestureMultitouchSettleInterval - when)
- * 0.000001f);
-#endif
- *outCancelPreviousGesture = true;
- } else {
- // Continue previous gesture.
- mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
- }
-
- if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
- mPointerGesture.currentGestureMode = PointerGesture::PRESS;
- mPointerGesture.activeGestureId = 0;
- mPointerGesture.referenceIdBits.clear();
- mPointerVelocityControl.reset();
-
- // Use the centroid and pointer location as the reference points for the gesture.
-#if DEBUG_GESTURES
- ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
- "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
- + mConfig.pointerGestureMultitouchSettleInterval - when)
- * 0.000001f);
-#endif
- mCurrentRawPointerData.getCentroidOfTouchingPointers(
- &mPointerGesture.referenceTouchX,
- &mPointerGesture.referenceTouchY);
- mPointerController->getPosition(&mPointerGesture.referenceGestureX,
- &mPointerGesture.referenceGestureY);
- }
-
- // Clear the reference deltas for fingers not yet included in the reference calculation.
- for (BitSet32 idBits(mCurrentFingerIdBits.value
- & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- mPointerGesture.referenceDeltas[id].dx = 0;
- mPointerGesture.referenceDeltas[id].dy = 0;
- }
- mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
-
- // Add delta for all fingers and calculate a common movement delta.
- float commonDeltaX = 0, commonDeltaY = 0;
- BitSet32 commonIdBits(mLastFingerIdBits.value
- & mCurrentFingerIdBits.value);
- for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
- bool first = (idBits == commonIdBits);
- uint32_t id = idBits.clearFirstMarkedBit();
- const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
- const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
- PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- delta.dx += cpd.x - lpd.x;
- delta.dy += cpd.y - lpd.y;
-
- if (first) {
- commonDeltaX = delta.dx;
- commonDeltaY = delta.dy;
- } else {
- commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
- commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
- }
- }
-
- // Consider transitions from PRESS to SWIPE or MULTITOUCH.
- if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
- float dist[MAX_POINTER_ID + 1];
- int32_t distOverThreshold = 0;
- for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- dist[id] = hypotf(delta.dx * mPointerXZoomScale,
- delta.dy * mPointerYZoomScale);
- if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
- distOverThreshold += 1;
- }
- }
-
- // Only transition when at least two pointers have moved further than
- // the minimum distance threshold.
- if (distOverThreshold >= 2) {
- if (currentFingerCount > 2) {
- // There are more than two pointers, switch to FREEFORM.
-#if DEBUG_GESTURES
- ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
- currentFingerCount);
-#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else {
- // There are exactly two pointers.
- BitSet32 idBits(mCurrentFingerIdBits);
- uint32_t id1 = idBits.clearFirstMarkedBit();
- uint32_t id2 = idBits.firstMarkedBit();
- const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
- const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
- float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
- if (mutualDistance > mPointerGestureMaxSwipeWidth) {
- // There are two pointers but they are too far apart for a SWIPE,
- // switch to FREEFORM.
-#if DEBUG_GESTURES
- ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
- mutualDistance, mPointerGestureMaxSwipeWidth);
-#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else {
- // There are two pointers. Wait for both pointers to start moving
- // before deciding whether this is a SWIPE or FREEFORM gesture.
- float dist1 = dist[id1];
- float dist2 = dist[id2];
- if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
- && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
- // Calculate the dot product of the displacement vectors.
- // When the vectors are oriented in approximately the same direction,
- // the angle betweeen them is near zero and the cosine of the angle
- // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
- PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
- PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
- float dx1 = delta1.dx * mPointerXZoomScale;
- float dy1 = delta1.dy * mPointerYZoomScale;
- float dx2 = delta2.dx * mPointerXZoomScale;
- float dy2 = delta2.dy * mPointerYZoomScale;
- float dot = dx1 * dx2 + dy1 * dy2;
- float cosine = dot / (dist1 * dist2); // denominator always > 0
- if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
- // Pointers are moving in the same direction. Switch to SWIPE.
-#if DEBUG_GESTURES
- ALOGD("Gestures: PRESS transitioned to SWIPE, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f >= %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
-#endif
- mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
- } else {
- // Pointers are moving in different directions. Switch to FREEFORM.
-#if DEBUG_GESTURES
- ALOGD("Gestures: PRESS transitioned to FREEFORM, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f < %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
-#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- }
- }
- }
- }
- }
- } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
- // Switch from SWIPE to FREEFORM if additional pointers go down.
- // Cancel previous gesture.
- if (currentFingerCount > 2) {
-#if DEBUG_GESTURES
- ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
- currentFingerCount);
-#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- }
- }
-
- // Move the reference points based on the overall group motion of the fingers
- // except in PRESS mode while waiting for a transition to occur.
- if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
- && (commonDeltaX || commonDeltaY)) {
- for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- delta.dx = 0;
- delta.dy = 0;
- }
-
- mPointerGesture.referenceTouchX += commonDeltaX;
- mPointerGesture.referenceTouchY += commonDeltaY;
-
- commonDeltaX *= mPointerXMovementScale;
- commonDeltaY *= mPointerYMovementScale;
-
- rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
- mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
-
- mPointerGesture.referenceGestureX += commonDeltaX;
- mPointerGesture.referenceGestureY += commonDeltaY;
- }
-
- // Report gestures.
- if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
- || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
- // PRESS or SWIPE mode.
-#if DEBUG_GESTURES
- ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
- "activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
-#endif
- ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
-
- mPointerGesture.currentGestureIdBits.clear();
- mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
- mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
- mPointerGesture.currentGestureProperties[0].clear();
- mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
- mPointerGesture.currentGestureProperties[0].toolType =
- AMOTION_EVENT_TOOL_TYPE_FINGER;
- mPointerGesture.currentGestureCoords[0].clear();
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
- mPointerGesture.referenceGestureX);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
- mPointerGesture.referenceGestureY);
- mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
- // FREEFORM mode.
-#if DEBUG_GESTURES
- ALOGD("Gestures: FREEFORM activeTouchId=%d,"
- "activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
-#endif
- ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
-
- mPointerGesture.currentGestureIdBits.clear();
-
- BitSet32 mappedTouchIdBits;
- BitSet32 usedGestureIdBits;
- if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
- // Initially, assign the active gesture id to the active touch point
- // if there is one. No other touch id bits are mapped yet.
- if (!*outCancelPreviousGesture) {
- mappedTouchIdBits.markBit(activeTouchId);
- usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
- mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
- mPointerGesture.activeGestureId;
- } else {
- mPointerGesture.activeGestureId = -1;
- }
- } else {
- // Otherwise, assume we mapped all touches from the previous frame.
- // Reuse all mappings that are still applicable.
- mappedTouchIdBits.value = mLastFingerIdBits.value
- & mCurrentFingerIdBits.value;
- usedGestureIdBits = mPointerGesture.lastGestureIdBits;
-
- // Check whether we need to choose a new active gesture id because the
- // current went went up.
- for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
- & ~mCurrentFingerIdBits.value);
- !upTouchIdBits.isEmpty(); ) {
- uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
- uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
- if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
- mPointerGesture.activeGestureId = -1;
- break;
- }
- }
- }
-
-#if DEBUG_GESTURES
- ALOGD("Gestures: FREEFORM follow up "
- "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
- "activeGestureId=%d",
- mappedTouchIdBits.value, usedGestureIdBits.value,
- mPointerGesture.activeGestureId);
-#endif
-
- BitSet32 idBits(mCurrentFingerIdBits);
- for (uint32_t i = 0; i < currentFingerCount; i++) {
- uint32_t touchId = idBits.clearFirstMarkedBit();
- uint32_t gestureId;
- if (!mappedTouchIdBits.hasBit(touchId)) {
- gestureId = usedGestureIdBits.markFirstUnmarkedBit();
- mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
-#if DEBUG_GESTURES
- ALOGD("Gestures: FREEFORM "
- "new mapping for touch id %d -> gesture id %d",
- touchId, gestureId);
-#endif
- } else {
- gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
-#if DEBUG_GESTURES
- ALOGD("Gestures: FREEFORM "
- "existing mapping for touch id %d -> gesture id %d",
- touchId, gestureId);
-#endif
- }
- mPointerGesture.currentGestureIdBits.markBit(gestureId);
- mPointerGesture.currentGestureIdToIndex[gestureId] = i;
-
- const RawPointerData::Pointer& pointer =
- mCurrentRawPointerData.pointerForId(touchId);
- float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
- * mPointerXZoomScale;
- float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
- * mPointerYZoomScale;
- rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
-
- mPointerGesture.currentGestureProperties[i].clear();
- mPointerGesture.currentGestureProperties[i].id = gestureId;
- mPointerGesture.currentGestureProperties[i].toolType =
- AMOTION_EVENT_TOOL_TYPE_FINGER;
- mPointerGesture.currentGestureCoords[i].clear();
- mPointerGesture.currentGestureCoords[i].setAxisValue(
- AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
- mPointerGesture.currentGestureCoords[i].setAxisValue(
- AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
- mPointerGesture.currentGestureCoords[i].setAxisValue(
- AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- }
-
- if (mPointerGesture.activeGestureId < 0) {
- mPointerGesture.activeGestureId =
- mPointerGesture.currentGestureIdBits.firstMarkedBit();
-#if DEBUG_GESTURES
- ALOGD("Gestures: FREEFORM new "
- "activeGestureId=%d", mPointerGesture.activeGestureId);
-#endif
- }
- }
- }
-
- mPointerController->setButtonState(mCurrentButtonState);
-
-#if DEBUG_GESTURES
- ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
- "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
- "lastGestureMode=%d, lastGestureIdBits=0x%08x",
- toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
- mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
- mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
- for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
- const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
- const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
- ALOGD(" currentGesture[%d]: index=%d, toolType=%d, "
- "x=%0.3f, y=%0.3f, pressure=%0.3f",
- id, index, properties.toolType,
- coords.getAxisValue(AMOTION_EVENT_AXIS_X),
- coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
- coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
- }
- for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
- const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
- const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
- ALOGD(" lastGesture[%d]: index=%d, toolType=%d, "
- "x=%0.3f, y=%0.3f, pressure=%0.3f",
- id, index, properties.toolType,
- coords.getAxisValue(AMOTION_EVENT_AXIS_X),
- coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
- coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
- }
-#endif
- return true;
-}
-
-void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
- mPointerSimple.currentCoords.clear();
- mPointerSimple.currentProperties.clear();
-
- bool down, hovering;
- if (!mCurrentStylusIdBits.isEmpty()) {
- uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
- uint32_t index = mCurrentCookedPointerData.idToIndex[id];
- float x = mCurrentCookedPointerData.pointerCoords[index].getX();
- float y = mCurrentCookedPointerData.pointerCoords[index].getY();
- mPointerController->setPosition(x, y);
-
- hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
- down = !hovering;
-
- mPointerController->getPosition(&x, &y);
- mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
- mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- mPointerSimple.currentProperties.id = 0;
- mPointerSimple.currentProperties.toolType =
- mCurrentCookedPointerData.pointerProperties[index].toolType;
- } else {
- down = false;
- hovering = false;
- }
-
- dispatchPointerSimple(when, policyFlags, down, hovering);
-}
-
-void TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
- abortPointerSimple(when, policyFlags);
-}
-
-void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
- mPointerSimple.currentCoords.clear();
- mPointerSimple.currentProperties.clear();
-
- bool down, hovering;
- if (!mCurrentMouseIdBits.isEmpty()) {
- uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
- uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
- if (mLastMouseIdBits.hasBit(id)) {
- uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
- float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
- - mLastRawPointerData.pointers[lastIndex].x)
- * mPointerXMovementScale;
- float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
- - mLastRawPointerData.pointers[lastIndex].y)
- * mPointerYMovementScale;
-
- rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
- mPointerController->move(deltaX, deltaY);
- } else {
- mPointerVelocityControl.reset();
- }
-
- down = isPointerDown(mCurrentButtonState);
- hovering = !down;
-
- float x, y;
- mPointerController->getPosition(&x, &y);
- mPointerSimple.currentCoords.copyFrom(
- mCurrentCookedPointerData.pointerCoords[currentIndex]);
- mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
- hovering ? 0.0f : 1.0f);
- mPointerSimple.currentProperties.id = 0;
- mPointerSimple.currentProperties.toolType =
- mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
- } else {
- mPointerVelocityControl.reset();
-
- down = false;
- hovering = false;
- }
-
- dispatchPointerSimple(when, policyFlags, down, hovering);
-}
-
-void TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
- abortPointerSimple(when, policyFlags);
-
- mPointerVelocityControl.reset();
-}
-
-void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
- bool down, bool hovering) {
- int32_t metaState = getContext()->getGlobalMetaState();
-
- if (mPointerController != NULL) {
- if (down || hovering) {
- mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
- mPointerController->clearSpots();
- mPointerController->setButtonState(mCurrentButtonState);
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
- } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- }
-
- if (mPointerSimple.down && !down) {
- mPointerSimple.down = false;
-
- // Send up.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- if (mPointerSimple.hovering && !hovering) {
- mPointerSimple.hovering = false;
-
- // Send hover exit.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- if (down) {
- if (!mPointerSimple.down) {
- mPointerSimple.down = true;
- mPointerSimple.downTime = when;
-
- // Send down.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- // Send move.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- if (hovering) {
- if (!mPointerSimple.hovering) {
- mPointerSimple.hovering = true;
-
- // Send hover enter.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- // Send hover move.
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- if (mCurrentRawVScroll || mCurrentRawHScroll) {
- float vscroll = mCurrentRawVScroll;
- float hscroll = mCurrentRawHScroll;
- mWheelYVelocityControl.move(when, NULL, &vscroll);
- mWheelXVelocityControl.move(when, &hscroll, NULL);
-
- // Send scroll.
- PointerCoords pointerCoords;
- pointerCoords.copyFrom(mPointerSimple.currentCoords);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
-
- NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
- mViewport.displayId,
- 1, &mPointerSimple.currentProperties, &pointerCoords,
- mOrientedXPrecision, mOrientedYPrecision,
- mPointerSimple.downTime);
- getListener()->notifyMotion(&args);
- }
-
- // Save state.
- if (down || hovering) {
- mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
- mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
- } else {
- mPointerSimple.reset();
- }
-}
-
-void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
- mPointerSimple.currentCoords.clear();
- mPointerSimple.currentProperties.clear();
-
- dispatchPointerSimple(when, policyFlags, false, false);
-}
-
-void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
- int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- const PointerProperties* properties, const PointerCoords* coords,
- const uint32_t* idToIndex, BitSet32 idBits,
- int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
- PointerCoords pointerCoords[MAX_POINTERS];
- PointerProperties pointerProperties[MAX_POINTERS];
- uint32_t pointerCount = 0;
- while (!idBits.isEmpty()) {
- uint32_t id = idBits.clearFirstMarkedBit();
- uint32_t index = idToIndex[id];
- pointerProperties[pointerCount].copyFrom(properties[index]);
- pointerCoords[pointerCount].copyFrom(coords[index]);
-
- if (changedId >= 0 && id == uint32_t(changedId)) {
- action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- }
-
- pointerCount += 1;
- }
-
- ALOG_ASSERT(pointerCount != 0);
-
- if (changedId >= 0 && pointerCount == 1) {
- // Replace initial down and final up action.
- // We can compare the action without masking off the changed pointer index
- // because we know the index is 0.
- if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
- action = AMOTION_EVENT_ACTION_DOWN;
- } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
- action = AMOTION_EVENT_ACTION_UP;
- } else {
- // Can't happen.
- ALOG_ASSERT(false);
- }
- }
-
- NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
- action, flags, metaState, buttonState, edgeFlags,
- mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
- xPrecision, yPrecision, downTime);
- getListener()->notifyMotion(&args);
-}
-
-bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
- const PointerCoords* inCoords, const uint32_t* inIdToIndex,
- PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
- BitSet32 idBits) const {
- bool changed = false;
- while (!idBits.isEmpty()) {
- uint32_t id = idBits.clearFirstMarkedBit();
- uint32_t inIndex = inIdToIndex[id];
- uint32_t outIndex = outIdToIndex[id];
-
- const PointerProperties& curInProperties = inProperties[inIndex];
- const PointerCoords& curInCoords = inCoords[inIndex];
- PointerProperties& curOutProperties = outProperties[outIndex];
- PointerCoords& curOutCoords = outCoords[outIndex];
-
- if (curInProperties != curOutProperties) {
- curOutProperties.copyFrom(curInProperties);
- changed = true;
- }
-
- if (curInCoords != curOutCoords) {
- curOutCoords.copyFrom(curInCoords);
- changed = true;
- }
- }
- return changed;
-}
-
-void TouchInputMapper::fadePointer() {
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
-}
-
-bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
- return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
- && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
-}
-
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
- int32_t x, int32_t y) {
- size_t numVirtualKeys = mVirtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
-
-#if DEBUG_VIRTUAL_KEYS
- ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
- "left=%d, top=%d, right=%d, bottom=%d",
- x, y,
- virtualKey.keyCode, virtualKey.scanCode,
- virtualKey.hitLeft, virtualKey.hitTop,
- virtualKey.hitRight, virtualKey.hitBottom);
-#endif
-
- if (virtualKey.isHit(x, y)) {
- return & virtualKey;
- }
- }
-
- return NULL;
-}
-
-void TouchInputMapper::assignPointerIds() {
- uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
- uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
-
- mCurrentRawPointerData.clearIdBits();
-
- if (currentPointerCount == 0) {
- // No pointers to assign.
- return;
- }
-
- if (lastPointerCount == 0) {
- // All pointers are new.
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- uint32_t id = i;
- mCurrentRawPointerData.pointers[i].id = id;
- mCurrentRawPointerData.idToIndex[id] = i;
- mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
- }
- return;
- }
-
- if (currentPointerCount == 1 && lastPointerCount == 1
- && mCurrentRawPointerData.pointers[0].toolType
- == mLastRawPointerData.pointers[0].toolType) {
- // Only one pointer and no change in count so it must have the same id as before.
- uint32_t id = mLastRawPointerData.pointers[0].id;
- mCurrentRawPointerData.pointers[0].id = id;
- mCurrentRawPointerData.idToIndex[id] = 0;
- mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
- return;
- }
-
- // General case.
- // We build a heap of squared euclidean distances between current and last pointers
- // associated with the current and last pointer indices. Then, we find the best
- // match (by distance) for each current pointer.
- // The pointers must have the same tool type but it is possible for them to
- // transition from hovering to touching or vice-versa while retaining the same id.
- PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
-
- uint32_t heapSize = 0;
- for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
- currentPointerIndex++) {
- for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
- lastPointerIndex++) {
- const RawPointerData::Pointer& currentPointer =
- mCurrentRawPointerData.pointers[currentPointerIndex];
- const RawPointerData::Pointer& lastPointer =
- mLastRawPointerData.pointers[lastPointerIndex];
- if (currentPointer.toolType == lastPointer.toolType) {
- int64_t deltaX = currentPointer.x - lastPointer.x;
- int64_t deltaY = currentPointer.y - lastPointer.y;
-
- uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
-
- // Insert new element into the heap (sift up).
- heap[heapSize].currentPointerIndex = currentPointerIndex;
- heap[heapSize].lastPointerIndex = lastPointerIndex;
- heap[heapSize].distance = distance;
- heapSize += 1;
- }
- }
- }
-
- // Heapify
- for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
- startIndex -= 1;
- for (uint32_t parentIndex = startIndex; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
-
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
-
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
- }
- }
-
-#if DEBUG_POINTER_ASSIGNMENT
- ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- ALOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
-
- // Pull matches out by increasing order of distance.
- // To avoid reassigning pointers that have already been matched, the loop keeps track
- // of which last and current pointers have been matched using the matchedXXXBits variables.
- // It also tracks the used pointer id bits.
- BitSet32 matchedLastBits(0);
- BitSet32 matchedCurrentBits(0);
- BitSet32 usedIdBits(0);
- bool first = true;
- for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
- while (heapSize > 0) {
- if (first) {
- // The first time through the loop, we just consume the root element of
- // the heap (the one with smallest distance).
- first = false;
- } else {
- // Previous iterations consumed the root element of the heap.
- // Pop root element off of the heap (sift down).
- heap[0] = heap[heapSize];
- for (uint32_t parentIndex = 0; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
-
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
-
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
- }
-
-#if DEBUG_POINTER_ASSIGNMENT
- ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- ALOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
- }
-
- heapSize -= 1;
-
- uint32_t currentPointerIndex = heap[0].currentPointerIndex;
- if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
-
- uint32_t lastPointerIndex = heap[0].lastPointerIndex;
- if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
-
- matchedCurrentBits.markBit(currentPointerIndex);
- matchedLastBits.markBit(lastPointerIndex);
-
- uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
- mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
- mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
- mCurrentRawPointerData.markIdBit(id,
- mCurrentRawPointerData.isHovering(currentPointerIndex));
- usedIdBits.markBit(id);
-
-#if DEBUG_POINTER_ASSIGNMENT
- ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
- lastPointerIndex, currentPointerIndex, id, heap[0].distance);
-#endif
- break;
- }
- }
-
- // Assign fresh ids to pointers that were not matched in the process.
- for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
- uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
- uint32_t id = usedIdBits.markFirstUnmarkedBit();
-
- mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
- mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
- mCurrentRawPointerData.markIdBit(id,
- mCurrentRawPointerData.isHovering(currentPointerIndex));
-
-#if DEBUG_POINTER_ASSIGNMENT
- ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
- currentPointerIndex, id);
-#endif
- }
-}
-
-int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
- return AKEY_STATE_VIRTUAL;
- }
-
- size_t numVirtualKeys = mVirtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
- if (virtualKey.keyCode == keyCode) {
- return AKEY_STATE_UP;
- }
- }
-
- return AKEY_STATE_UNKNOWN;
-}
-
-int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
- return AKEY_STATE_VIRTUAL;
- }
-
- size_t numVirtualKeys = mVirtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
- if (virtualKey.scanCode == scanCode) {
- return AKEY_STATE_UP;
- }
- }
-
- return AKEY_STATE_UNKNOWN;
-}
-
-bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- size_t numVirtualKeys = mVirtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mVirtualKeys[i];
-
- for (size_t i = 0; i < numCodes; i++) {
- if (virtualKey.keyCode == keyCodes[i]) {
- outFlags[i] = 1;
- }
- }
- }
-
- return true;
-}
-
-
-// --- SingleTouchInputMapper ---
-
-SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
- TouchInputMapper(device) {
-}
-
-SingleTouchInputMapper::~SingleTouchInputMapper() {
-}
-
-void SingleTouchInputMapper::reset(nsecs_t when) {
- mSingleTouchMotionAccumulator.reset(getDevice());
-
- TouchInputMapper::reset(when);
-}
-
-void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
- TouchInputMapper::process(rawEvent);
-
- mSingleTouchMotionAccumulator.process(rawEvent);
-}
-
-void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
- if (mTouchButtonAccumulator.isToolActive()) {
- mCurrentRawPointerData.pointerCount = 1;
- mCurrentRawPointerData.idToIndex[0] = 0;
-
- bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
- && (mTouchButtonAccumulator.isHovering()
- || (mRawPointerAxes.pressure.valid
- && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
- mCurrentRawPointerData.markIdBit(0, isHovering);
-
- RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
- outPointer.id = 0;
- outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
- outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
- outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
- outPointer.touchMajor = 0;
- outPointer.touchMinor = 0;
- outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
- outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
- outPointer.orientation = 0;
- outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
- outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
- outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
- outPointer.toolType = mTouchButtonAccumulator.getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
- }
- outPointer.isHovering = isHovering;
- }
-}
-
-void SingleTouchInputMapper::configureRawPointerAxes() {
- TouchInputMapper::configureRawPointerAxes();
-
- getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
- getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
- getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
- getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
- getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
- getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
- getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
-}
-
-bool SingleTouchInputMapper::hasStylus() const {
- return mTouchButtonAccumulator.hasStylus();
-}
-
-
-// --- MultiTouchInputMapper ---
-
-MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
- TouchInputMapper(device) {
-}
-
-MultiTouchInputMapper::~MultiTouchInputMapper() {
-}
-
-void MultiTouchInputMapper::reset(nsecs_t when) {
- mMultiTouchMotionAccumulator.reset(getDevice());
-
- mPointerIdBits.clear();
-
- TouchInputMapper::reset(when);
-}
-
-void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
- TouchInputMapper::process(rawEvent);
-
- mMultiTouchMotionAccumulator.process(rawEvent);
-}
-
-void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
- size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
- size_t outCount = 0;
- BitSet32 newPointerIdBits;
-
- for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
- const MultiTouchMotionAccumulator::Slot* inSlot =
- mMultiTouchMotionAccumulator.getSlot(inIndex);
- if (!inSlot->isInUse()) {
- continue;
- }
-
- if (outCount >= MAX_POINTERS) {
-#if DEBUG_POINTERS
- ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
- "ignoring the rest.",
- getDeviceName().string(), MAX_POINTERS);
-#endif
- break; // too many fingers!
- }
-
- RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
- outPointer.x = inSlot->getX();
- outPointer.y = inSlot->getY();
- outPointer.pressure = inSlot->getPressure();
- outPointer.touchMajor = inSlot->getTouchMajor();
- outPointer.touchMinor = inSlot->getTouchMinor();
- outPointer.toolMajor = inSlot->getToolMajor();
- outPointer.toolMinor = inSlot->getToolMinor();
- outPointer.orientation = inSlot->getOrientation();
- outPointer.distance = inSlot->getDistance();
- outPointer.tiltX = 0;
- outPointer.tiltY = 0;
-
- outPointer.toolType = inSlot->getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- outPointer.toolType = mTouchButtonAccumulator.getToolType();
- if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
- outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
- }
- }
-
- bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
- && (mTouchButtonAccumulator.isHovering()
- || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
- outPointer.isHovering = isHovering;
-
- // Assign pointer id using tracking id if available.
- if (*outHavePointerIds) {
- int32_t trackingId = inSlot->getTrackingId();
- int32_t id = -1;
- if (trackingId >= 0) {
- for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
- uint32_t n = idBits.clearFirstMarkedBit();
- if (mPointerTrackingIdMap[n] == trackingId) {
- id = n;
- }
- }
-
- if (id < 0 && !mPointerIdBits.isFull()) {
- id = mPointerIdBits.markFirstUnmarkedBit();
- mPointerTrackingIdMap[id] = trackingId;
- }
- }
- if (id < 0) {
- *outHavePointerIds = false;
- mCurrentRawPointerData.clearIdBits();
- newPointerIdBits.clear();
- } else {
- outPointer.id = id;
- mCurrentRawPointerData.idToIndex[id] = outCount;
- mCurrentRawPointerData.markIdBit(id, isHovering);
- newPointerIdBits.markBit(id);
- }
- }
-
- outCount += 1;
- }
-
- mCurrentRawPointerData.pointerCount = outCount;
- mPointerIdBits = newPointerIdBits;
-
- mMultiTouchMotionAccumulator.finishSync();
-}
-
-void MultiTouchInputMapper::configureRawPointerAxes() {
- TouchInputMapper::configureRawPointerAxes();
-
- getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
- getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
- getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
- getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
- getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
- getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
- getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
- getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
- getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
- getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
- getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
-
- if (mRawPointerAxes.trackingId.valid
- && mRawPointerAxes.slot.valid
- && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
- size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
- if (slotCount > MAX_SLOTS) {
- ALOGW("MultiTouch Device %s reported %d slots but the framework "
- "only supports a maximum of %d slots at this time.",
- getDeviceName().string(), slotCount, MAX_SLOTS);
- slotCount = MAX_SLOTS;
- }
- mMultiTouchMotionAccumulator.configure(getDevice(),
- slotCount, true /*usingSlotsProtocol*/);
- } else {
- mMultiTouchMotionAccumulator.configure(getDevice(),
- MAX_POINTERS, false /*usingSlotsProtocol*/);
- }
-}
-
-bool MultiTouchInputMapper::hasStylus() const {
- return mMultiTouchMotionAccumulator.hasStylus()
- || mTouchButtonAccumulator.hasStylus();
-}
-
-
-// --- JoystickInputMapper ---
-
-JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
- InputMapper(device) {
-}
-
-JoystickInputMapper::~JoystickInputMapper() {
-}
-
-uint32_t JoystickInputMapper::getSources() {
- return AINPUT_SOURCE_JOYSTICK;
-}
-
-void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
- InputMapper::populateDeviceInfo(info);
-
- for (size_t i = 0; i < mAxes.size(); i++) {
- const Axis& axis = mAxes.valueAt(i);
- addMotionRange(axis.axisInfo.axis, axis, info);
-
- if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
- addMotionRange(axis.axisInfo.highAxis, axis, info);
-
- }
- }
-}
-
-void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
- InputDeviceInfo* info) {
- info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
- axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
- /* In order to ease the transition for developers from using the old axes
- * to the newer, more semantically correct axes, we'll continue to register
- * the old axes as duplicates of their corresponding new ones. */
- int32_t compatAxis = getCompatAxis(axisId);
- if (compatAxis >= 0) {
- info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
- axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
- }
-}
-
-/* A mapping from axes the joystick actually has to the axes that should be
- * artificially created for compatibility purposes.
- * Returns -1 if no compatibility axis is needed. */
-int32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
- switch(axis) {
- case AMOTION_EVENT_AXIS_LTRIGGER:
- return AMOTION_EVENT_AXIS_BRAKE;
- case AMOTION_EVENT_AXIS_RTRIGGER:
- return AMOTION_EVENT_AXIS_GAS;
- }
- return -1;
-}
-
-void JoystickInputMapper::dump(String8& dump) {
- dump.append(INDENT2 "Joystick Input Mapper:\n");
-
- dump.append(INDENT3 "Axes:\n");
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- const Axis& axis = mAxes.valueAt(i);
- const char* label = getAxisLabel(axis.axisInfo.axis);
- if (label) {
- dump.appendFormat(INDENT4 "%s", label);
- } else {
- dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
- }
- if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
- label = getAxisLabel(axis.axisInfo.highAxis);
- if (label) {
- dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
- } else {
- dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
- axis.axisInfo.splitValue);
- }
- } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
- dump.append(" (invert)");
- }
-
- dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
- axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
- dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, "
- "highScale=%0.5f, highOffset=%0.5f\n",
- axis.scale, axis.offset, axis.highScale, axis.highOffset);
- dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, "
- "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
- mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
- axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
- }
-}
-
-void JoystickInputMapper::configure(nsecs_t when,
- const InputReaderConfiguration* config, uint32_t changes) {
- InputMapper::configure(when, config, changes);
-
- if (!changes) { // first time only
- // Collect all axes.
- for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
- if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
- & INPUT_DEVICE_CLASS_JOYSTICK)) {
- continue; // axis must be claimed by a different device
- }
-
- RawAbsoluteAxisInfo rawAxisInfo;
- getAbsoluteAxisInfo(abs, &rawAxisInfo);
- if (rawAxisInfo.valid) {
- // Map axis.
- AxisInfo axisInfo;
- bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
- if (!explicitlyMapped) {
- // Axis is not explicitly mapped, will choose a generic axis later.
- axisInfo.mode = AxisInfo::MODE_NORMAL;
- axisInfo.axis = -1;
- }
-
- // Apply flat override.
- int32_t rawFlat = axisInfo.flatOverride < 0
- ? rawAxisInfo.flat : axisInfo.flatOverride;
-
- // Calculate scaling factors and limits.
- Axis axis;
- if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
- float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
- float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, 0.0f, highScale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
- rawAxisInfo.resolution * scale);
- } else if (isCenteredAxis(axisInfo.axis)) {
- float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
- float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, offset, scale, offset,
- -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
- rawAxisInfo.resolution * scale);
- } else {
- float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, 0.0f, scale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
- rawAxisInfo.resolution * scale);
- }
-
- // To eliminate noise while the joystick is at rest, filter out small variations
- // in axis values up front.
- axis.filter = axis.flat * 0.25f;
-
- mAxes.add(abs, axis);
- }
- }
-
- // If there are too many axes, start dropping them.
- // Prefer to keep explicitly mapped axes.
- if (mAxes.size() > PointerCoords::MAX_AXES) {
- ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
- getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
- pruneAxes(true);
- pruneAxes(false);
- }
-
- // Assign generic axis ids to remaining axes.
- int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- Axis& axis = mAxes.editValueAt(i);
- if (axis.axisInfo.axis < 0) {
- while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
- && haveAxis(nextGenericAxisId)) {
- nextGenericAxisId += 1;
- }
-
- if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
- axis.axisInfo.axis = nextGenericAxisId;
- nextGenericAxisId += 1;
- } else {
- ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
- "have already been assigned to other axes.",
- getDeviceName().string(), mAxes.keyAt(i));
- mAxes.removeItemsAt(i--);
- numAxes -= 1;
- }
- }
- }
- }
-}
-
-bool JoystickInputMapper::haveAxis(int32_t axisId) {
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- const Axis& axis = mAxes.valueAt(i);
- if (axis.axisInfo.axis == axisId
- || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
- && axis.axisInfo.highAxis == axisId)) {
- return true;
- }
- }
- return false;
-}
-
-void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
- size_t i = mAxes.size();
- while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
- if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
- continue;
- }
- ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
- getDeviceName().string(), mAxes.keyAt(i));
- mAxes.removeItemsAt(i);
- }
-}
-
-bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
- switch (axis) {
- case AMOTION_EVENT_AXIS_X:
- case AMOTION_EVENT_AXIS_Y:
- case AMOTION_EVENT_AXIS_Z:
- case AMOTION_EVENT_AXIS_RX:
- case AMOTION_EVENT_AXIS_RY:
- case AMOTION_EVENT_AXIS_RZ:
- case AMOTION_EVENT_AXIS_HAT_X:
- case AMOTION_EVENT_AXIS_HAT_Y:
- case AMOTION_EVENT_AXIS_ORIENTATION:
- case AMOTION_EVENT_AXIS_RUDDER:
- case AMOTION_EVENT_AXIS_WHEEL:
- return true;
- default:
- return false;
- }
-}
-
-void JoystickInputMapper::reset(nsecs_t when) {
- // Recenter all axes.
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- Axis& axis = mAxes.editValueAt(i);
- axis.resetValue();
- }
-
- InputMapper::reset(when);
-}
-
-void JoystickInputMapper::process(const RawEvent* rawEvent) {
- switch (rawEvent->type) {
- case EV_ABS: {
- ssize_t index = mAxes.indexOfKey(rawEvent->code);
- if (index >= 0) {
- Axis& axis = mAxes.editValueAt(index);
- float newValue, highNewValue;
- switch (axis.axisInfo.mode) {
- case AxisInfo::MODE_INVERT:
- newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
- * axis.scale + axis.offset;
- highNewValue = 0.0f;
- break;
- case AxisInfo::MODE_SPLIT:
- if (rawEvent->value < axis.axisInfo.splitValue) {
- newValue = (axis.axisInfo.splitValue - rawEvent->value)
- * axis.scale + axis.offset;
- highNewValue = 0.0f;
- } else if (rawEvent->value > axis.axisInfo.splitValue) {
- newValue = 0.0f;
- highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
- * axis.highScale + axis.highOffset;
- } else {
- newValue = 0.0f;
- highNewValue = 0.0f;
- }
- break;
- default:
- newValue = rawEvent->value * axis.scale + axis.offset;
- highNewValue = 0.0f;
- break;
- }
- axis.newValue = newValue;
- axis.highNewValue = highNewValue;
- }
- break;
- }
-
- case EV_SYN:
- switch (rawEvent->code) {
- case SYN_REPORT:
- sync(rawEvent->when, false /*force*/);
- break;
- }
- break;
- }
-}
-
-void JoystickInputMapper::sync(nsecs_t when, bool force) {
- if (!filterAxes(force)) {
- return;
- }
-
- int32_t metaState = mContext->getGlobalMetaState();
- int32_t buttonState = 0;
-
- PointerProperties pointerProperties;
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-
- PointerCoords pointerCoords;
- pointerCoords.clear();
-
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- const Axis& axis = mAxes.valueAt(i);
- setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
- if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
- setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
- axis.highCurrentValue);
- }
- }
-
- // Moving a joystick axis should not wake the device because joysticks can
- // be fairly noisy even when not in use. On the other hand, pushing a gamepad
- // button will likely wake the device.
- // TODO: Use the input device configuration to control this behavior more finely.
- uint32_t policyFlags = 0;
-
- NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
- ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
- getListener()->notifyMotion(&args);
-}
-
-void JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
- int32_t axis, float value) {
- pointerCoords->setAxisValue(axis, value);
- /* In order to ease the transition for developers from using the old axes
- * to the newer, more semantically correct axes, we'll continue to produce
- * values for the old axes as mirrors of the value of their corresponding
- * new axes. */
- int32_t compatAxis = getCompatAxis(axis);
- if (compatAxis >= 0) {
- pointerCoords->setAxisValue(compatAxis, value);
- }
-}
-
-bool JoystickInputMapper::filterAxes(bool force) {
- bool atLeastOneSignificantChange = force;
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- Axis& axis = mAxes.editValueAt(i);
- if (force || hasValueChangedSignificantly(axis.filter,
- axis.newValue, axis.currentValue, axis.min, axis.max)) {
- axis.currentValue = axis.newValue;
- atLeastOneSignificantChange = true;
- }
- if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
- if (force || hasValueChangedSignificantly(axis.filter,
- axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
- axis.highCurrentValue = axis.highNewValue;
- atLeastOneSignificantChange = true;
- }
- }
- }
- return atLeastOneSignificantChange;
-}
-
-bool JoystickInputMapper::hasValueChangedSignificantly(
- float filter, float newValue, float currentValue, float min, float max) {
- if (newValue != currentValue) {
- // Filter out small changes in value unless the value is converging on the axis
- // bounds or center point. This is intended to reduce the amount of information
- // sent to applications by particularly noisy joysticks (such as PS3).
- if (fabs(newValue - currentValue) > filter
- || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
- || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
- || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
- return true;
- }
- }
- return false;
-}
-
-bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
- float filter, float newValue, float currentValue, float thresholdValue) {
- float newDistance = fabs(newValue - thresholdValue);
- if (newDistance < filter) {
- float oldDistance = fabs(currentValue - thresholdValue);
- if (newDistance < oldDistance) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputReader.h b/widget/gonk/libui/InputReader.h
deleted file mode 100644
index 5c790fdb8..000000000
--- a/widget/gonk/libui/InputReader.h
+++ /dev/null
@@ -1,1811 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_READER_H
-#define _UI_INPUT_READER_H
-
-#include "EventHub.h"
-#include "PointerController.h"
-#include "InputListener.h"
-
-#include "Input.h"
-#include "VelocityControl.h"
-#include "VelocityTracker.h"
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/BitSet.h>
-
-#include <stddef.h>
-#include <unistd.h>
-
-// Maximum supported size of a vibration pattern.
-// Must be at least 2.
-#define MAX_VIBRATE_PATTERN_SIZE 100
-
-// Maximum allowable delay value in a vibration pattern before
-// which the delay will be truncated.
-#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
-
-namespace android {
-
-class InputDevice;
-class InputMapper;
-
-/*
- * Describes how coordinates are mapped on a physical display.
- * See com.android.server.display.DisplayViewport.
- */
-struct DisplayViewport {
- int32_t displayId; // -1 if invalid
- int32_t orientation;
- int32_t logicalLeft;
- int32_t logicalTop;
- int32_t logicalRight;
- int32_t logicalBottom;
- int32_t physicalLeft;
- int32_t physicalTop;
- int32_t physicalRight;
- int32_t physicalBottom;
- int32_t deviceWidth;
- int32_t deviceHeight;
-
- DisplayViewport() :
- displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
- logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
- physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
- deviceWidth(0), deviceHeight(0) {
- }
-
- bool operator==(const DisplayViewport& other) const {
- return displayId == other.displayId
- && orientation == other.orientation
- && logicalLeft == other.logicalLeft
- && logicalTop == other.logicalTop
- && logicalRight == other.logicalRight
- && logicalBottom == other.logicalBottom
- && physicalLeft == other.physicalLeft
- && physicalTop == other.physicalTop
- && physicalRight == other.physicalRight
- && physicalBottom == other.physicalBottom
- && deviceWidth == other.deviceWidth
- && deviceHeight == other.deviceHeight;
- }
-
- bool operator!=(const DisplayViewport& other) const {
- return !(*this == other);
- }
-
- inline bool isValid() const {
- return displayId >= 0;
- }
-
- void setNonDisplayViewport(int32_t width, int32_t height) {
- displayId = ADISPLAY_ID_NONE;
- orientation = DISPLAY_ORIENTATION_0;
- logicalLeft = 0;
- logicalTop = 0;
- logicalRight = width;
- logicalBottom = height;
- physicalLeft = 0;
- physicalTop = 0;
- physicalRight = width;
- physicalBottom = height;
- deviceWidth = width;
- deviceHeight = height;
- }
-};
-
-/*
- * Input reader configuration.
- *
- * Specifies various options that modify the behavior of the input reader.
- */
-struct InputReaderConfiguration {
- // Describes changes that have occurred.
- enum {
- // The pointer speed changed.
- CHANGE_POINTER_SPEED = 1 << 0,
-
- // The pointer gesture control changed.
- CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
-
- // The display size or orientation changed.
- CHANGE_DISPLAY_INFO = 1 << 2,
-
- // The visible touches option changed.
- CHANGE_SHOW_TOUCHES = 1 << 3,
-
- // The keyboard layouts must be reloaded.
- CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
-
- // The device name alias supplied by the may have changed for some devices.
- CHANGE_DEVICE_ALIAS = 1 << 5,
-
- // All devices must be reopened.
- CHANGE_MUST_REOPEN = 1 << 31,
- };
-
- // Gets the amount of time to disable virtual keys after the screen is touched
- // in order to filter out accidental virtual key presses due to swiping gestures
- // or taps near the edge of the display. May be 0 to disable the feature.
- nsecs_t virtualKeyQuietTime;
-
- // The excluded device names for the platform.
- // Devices with these names will be ignored.
- Vector<String8> excludedDeviceNames;
-
- // Velocity control parameters for mouse pointer movements.
- VelocityControlParameters pointerVelocityControlParameters;
-
- // Velocity control parameters for mouse wheel movements.
- VelocityControlParameters wheelVelocityControlParameters;
-
- // True if pointer gestures are enabled.
- bool pointerGesturesEnabled;
-
- // Quiet time between certain pointer gesture transitions.
- // Time to allow for all fingers or buttons to settle into a stable state before
- // starting a new gesture.
- nsecs_t pointerGestureQuietInterval;
-
- // The minimum speed that a pointer must travel for us to consider switching the active
- // touch pointer to it during a drag. This threshold is set to avoid switching due
- // to noise from a finger resting on the touch pad (perhaps just pressing it down).
- float pointerGestureDragMinSwitchSpeed; // in pixels per second
-
- // Tap gesture delay time.
- // The time between down and up must be less than this to be considered a tap.
- nsecs_t pointerGestureTapInterval;
-
- // Tap drag gesture delay time.
- // The time between the previous tap's up and the next down must be less than
- // this to be considered a drag. Otherwise, the previous tap is finished and a
- // new tap begins.
- //
- // Note that the previous tap will be held down for this entire duration so this
- // interval must be shorter than the long press timeout.
- nsecs_t pointerGestureTapDragInterval;
-
- // The distance in pixels that the pointer is allowed to move from initial down
- // to up and still be called a tap.
- float pointerGestureTapSlop; // in pixels
-
- // Time after the first touch points go down to settle on an initial centroid.
- // This is intended to be enough time to handle cases where the user puts down two
- // fingers at almost but not quite exactly the same time.
- nsecs_t pointerGestureMultitouchSettleInterval;
-
- // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
- // at least two pointers have moved at least this far from their starting place.
- float pointerGestureMultitouchMinDistance; // in pixels
-
- // The transition from PRESS to SWIPE gesture mode can only occur when the
- // cosine of the angle between the two vectors is greater than or equal to than this value
- // which indicates that the vectors are oriented in the same direction.
- // When the vectors are oriented in the exactly same direction, the cosine is 1.0.
- // (In exactly opposite directions, the cosine is -1.0.)
- float pointerGestureSwipeTransitionAngleCosine;
-
- // The transition from PRESS to SWIPE gesture mode can only occur when the
- // fingers are no more than this far apart relative to the diagonal size of
- // the touch pad. For example, a ratio of 0.5 means that the fingers must be
- // no more than half the diagonal size of the touch pad apart.
- float pointerGestureSwipeMaxWidthRatio;
-
- // The gesture movement speed factor relative to the size of the display.
- // Movement speed applies when the fingers are moving in the same direction.
- // Without acceleration, a full swipe of the touch pad diagonal in movement mode
- // will cover this portion of the display diagonal.
- float pointerGestureMovementSpeedRatio;
-
- // The gesture zoom speed factor relative to the size of the display.
- // Zoom speed applies when the fingers are mostly moving relative to each other
- // to execute a scale gesture or similar.
- // Without acceleration, a full swipe of the touch pad diagonal in zoom mode
- // will cover this portion of the display diagonal.
- float pointerGestureZoomSpeedRatio;
-
- // True to show the location of touches on the touch screen as spots.
- bool showTouches;
-
- InputReaderConfiguration() :
- virtualKeyQuietTime(0),
- pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
- wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
- pointerGesturesEnabled(true),
- pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
- pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
- pointerGestureTapInterval(150 * 1000000LL), // 150 ms
- pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
- pointerGestureTapSlop(10.0f), // 10 pixels
- pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
- pointerGestureMultitouchMinDistance(15), // 15 pixels
- pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
- pointerGestureSwipeMaxWidthRatio(0.25f),
- pointerGestureMovementSpeedRatio(0.8f),
- pointerGestureZoomSpeedRatio(0.3f),
- showTouches(false) { }
-
- bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
- void setDisplayInfo(bool external, const DisplayViewport& viewport);
-
-private:
- DisplayViewport mInternalDisplay;
- DisplayViewport mExternalDisplay;
-};
-
-
-/*
- * Input reader policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI. This interface is also mocked in the unit tests.
- *
- * These methods must NOT re-enter the input reader since they may be called while
- * holding the input reader lock.
- */
-class InputReaderPolicyInterface : public virtual RefBase {
-protected:
- InputReaderPolicyInterface() { }
- virtual ~InputReaderPolicyInterface() { }
-
-public:
- /* Gets the input reader configuration. */
- virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
-
- /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
- virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
-
- /* Notifies the input reader policy that some input devices have changed
- * and provides information about all current input devices.
- */
- virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
-
- /* Gets the keyboard layout for a particular input device. */
- virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) = 0;
-
- /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
- virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
-};
-
-
-/* Processes raw input events and sends cooked event data to an input listener. */
-class InputReaderInterface : public virtual RefBase {
-protected:
- InputReaderInterface() { }
- virtual ~InputReaderInterface() { }
-
-public:
- /* Dumps the state of the input reader.
- *
- * This method may be called on any thread (usually by the input manager). */
- virtual void dump(String8& dump) = 0;
-
- /* Called by the heatbeat to ensures that the reader has not deadlocked. */
- virtual void monitor() = 0;
-
- /* Runs a single iteration of the processing loop.
- * Nominally reads and processes one incoming message from the EventHub.
- *
- * This method should be called on the input reader thread.
- */
- virtual void loopOnce() = 0;
-
- /* Gets information about all input devices.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0;
-
- /* Query current input state. */
- virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t scanCode) = 0;
- virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t keyCode) = 0;
- virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
- int32_t sw) = 0;
-
- /* Determine whether physical keys exist for the given framework-domain key codes. */
- virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
- size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
-
- /* Requests that a reconfiguration of all input devices.
- * The changes flag is a bitfield that indicates what has changed and whether
- * the input devices must all be reopened. */
- virtual void requestRefreshConfiguration(uint32_t changes) = 0;
-
- /* Controls the vibrator of a particular input device. */
- virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
- ssize_t repeat, int32_t token) = 0;
- virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;
-};
-
-
-/* Internal interface used by individual input devices to access global input device state
- * and parameters maintained by the input reader.
- */
-class InputReaderContext {
-public:
- InputReaderContext() { }
- virtual ~InputReaderContext() { }
-
- virtual void updateGlobalMetaState() = 0;
- virtual int32_t getGlobalMetaState() = 0;
-
- virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
- virtual bool shouldDropVirtualKey(nsecs_t now,
- InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
-
- virtual void fadePointer() = 0;
-
- virtual void requestTimeoutAtTime(nsecs_t when) = 0;
- virtual int32_t bumpGeneration() = 0;
-
- virtual InputReaderPolicyInterface* getPolicy() = 0;
- virtual InputListenerInterface* getListener() = 0;
- virtual EventHubInterface* getEventHub() = 0;
-};
-
-
-/* The input reader reads raw event data from the event hub and processes it into input events
- * that it sends to the input listener. Some functions of the input reader, such as early
- * event filtering in low power states, are controlled by a separate policy object.
- *
- * The InputReader owns a collection of InputMappers. Most of the work it does happens
- * on the input reader thread but the InputReader can receive queries from other system
- * components running on arbitrary threads. To keep things manageable, the InputReader
- * uses a single Mutex to guard its state. The Mutex may be held while calling into the
- * EventHub or the InputReaderPolicy but it is never held while calling into the
- * InputListener.
- */
-class InputReader : public InputReaderInterface {
-public:
- InputReader(const sp<EventHubInterface>& eventHub,
- const sp<InputReaderPolicyInterface>& policy,
- const sp<InputListenerInterface>& listener);
- virtual ~InputReader();
-
- virtual void dump(String8& dump);
- virtual void monitor();
-
- virtual void loopOnce();
-
- virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices);
-
- virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t scanCode);
- virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t keyCode);
- virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
- int32_t sw);
-
- virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
- size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
-
- virtual void requestRefreshConfiguration(uint32_t changes);
-
- virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
- ssize_t repeat, int32_t token);
- virtual void cancelVibrate(int32_t deviceId, int32_t token);
-
-protected:
- // These members are protected so they can be instrumented by test cases.
- virtual InputDevice* createDeviceLocked(int32_t deviceId,
- const InputDeviceIdentifier& identifier, uint32_t classes);
-
- class ContextImpl : public InputReaderContext {
- InputReader* mReader;
-
- public:
- ContextImpl(InputReader* reader);
-
- virtual void updateGlobalMetaState();
- virtual int32_t getGlobalMetaState();
- virtual void disableVirtualKeysUntil(nsecs_t time);
- virtual bool shouldDropVirtualKey(nsecs_t now,
- InputDevice* device, int32_t keyCode, int32_t scanCode);
- virtual void fadePointer();
- virtual void requestTimeoutAtTime(nsecs_t when);
- virtual int32_t bumpGeneration();
- virtual InputReaderPolicyInterface* getPolicy();
- virtual InputListenerInterface* getListener();
- virtual EventHubInterface* getEventHub();
- } mContext;
-
- friend class ContextImpl;
-
-private:
- Mutex mLock;
-
- Condition mReaderIsAliveCondition;
-
- sp<EventHubInterface> mEventHub;
- sp<InputReaderPolicyInterface> mPolicy;
- sp<QueuedInputListener> mQueuedListener;
-
- InputReaderConfiguration mConfig;
-
- // The event queue.
- static const int EVENT_BUFFER_SIZE = 256;
- RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
-
- KeyedVector<int32_t, InputDevice*> mDevices;
-
- // low-level input event decoding and device management
- void processEventsLocked(const RawEvent* rawEvents, size_t count);
-
- void addDeviceLocked(nsecs_t when, int32_t deviceId);
- void removeDeviceLocked(nsecs_t when, int32_t deviceId);
- void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
- void timeoutExpiredLocked(nsecs_t when);
-
- void handleConfigurationChangedLocked(nsecs_t when);
-
- int32_t mGlobalMetaState;
- void updateGlobalMetaStateLocked();
- int32_t getGlobalMetaStateLocked();
-
- void fadePointerLocked();
-
- int32_t mGeneration;
- int32_t bumpGenerationLocked();
-
- void getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices);
-
- nsecs_t mDisableVirtualKeysTimeout;
- void disableVirtualKeysUntilLocked(nsecs_t time);
- bool shouldDropVirtualKeyLocked(nsecs_t now,
- InputDevice* device, int32_t keyCode, int32_t scanCode);
-
- nsecs_t mNextTimeout;
- void requestTimeoutAtTimeLocked(nsecs_t when);
-
- uint32_t mConfigurationChangesToRefresh;
- void refreshConfigurationLocked(uint32_t changes);
-
- // state queries
- typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
- int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
- GetStateFunc getStateFunc);
- bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags);
-};
-
-
-/* Reads raw events from the event hub and processes them, endlessly. */
-class InputReaderThread : public Thread {
-public:
- InputReaderThread(const sp<InputReaderInterface>& reader);
- virtual ~InputReaderThread();
-
-private:
- uint32_t mFoo;
- sp<InputReaderInterface> mReader;
-
- virtual bool threadLoop();
-};
-
-
-/* Represents the state of a single input device. */
-class InputDevice {
-public:
- InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
- const InputDeviceIdentifier& identifier, uint32_t classes);
- ~InputDevice();
-
- inline InputReaderContext* getContext() { return mContext; }
- inline int32_t getId() { return mId; }
- inline int32_t getGeneration() { return mGeneration; }
- inline const String8& getName() { return mIdentifier.name; }
- inline uint32_t getClasses() { return mClasses; }
- inline uint32_t getSources() { return mSources; }
-
- inline bool isExternal() { return mIsExternal; }
- inline void setExternal(bool external) { mIsExternal = external; }
-
- inline bool isIgnored() { return mMappers.isEmpty(); }
-
- void dump(String8& dump);
- void addMapper(InputMapper* mapper);
- void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- void reset(nsecs_t when);
- void process(const RawEvent* rawEvents, size_t count);
- void timeoutExpired(nsecs_t when);
-
- void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
- int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
- int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
- int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
- bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags);
- void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token);
- void cancelVibrate(int32_t token);
-
- int32_t getMetaState();
-
- void fadePointer();
-
- void bumpGeneration();
-
- void notifyReset(nsecs_t when);
-
- inline const PropertyMap& getConfiguration() { return mConfiguration; }
- inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
-
- bool hasKey(int32_t code) {
- return getEventHub()->hasScanCode(mId, code);
- }
-
- bool hasAbsoluteAxis(int32_t code) {
- RawAbsoluteAxisInfo info;
- getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
- return info.valid;
- }
-
- bool isKeyPressed(int32_t code) {
- return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
- }
-
- int32_t getAbsoluteAxisValue(int32_t code) {
- int32_t value;
- getEventHub()->getAbsoluteAxisValue(mId, code, &value);
- return value;
- }
-
-private:
- InputReaderContext* mContext;
- int32_t mId;
- int32_t mGeneration;
- InputDeviceIdentifier mIdentifier;
- String8 mAlias;
- uint32_t mClasses;
-
- Vector<InputMapper*> mMappers;
-
- uint32_t mSources;
- bool mIsExternal;
- bool mDropUntilNextSync;
-
- typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
- int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
-
- PropertyMap mConfiguration;
-};
-
-
-/* Keeps track of the state of mouse or touch pad buttons. */
-class CursorButtonAccumulator {
-public:
- CursorButtonAccumulator();
- void reset(InputDevice* device);
-
- void process(const RawEvent* rawEvent);
-
- uint32_t getButtonState() const;
-
-private:
- bool mBtnLeft;
- bool mBtnRight;
- bool mBtnMiddle;
- bool mBtnBack;
- bool mBtnSide;
- bool mBtnForward;
- bool mBtnExtra;
- bool mBtnTask;
-
- void clearButtons();
-};
-
-
-/* Keeps track of cursor movements. */
-
-class CursorMotionAccumulator {
-public:
- CursorMotionAccumulator();
- void reset(InputDevice* device);
-
- void process(const RawEvent* rawEvent);
- void finishSync();
-
- inline int32_t getRelativeX() const { return mRelX; }
- inline int32_t getRelativeY() const { return mRelY; }
-
-private:
- int32_t mRelX;
- int32_t mRelY;
-
- void clearRelativeAxes();
-};
-
-
-/* Keeps track of cursor scrolling motions. */
-
-class CursorScrollAccumulator {
-public:
- CursorScrollAccumulator();
- void configure(InputDevice* device);
- void reset(InputDevice* device);
-
- void process(const RawEvent* rawEvent);
- void finishSync();
-
- inline bool haveRelativeVWheel() const { return mHaveRelWheel; }
- inline bool haveRelativeHWheel() const { return mHaveRelHWheel; }
-
- inline int32_t getRelativeX() const { return mRelX; }
- inline int32_t getRelativeY() const { return mRelY; }
- inline int32_t getRelativeVWheel() const { return mRelWheel; }
- inline int32_t getRelativeHWheel() const { return mRelHWheel; }
-
-private:
- bool mHaveRelWheel;
- bool mHaveRelHWheel;
-
- int32_t mRelX;
- int32_t mRelY;
- int32_t mRelWheel;
- int32_t mRelHWheel;
-
- void clearRelativeAxes();
-};
-
-
-/* Keeps track of the state of touch, stylus and tool buttons. */
-class TouchButtonAccumulator {
-public:
- TouchButtonAccumulator();
- void configure(InputDevice* device);
- void reset(InputDevice* device);
-
- void process(const RawEvent* rawEvent);
-
- uint32_t getButtonState() const;
- int32_t getToolType() const;
- bool isToolActive() const;
- bool isHovering() const;
- bool hasStylus() const;
-
-private:
- bool mHaveBtnTouch;
- bool mHaveStylus;
-
- bool mBtnTouch;
- bool mBtnStylus;
- bool mBtnStylus2;
- bool mBtnToolFinger;
- bool mBtnToolPen;
- bool mBtnToolRubber;
- bool mBtnToolBrush;
- bool mBtnToolPencil;
- bool mBtnToolAirbrush;
- bool mBtnToolMouse;
- bool mBtnToolLens;
- bool mBtnToolDoubleTap;
- bool mBtnToolTripleTap;
- bool mBtnToolQuadTap;
-
- void clearButtons();
-};
-
-
-/* Raw axis information from the driver. */
-struct RawPointerAxes {
- RawAbsoluteAxisInfo x;
- RawAbsoluteAxisInfo y;
- RawAbsoluteAxisInfo pressure;
- RawAbsoluteAxisInfo touchMajor;
- RawAbsoluteAxisInfo touchMinor;
- RawAbsoluteAxisInfo toolMajor;
- RawAbsoluteAxisInfo toolMinor;
- RawAbsoluteAxisInfo orientation;
- RawAbsoluteAxisInfo distance;
- RawAbsoluteAxisInfo tiltX;
- RawAbsoluteAxisInfo tiltY;
- RawAbsoluteAxisInfo trackingId;
- RawAbsoluteAxisInfo slot;
-
- RawPointerAxes();
- void clear();
-};
-
-
-/* Raw data for a collection of pointers including a pointer id mapping table. */
-struct RawPointerData {
- struct Pointer {
- uint32_t id;
- int32_t x;
- int32_t y;
- int32_t pressure;
- int32_t touchMajor;
- int32_t touchMinor;
- int32_t toolMajor;
- int32_t toolMinor;
- int32_t orientation;
- int32_t distance;
- int32_t tiltX;
- int32_t tiltY;
- int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
- bool isHovering;
- };
-
- uint32_t pointerCount;
- Pointer pointers[MAX_POINTERS];
- BitSet32 hoveringIdBits, touchingIdBits;
- uint32_t idToIndex[MAX_POINTER_ID + 1];
-
- RawPointerData();
- void clear();
- void copyFrom(const RawPointerData& other);
- void getCentroidOfTouchingPointers(float* outX, float* outY) const;
-
- inline void markIdBit(uint32_t id, bool isHovering) {
- if (isHovering) {
- hoveringIdBits.markBit(id);
- } else {
- touchingIdBits.markBit(id);
- }
- }
-
- inline void clearIdBits() {
- hoveringIdBits.clear();
- touchingIdBits.clear();
- }
-
- inline const Pointer& pointerForId(uint32_t id) const {
- return pointers[idToIndex[id]];
- }
-
- inline bool isHovering(uint32_t pointerIndex) {
- return pointers[pointerIndex].isHovering;
- }
-};
-
-
-/* Cooked data for a collection of pointers including a pointer id mapping table. */
-struct CookedPointerData {
- uint32_t pointerCount;
- PointerProperties pointerProperties[MAX_POINTERS];
- PointerCoords pointerCoords[MAX_POINTERS];
- BitSet32 hoveringIdBits, touchingIdBits;
- uint32_t idToIndex[MAX_POINTER_ID + 1];
-
- CookedPointerData();
- void clear();
- void copyFrom(const CookedPointerData& other);
-
- inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
- return pointerCoords[idToIndex[id]];
- }
-
- inline bool isHovering(uint32_t pointerIndex) {
- return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
- }
-};
-
-
-/* Keeps track of the state of single-touch protocol. */
-class SingleTouchMotionAccumulator {
-public:
- SingleTouchMotionAccumulator();
-
- void process(const RawEvent* rawEvent);
- void reset(InputDevice* device);
-
- inline int32_t getAbsoluteX() const { return mAbsX; }
- inline int32_t getAbsoluteY() const { return mAbsY; }
- inline int32_t getAbsolutePressure() const { return mAbsPressure; }
- inline int32_t getAbsoluteToolWidth() const { return mAbsToolWidth; }
- inline int32_t getAbsoluteDistance() const { return mAbsDistance; }
- inline int32_t getAbsoluteTiltX() const { return mAbsTiltX; }
- inline int32_t getAbsoluteTiltY() const { return mAbsTiltY; }
-
-private:
- int32_t mAbsX;
- int32_t mAbsY;
- int32_t mAbsPressure;
- int32_t mAbsToolWidth;
- int32_t mAbsDistance;
- int32_t mAbsTiltX;
- int32_t mAbsTiltY;
-
- void clearAbsoluteAxes();
-};
-
-
-/* Keeps track of the state of multi-touch protocol. */
-class MultiTouchMotionAccumulator {
-public:
- class Slot {
- public:
- inline bool isInUse() const { return mInUse; }
- inline int32_t getX() const { return mAbsMTPositionX; }
- inline int32_t getY() const { return mAbsMTPositionY; }
- inline int32_t getTouchMajor() const { return mAbsMTTouchMajor; }
- inline int32_t getTouchMinor() const {
- return mHaveAbsMTTouchMinor ? mAbsMTTouchMinor : mAbsMTTouchMajor; }
- inline int32_t getToolMajor() const { return mAbsMTWidthMajor; }
- inline int32_t getToolMinor() const {
- return mHaveAbsMTWidthMinor ? mAbsMTWidthMinor : mAbsMTWidthMajor; }
- inline int32_t getOrientation() const { return mAbsMTOrientation; }
- inline int32_t getTrackingId() const { return mAbsMTTrackingId; }
- inline int32_t getPressure() const { return mAbsMTPressure; }
- inline int32_t getDistance() const { return mAbsMTDistance; }
- inline int32_t getToolType() const;
-
- private:
- friend class MultiTouchMotionAccumulator;
-
- bool mInUse;
- bool mHaveAbsMTTouchMinor;
- bool mHaveAbsMTWidthMinor;
- bool mHaveAbsMTToolType;
-
- int32_t mAbsMTPositionX;
- int32_t mAbsMTPositionY;
- int32_t mAbsMTTouchMajor;
- int32_t mAbsMTTouchMinor;
- int32_t mAbsMTWidthMajor;
- int32_t mAbsMTWidthMinor;
- int32_t mAbsMTOrientation;
- int32_t mAbsMTTrackingId;
- int32_t mAbsMTPressure;
- int32_t mAbsMTDistance;
- int32_t mAbsMTToolType;
-
- Slot();
- void clear();
- };
-
- MultiTouchMotionAccumulator();
- ~MultiTouchMotionAccumulator();
-
- void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
- void reset(InputDevice* device);
- void process(const RawEvent* rawEvent);
- void finishSync();
- bool hasStylus() const;
-
- inline size_t getSlotCount() const { return mSlotCount; }
- inline const Slot* getSlot(size_t index) const { return &mSlots[index]; }
-
-private:
- int32_t mCurrentSlot;
- Slot* mSlots;
- size_t mSlotCount;
- bool mUsingSlotsProtocol;
- bool mHaveStylus;
-
- void clearSlots(int32_t initialSlot);
-};
-
-
-/* An input mapper transforms raw input events into cooked event data.
- * A single input device can have multiple associated input mappers in order to interpret
- * different classes of events.
- *
- * InputMapper lifecycle:
- * - create
- * - configure with 0 changes
- * - reset
- * - process, process, process (may occasionally reconfigure with non-zero changes or reset)
- * - reset
- * - destroy
- */
-class InputMapper {
-public:
- InputMapper(InputDevice* device);
- virtual ~InputMapper();
-
- inline InputDevice* getDevice() { return mDevice; }
- inline int32_t getDeviceId() { return mDevice->getId(); }
- inline const String8 getDeviceName() { return mDevice->getName(); }
- inline InputReaderContext* getContext() { return mContext; }
- inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
- inline InputListenerInterface* getListener() { return mContext->getListener(); }
- inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
-
- virtual uint32_t getSources() = 0;
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void dump(String8& dump);
- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent) = 0;
- virtual void timeoutExpired(nsecs_t when);
-
- virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
- virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
- virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
- virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags);
- virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token);
- virtual void cancelVibrate(int32_t token);
-
- virtual int32_t getMetaState();
-
- virtual void fadePointer();
-
-protected:
- InputDevice* mDevice;
- InputReaderContext* mContext;
-
- status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
- void bumpGeneration();
-
- static void dumpRawAbsoluteAxisInfo(String8& dump,
- const RawAbsoluteAxisInfo& axis, const char* name);
-};
-
-
-class SwitchInputMapper : public InputMapper {
-public:
- SwitchInputMapper(InputDevice* device);
- virtual ~SwitchInputMapper();
-
- virtual uint32_t getSources();
- virtual void process(const RawEvent* rawEvent);
-
- virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-
-private:
- uint32_t mUpdatedSwitchValues;
- uint32_t mUpdatedSwitchMask;
-
- void processSwitch(int32_t switchCode, int32_t switchValue);
- void sync(nsecs_t when);
-};
-
-
-class VibratorInputMapper : public InputMapper {
-public:
- VibratorInputMapper(InputDevice* device);
- virtual ~VibratorInputMapper();
-
- virtual uint32_t getSources();
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void process(const RawEvent* rawEvent);
-
- virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
- int32_t token);
- virtual void cancelVibrate(int32_t token);
- virtual void timeoutExpired(nsecs_t when);
- virtual void dump(String8& dump);
-
-private:
- bool mVibrating;
- nsecs_t mPattern[MAX_VIBRATE_PATTERN_SIZE];
- size_t mPatternSize;
- ssize_t mRepeat;
- int32_t mToken;
- ssize_t mIndex;
- nsecs_t mNextStepTime;
-
- void nextStep();
- void stopVibrating();
-};
-
-
-class KeyboardInputMapper : public InputMapper {
-public:
- KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
- virtual ~KeyboardInputMapper();
-
- virtual uint32_t getSources();
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void dump(String8& dump);
- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
- virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
- virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
- virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags);
-
- virtual int32_t getMetaState();
-
-private:
- struct KeyDown {
- int32_t keyCode;
- int32_t scanCode;
- };
-
- uint32_t mSource;
- int32_t mKeyboardType;
-
- int32_t mOrientation; // orientation for dpad keys
-
- Vector<KeyDown> mKeyDowns; // keys that are down
- int32_t mMetaState;
- nsecs_t mDownTime; // time of most recent key down
-
- int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none
-
- struct LedState {
- bool avail; // led is available
- bool on; // we think the led is currently on
- };
- LedState mCapsLockLedState;
- LedState mNumLockLedState;
- LedState mScrollLockLedState;
-
- // Immutable configuration parameters.
- struct Parameters {
- bool hasAssociatedDisplay;
- bool orientationAware;
- } mParameters;
-
- void configureParameters();
- void dumpParameters(String8& dump);
-
- bool isKeyboardOrGamepadKey(int32_t scanCode);
-
- void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
- uint32_t policyFlags);
-
- ssize_t findKeyDown(int32_t scanCode);
-
- void resetLedState();
- void initializeLedState(LedState& ledState, int32_t led);
- void updateLedState(bool reset);
- void updateLedStateForModifier(LedState& ledState, int32_t led,
- int32_t modifier, bool reset);
-};
-
-
-class CursorInputMapper : public InputMapper {
-public:
- CursorInputMapper(InputDevice* device);
- virtual ~CursorInputMapper();
-
- virtual uint32_t getSources();
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void dump(String8& dump);
- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
- virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-
- virtual void fadePointer();
-
-private:
- // Amount that trackball needs to move in order to generate a key event.
- static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
- // Immutable configuration parameters.
- struct Parameters {
- enum Mode {
- MODE_POINTER,
- MODE_NAVIGATION,
- };
-
- Mode mode;
- bool hasAssociatedDisplay;
- bool orientationAware;
- } mParameters;
-
- CursorButtonAccumulator mCursorButtonAccumulator;
- CursorMotionAccumulator mCursorMotionAccumulator;
- CursorScrollAccumulator mCursorScrollAccumulator;
-
- int32_t mSource;
- float mXScale;
- float mYScale;
- float mXPrecision;
- float mYPrecision;
-
- float mVWheelScale;
- float mHWheelScale;
-
- // Velocity controls for mouse pointer and wheel movements.
- // The controls for X and Y wheel movements are separate to keep them decoupled.
- VelocityControl mPointerVelocityControl;
- VelocityControl mWheelXVelocityControl;
- VelocityControl mWheelYVelocityControl;
-
- int32_t mOrientation;
-
- sp<PointerControllerInterface> mPointerController;
-
- int32_t mButtonState;
- nsecs_t mDownTime;
-
- void configureParameters();
- void dumpParameters(String8& dump);
-
- void sync(nsecs_t when);
-};
-
-
-class TouchInputMapper : public InputMapper {
-public:
- TouchInputMapper(InputDevice* device);
- virtual ~TouchInputMapper();
-
- virtual uint32_t getSources();
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void dump(String8& dump);
- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
- virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
- virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
- virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags);
-
- virtual void fadePointer();
- virtual void timeoutExpired(nsecs_t when);
-
-protected:
- CursorButtonAccumulator mCursorButtonAccumulator;
- CursorScrollAccumulator mCursorScrollAccumulator;
- TouchButtonAccumulator mTouchButtonAccumulator;
-
- struct VirtualKey {
- int32_t keyCode;
- int32_t scanCode;
- uint32_t flags;
-
- // computed hit box, specified in touch screen coords based on known display size
- int32_t hitLeft;
- int32_t hitTop;
- int32_t hitRight;
- int32_t hitBottom;
-
- inline bool isHit(int32_t x, int32_t y) const {
- return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
- }
- };
-
- // Input sources and device mode.
- uint32_t mSource;
-
- enum DeviceMode {
- DEVICE_MODE_DISABLED, // input is disabled
- DEVICE_MODE_DIRECT, // direct mapping (touchscreen)
- DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad)
- DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
- DEVICE_MODE_POINTER, // pointer mapping (pointer)
- };
- DeviceMode mDeviceMode;
-
- // The reader's configuration.
- InputReaderConfiguration mConfig;
-
- // Immutable configuration parameters.
- struct Parameters {
- enum DeviceType {
- DEVICE_TYPE_TOUCH_SCREEN,
- DEVICE_TYPE_TOUCH_PAD,
- DEVICE_TYPE_TOUCH_NAVIGATION,
- DEVICE_TYPE_POINTER,
- };
-
- DeviceType deviceType;
- bool hasAssociatedDisplay;
- bool associatedDisplayIsExternal;
- bool orientationAware;
-
- enum GestureMode {
- GESTURE_MODE_POINTER,
- GESTURE_MODE_SPOTS,
- };
- GestureMode gestureMode;
- } mParameters;
-
- // Immutable calibration parameters in parsed form.
- struct Calibration {
- // Size
- enum SizeCalibration {
- SIZE_CALIBRATION_DEFAULT,
- SIZE_CALIBRATION_NONE,
- SIZE_CALIBRATION_GEOMETRIC,
- SIZE_CALIBRATION_DIAMETER,
- SIZE_CALIBRATION_BOX,
- SIZE_CALIBRATION_AREA,
- };
-
- SizeCalibration sizeCalibration;
-
- bool haveSizeScale;
- float sizeScale;
- bool haveSizeBias;
- float sizeBias;
- bool haveSizeIsSummed;
- bool sizeIsSummed;
-
- // Pressure
- enum PressureCalibration {
- PRESSURE_CALIBRATION_DEFAULT,
- PRESSURE_CALIBRATION_NONE,
- PRESSURE_CALIBRATION_PHYSICAL,
- PRESSURE_CALIBRATION_AMPLITUDE,
- };
-
- PressureCalibration pressureCalibration;
- bool havePressureScale;
- float pressureScale;
-
- // Orientation
- enum OrientationCalibration {
- ORIENTATION_CALIBRATION_DEFAULT,
- ORIENTATION_CALIBRATION_NONE,
- ORIENTATION_CALIBRATION_INTERPOLATED,
- ORIENTATION_CALIBRATION_VECTOR,
- };
-
- OrientationCalibration orientationCalibration;
-
- // Distance
- enum DistanceCalibration {
- DISTANCE_CALIBRATION_DEFAULT,
- DISTANCE_CALIBRATION_NONE,
- DISTANCE_CALIBRATION_SCALED,
- };
-
- DistanceCalibration distanceCalibration;
- bool haveDistanceScale;
- float distanceScale;
-
- enum CoverageCalibration {
- COVERAGE_CALIBRATION_DEFAULT,
- COVERAGE_CALIBRATION_NONE,
- COVERAGE_CALIBRATION_BOX,
- };
-
- CoverageCalibration coverageCalibration;
-
- inline void applySizeScaleAndBias(float* outSize) const {
- if (haveSizeScale) {
- *outSize *= sizeScale;
- }
- if (haveSizeBias) {
- *outSize += sizeBias;
- }
- }
- } mCalibration;
-
- // Raw pointer axis information from the driver.
- RawPointerAxes mRawPointerAxes;
-
- // Raw pointer sample data.
- RawPointerData mCurrentRawPointerData;
- RawPointerData mLastRawPointerData;
-
- // Cooked pointer sample data.
- CookedPointerData mCurrentCookedPointerData;
- CookedPointerData mLastCookedPointerData;
-
- // Button state.
- int32_t mCurrentButtonState;
- int32_t mLastButtonState;
-
- // Scroll state.
- int32_t mCurrentRawVScroll;
- int32_t mCurrentRawHScroll;
-
- // Id bits used to differentiate fingers, stylus and mouse tools.
- BitSet32 mCurrentFingerIdBits; // finger or unknown
- BitSet32 mLastFingerIdBits;
- BitSet32 mCurrentStylusIdBits; // stylus or eraser
- BitSet32 mLastStylusIdBits;
- BitSet32 mCurrentMouseIdBits; // mouse or lens
- BitSet32 mLastMouseIdBits;
-
- // True if we sent a HOVER_ENTER event.
- bool mSentHoverEnter;
-
- // The time the primary pointer last went down.
- nsecs_t mDownTime;
-
- // The pointer controller, or null if the device is not a pointer.
- sp<PointerControllerInterface> mPointerController;
-
- Vector<VirtualKey> mVirtualKeys;
-
- virtual void configureParameters();
- virtual void dumpParameters(String8& dump);
- virtual void configureRawPointerAxes();
- virtual void dumpRawPointerAxes(String8& dump);
- virtual void configureSurface(nsecs_t when, bool* outResetNeeded);
- virtual void dumpSurface(String8& dump);
- virtual void configureVirtualKeys();
- virtual void dumpVirtualKeys(String8& dump);
- virtual void parseCalibration();
- virtual void resolveCalibration();
- virtual void dumpCalibration(String8& dump);
- virtual bool hasStylus() const = 0;
-
- virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
-
-private:
- // The current viewport.
- // The components of the viewport are specified in the display's rotated orientation.
- DisplayViewport mViewport;
-
- // The surface orientation, width and height set by configureSurface().
- // The width and height are derived from the viewport but are specified
- // in the natural orientation.
- // The surface origin specifies how the surface coordinates should be translated
- // to align with the logical display coordinate space.
- // The orientation may be different from the viewport orientation as it specifies
- // the rotation of the surface coordinates required to produce the viewport's
- // requested orientation, so it will depend on whether the device is orientation aware.
- int32_t mSurfaceWidth;
- int32_t mSurfaceHeight;
- int32_t mSurfaceLeft;
- int32_t mSurfaceTop;
- int32_t mSurfaceOrientation;
-
- // Translation and scaling factors, orientation-independent.
- float mXTranslate;
- float mXScale;
- float mXPrecision;
-
- float mYTranslate;
- float mYScale;
- float mYPrecision;
-
- float mGeometricScale;
-
- float mPressureScale;
-
- float mSizeScale;
-
- float mOrientationScale;
-
- float mDistanceScale;
-
- bool mHaveTilt;
- float mTiltXCenter;
- float mTiltXScale;
- float mTiltYCenter;
- float mTiltYScale;
-
- // Oriented motion ranges for input device info.
- struct OrientedRanges {
- InputDeviceInfo::MotionRange x;
- InputDeviceInfo::MotionRange y;
- InputDeviceInfo::MotionRange pressure;
-
- bool haveSize;
- InputDeviceInfo::MotionRange size;
-
- bool haveTouchSize;
- InputDeviceInfo::MotionRange touchMajor;
- InputDeviceInfo::MotionRange touchMinor;
-
- bool haveToolSize;
- InputDeviceInfo::MotionRange toolMajor;
- InputDeviceInfo::MotionRange toolMinor;
-
- bool haveOrientation;
- InputDeviceInfo::MotionRange orientation;
-
- bool haveDistance;
- InputDeviceInfo::MotionRange distance;
-
- bool haveTilt;
- InputDeviceInfo::MotionRange tilt;
-
- OrientedRanges() {
- clear();
- }
-
- void clear() {
- haveSize = false;
- haveTouchSize = false;
- haveToolSize = false;
- haveOrientation = false;
- haveDistance = false;
- haveTilt = false;
- }
- } mOrientedRanges;
-
- // Oriented dimensions and precision.
- float mOrientedXPrecision;
- float mOrientedYPrecision;
-
- struct CurrentVirtualKeyState {
- bool down;
- bool ignored;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } mCurrentVirtualKey;
-
- // Scale factor for gesture or mouse based pointer movements.
- float mPointerXMovementScale;
- float mPointerYMovementScale;
-
- // Scale factor for gesture based zooming and other freeform motions.
- float mPointerXZoomScale;
- float mPointerYZoomScale;
-
- // The maximum swipe width.
- float mPointerGestureMaxSwipeWidth;
-
- struct PointerDistanceHeapElement {
- uint32_t currentPointerIndex : 8;
- uint32_t lastPointerIndex : 8;
- uint64_t distance : 48; // squared distance
- };
-
- enum PointerUsage {
- POINTER_USAGE_NONE,
- POINTER_USAGE_GESTURES,
- POINTER_USAGE_STYLUS,
- POINTER_USAGE_MOUSE,
- };
- PointerUsage mPointerUsage;
-
- struct PointerGesture {
- enum Mode {
- // No fingers, button is not pressed.
- // Nothing happening.
- NEUTRAL,
-
- // No fingers, button is not pressed.
- // Tap detected.
- // Emits DOWN and UP events at the pointer location.
- TAP,
-
- // Exactly one finger dragging following a tap.
- // Pointer follows the active finger.
- // Emits DOWN, MOVE and UP events at the pointer location.
- //
- // Detect double-taps when the finger goes up while in TAP_DRAG mode.
- TAP_DRAG,
-
- // Button is pressed.
- // Pointer follows the active finger if there is one. Other fingers are ignored.
- // Emits DOWN, MOVE and UP events at the pointer location.
- BUTTON_CLICK_OR_DRAG,
-
- // Exactly one finger, button is not pressed.
- // Pointer follows the active finger.
- // Emits HOVER_MOVE events at the pointer location.
- //
- // Detect taps when the finger goes up while in HOVER mode.
- HOVER,
-
- // Exactly two fingers but neither have moved enough to clearly indicate
- // whether a swipe or freeform gesture was intended. We consider the
- // pointer to be pressed so this enables clicking or long-pressing on buttons.
- // Pointer does not move.
- // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
- PRESS,
-
- // Exactly two fingers moving in the same direction, button is not pressed.
- // Pointer does not move.
- // Emits DOWN, MOVE and UP events with a single pointer coordinate that
- // follows the midpoint between both fingers.
- SWIPE,
-
- // Two or more fingers moving in arbitrary directions, button is not pressed.
- // Pointer does not move.
- // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
- // each finger individually relative to the initial centroid of the finger.
- FREEFORM,
-
- // Waiting for quiet time to end before starting the next gesture.
- QUIET,
- };
-
- // Time the first finger went down.
- nsecs_t firstTouchTime;
-
- // The active pointer id from the raw touch data.
- int32_t activeTouchId; // -1 if none
-
- // The active pointer id from the gesture last delivered to the application.
- int32_t activeGestureId; // -1 if none
-
- // Pointer coords and ids for the current and previous pointer gesture.
- Mode currentGestureMode;
- BitSet32 currentGestureIdBits;
- uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1];
- PointerProperties currentGestureProperties[MAX_POINTERS];
- PointerCoords currentGestureCoords[MAX_POINTERS];
-
- Mode lastGestureMode;
- BitSet32 lastGestureIdBits;
- uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1];
- PointerProperties lastGestureProperties[MAX_POINTERS];
- PointerCoords lastGestureCoords[MAX_POINTERS];
-
- // Time the pointer gesture last went down.
- nsecs_t downTime;
-
- // Time when the pointer went down for a TAP.
- nsecs_t tapDownTime;
-
- // Time when the pointer went up for a TAP.
- nsecs_t tapUpTime;
-
- // Location of initial tap.
- float tapX, tapY;
-
- // Time we started waiting for quiescence.
- nsecs_t quietTime;
-
- // Reference points for multitouch gestures.
- float referenceTouchX; // reference touch X/Y coordinates in surface units
- float referenceTouchY;
- float referenceGestureX; // reference gesture X/Y coordinates in pixels
- float referenceGestureY;
-
- // Distance that each pointer has traveled which has not yet been
- // subsumed into the reference gesture position.
- BitSet32 referenceIdBits;
- struct Delta {
- float dx, dy;
- };
- Delta referenceDeltas[MAX_POINTER_ID + 1];
-
- // Describes how touch ids are mapped to gesture ids for freeform gestures.
- uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
-
- // A velocity tracker for determining whether to switch active pointers during drags.
- VelocityTracker velocityTracker;
-
- void reset() {
- firstTouchTime = LLONG_MIN;
- activeTouchId = -1;
- activeGestureId = -1;
- currentGestureMode = NEUTRAL;
- currentGestureIdBits.clear();
- lastGestureMode = NEUTRAL;
- lastGestureIdBits.clear();
- downTime = 0;
- velocityTracker.clear();
- resetTap();
- resetQuietTime();
- }
-
- void resetTap() {
- tapDownTime = LLONG_MIN;
- tapUpTime = LLONG_MIN;
- }
-
- void resetQuietTime() {
- quietTime = LLONG_MIN;
- }
- } mPointerGesture;
-
- struct PointerSimple {
- PointerCoords currentCoords;
- PointerProperties currentProperties;
- PointerCoords lastCoords;
- PointerProperties lastProperties;
-
- // True if the pointer is down.
- bool down;
-
- // True if the pointer is hovering.
- bool hovering;
-
- // Time the pointer last went down.
- nsecs_t downTime;
-
- void reset() {
- currentCoords.clear();
- currentProperties.clear();
- lastCoords.clear();
- lastProperties.clear();
- down = false;
- hovering = false;
- downTime = 0;
- }
- } mPointerSimple;
-
- // The pointer and scroll velocity controls.
- VelocityControl mPointerVelocityControl;
- VelocityControl mWheelXVelocityControl;
- VelocityControl mWheelYVelocityControl;
-
- void sync(nsecs_t when);
-
- bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
- void dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
- int32_t keyEventAction, int32_t keyEventFlags);
-
- void dispatchTouches(nsecs_t when, uint32_t policyFlags);
- void dispatchHoverExit(nsecs_t when, uint32_t policyFlags);
- void dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags);
- void cookPointerData();
-
- void dispatchPointerUsage(nsecs_t when, uint32_t policyFlags, PointerUsage pointerUsage);
- void abortPointerUsage(nsecs_t when, uint32_t policyFlags);
-
- void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
- void abortPointerGestures(nsecs_t when, uint32_t policyFlags);
- bool preparePointerGestures(nsecs_t when,
- bool* outCancelPreviousGesture, bool* outFinishPreviousGesture,
- bool isTimeout);
-
- void dispatchPointerStylus(nsecs_t when, uint32_t policyFlags);
- void abortPointerStylus(nsecs_t when, uint32_t policyFlags);
-
- void dispatchPointerMouse(nsecs_t when, uint32_t policyFlags);
- void abortPointerMouse(nsecs_t when, uint32_t policyFlags);
-
- void dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
- bool down, bool hovering);
- void abortPointerSimple(nsecs_t when, uint32_t policyFlags);
-
- // Dispatches a motion event.
- // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
- // method will take care of setting the index and transmuting the action to DOWN or UP
- // it is the first / last pointer to go down / up.
- void dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
- int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
- int32_t edgeFlags,
- const PointerProperties* properties, const PointerCoords* coords,
- const uint32_t* idToIndex, BitSet32 idBits,
- int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
-
- // Updates pointer coords and properties for pointers with specified ids that have moved.
- // Returns true if any of them changed.
- bool updateMovedPointers(const PointerProperties* inProperties,
- const PointerCoords* inCoords, const uint32_t* inIdToIndex,
- PointerProperties* outProperties, PointerCoords* outCoords,
- const uint32_t* outIdToIndex, BitSet32 idBits) const;
-
- bool isPointInsideSurface(int32_t x, int32_t y);
- const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
-
- void assignPointerIds();
-};
-
-
-class SingleTouchInputMapper : public TouchInputMapper {
-public:
- SingleTouchInputMapper(InputDevice* device);
- virtual ~SingleTouchInputMapper();
-
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
-protected:
- virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
- virtual void configureRawPointerAxes();
- virtual bool hasStylus() const;
-
-private:
- SingleTouchMotionAccumulator mSingleTouchMotionAccumulator;
-};
-
-
-class MultiTouchInputMapper : public TouchInputMapper {
-public:
- MultiTouchInputMapper(InputDevice* device);
- virtual ~MultiTouchInputMapper();
-
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
-protected:
- virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
- virtual void configureRawPointerAxes();
- virtual bool hasStylus() const;
-
-private:
- MultiTouchMotionAccumulator mMultiTouchMotionAccumulator;
-
- // Specifies the pointer id bits that are in use, and their associated tracking id.
- BitSet32 mPointerIdBits;
- int32_t mPointerTrackingIdMap[MAX_POINTER_ID + 1];
-};
-
-
-class JoystickInputMapper : public InputMapper {
-public:
- JoystickInputMapper(InputDevice* device);
- virtual ~JoystickInputMapper();
-
- virtual uint32_t getSources();
- virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
- virtual void dump(String8& dump);
- virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
- virtual void reset(nsecs_t when);
- virtual void process(const RawEvent* rawEvent);
-
-private:
- struct Axis {
- RawAbsoluteAxisInfo rawAxisInfo;
- AxisInfo axisInfo;
-
- bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
-
- float scale; // scale factor from raw to normalized values
- float offset; // offset to add after scaling for normalization
- float highScale; // scale factor from raw to normalized values of high split
- float highOffset; // offset to add after scaling for normalization of high split
-
- float min; // normalized inclusive minimum
- float max; // normalized inclusive maximum
- float flat; // normalized flat region size
- float fuzz; // normalized error tolerance
- float resolution; // normalized resolution in units/mm
-
- float filter; // filter out small variations of this size
- float currentValue; // current value
- float newValue; // most recent value
- float highCurrentValue; // current value of high split
- float highNewValue; // most recent value of high split
-
- void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
- bool explicitlyMapped, float scale, float offset,
- float highScale, float highOffset,
- float min, float max, float flat, float fuzz, float resolution) {
- this->rawAxisInfo = rawAxisInfo;
- this->axisInfo = axisInfo;
- this->explicitlyMapped = explicitlyMapped;
- this->scale = scale;
- this->offset = offset;
- this->highScale = highScale;
- this->highOffset = highOffset;
- this->min = min;
- this->max = max;
- this->flat = flat;
- this->fuzz = fuzz;
- this->resolution = resolution;
- this->filter = 0;
- resetValue();
- }
-
- void resetValue() {
- this->currentValue = 0;
- this->newValue = 0;
- this->highCurrentValue = 0;
- this->highNewValue = 0;
- }
- };
-
- // Axes indexed by raw ABS_* axis index.
- KeyedVector<int32_t, Axis> mAxes;
-
- void sync(nsecs_t when, bool force);
-
- bool haveAxis(int32_t axisId);
- void pruneAxes(bool ignoreExplicitlyMappedAxes);
- bool filterAxes(bool force);
-
- static bool hasValueChangedSignificantly(float filter,
- float newValue, float currentValue, float min, float max);
- static bool hasMovedNearerToValueWithinFilteredRange(float filter,
- float newValue, float currentValue, float thresholdValue);
-
- static bool isCenteredAxis(int32_t axis);
- static int32_t getCompatAxis(int32_t axis);
-
- static void addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo* info);
- static void setPointerCoordsAxisValue(PointerCoords* pointerCoords, int32_t axis,
- float value);
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_READER_H
diff --git a/widget/gonk/libui/InputTransport.cpp b/widget/gonk/libui/InputTransport.cpp
deleted file mode 100644
index 3f0fcb047..000000000
--- a/widget/gonk/libui/InputTransport.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// Provides a shared memory transport for input events.
-//
-#define LOG_TAG "InputTransport"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about channel messages (send message, receive message)
-#define DEBUG_CHANNEL_MESSAGES 0
-
-// Log debug messages whenever InputChannel objects are created/destroyed
-#define DEBUG_CHANNEL_LIFECYCLE 0
-
-// Log debug messages about transport actions
-#define DEBUG_TRANSPORT_ACTIONS 0
-
-// Log debug messages about touch event resampling
-#define DEBUG_RESAMPLING 0
-
-
-#include "cutils_log.h"
-#include <cutils/properties.h>
-#include <errno.h>
-#include <fcntl.h>
-#include "InputTransport.h"
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <math.h>
-
-
-namespace android {
-
-// Socket buffer size. The default is typically about 128KB, which is much larger than
-// we really need. So we make it smaller. It just needs to be big enough to hold
-// a few dozen large multi-finger motion events in the case where an application gets
-// behind processing touches.
-static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Latency added during resampling. A few milliseconds doesn't hurt much but
-// reduces the impact of mispredicted touch positions.
-static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
-
-// Minimum time difference between consecutive samples before attempting to resample.
-static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
-
-// Maximum time to predict forward from the last known state, to avoid predicting too
-// far into the future. This time is further bounded by 50% of the last time delta.
-static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
- return a < b ? a : b;
-}
-
-inline static float lerp(float a, float b, float alpha) {
- return a + alpha * (b - a);
-}
-
-// --- InputMessage ---
-
-bool InputMessage::isValid(size_t actualSize) const {
- if (size() == actualSize) {
- switch (header.type) {
- case TYPE_KEY:
- return true;
- case TYPE_MOTION:
- return body.motion.pointerCount > 0
- && body.motion.pointerCount <= MAX_POINTERS;
- case TYPE_FINISHED:
- return true;
- }
- }
- return false;
-}
-
-size_t InputMessage::size() const {
- switch (header.type) {
- case TYPE_KEY:
- return sizeof(Header) + body.key.size();
- case TYPE_MOTION:
- return sizeof(Header) + body.motion.size();
- case TYPE_FINISHED:
- return sizeof(Header) + body.finished.size();
- }
- return sizeof(Header);
-}
-
-
-// --- InputChannel ---
-
-InputChannel::InputChannel(const String8& name, int fd) :
- mName(name), mFd(fd) {
-#if DEBUG_CHANNEL_LIFECYCLE
- ALOGD("Input channel constructed: name='%s', fd=%d",
- mName.string(), fd);
-#endif
-
- int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
- "non-blocking. errno=%d", mName.string(), errno);
-}
-
-InputChannel::~InputChannel() {
-#if DEBUG_CHANNEL_LIFECYCLE
- ALOGD("Input channel destroyed: name='%s', fd=%d",
- mName.string(), mFd);
-#endif
-
- ::close(mFd);
-}
-
-status_t InputChannel::openInputChannelPair(const String8& name,
- sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
- int sockets[2];
- if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
- status_t result = -errno;
- ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
- name.string(), errno);
- outServerChannel.clear();
- outClientChannel.clear();
- return result;
- }
-
- int bufferSize = SOCKET_BUFFER_SIZE;
- setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
- setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
- setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
- setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
-
- String8 serverChannelName = name;
- serverChannelName.append(" (server)");
- outServerChannel = new InputChannel(serverChannelName, sockets[0]);
-
- String8 clientChannelName = name;
- clientChannelName.append(" (client)");
- outClientChannel = new InputChannel(clientChannelName, sockets[1]);
- return OK;
-}
-
-status_t InputChannel::sendMessage(const InputMessage* msg) {
- size_t msgLength = msg->size();
- ssize_t nWrite;
- do {
- nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
- } while (nWrite == -1 && errno == EINTR);
-
- if (nWrite < 0) {
- int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
- msg->header.type, error);
-#endif
- if (error == EAGAIN || error == EWOULDBLOCK) {
- return WOULD_BLOCK;
- }
- if (error == EPIPE || error == ENOTCONN) {
- return DEAD_OBJECT;
- }
- return -error;
- }
-
- if (size_t(nWrite) != msgLength) {
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
- mName.string(), msg->header.type);
-#endif
- return DEAD_OBJECT;
- }
-
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
-#endif
- return OK;
-}
-
-status_t InputChannel::receiveMessage(InputMessage* msg) {
- ssize_t nRead;
- do {
- nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
- } while (nRead == -1 && errno == EINTR);
-
- if (nRead < 0) {
- int error = errno;
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
-#endif
- if (error == EAGAIN || error == EWOULDBLOCK) {
- return WOULD_BLOCK;
- }
- if (error == EPIPE || error == ENOTCONN) {
- return DEAD_OBJECT;
- }
- return -error;
- }
-
- if (nRead == 0) { // check for EOF
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
-#endif
- return DEAD_OBJECT;
- }
-
- if (!msg->isValid(nRead)) {
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ received invalid message", mName.string());
-#endif
- return BAD_VALUE;
- }
-
-#if DEBUG_CHANNEL_MESSAGES
- ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
-#endif
- return OK;
-}
-
-sp<InputChannel> InputChannel::dup() const {
- int fd = ::dup(getFd());
- return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
-}
-
-
-// --- InputPublisher ---
-
-InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
- mChannel(channel) {
-}
-
-InputPublisher::~InputPublisher() {
-}
-
-status_t InputPublisher::publishKeyEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t keyCode,
- int32_t scanCode,
- int32_t metaState,
- int32_t repeatCount,
- nsecs_t downTime,
- nsecs_t eventTime) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
- "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
- "downTime=%lld, eventTime=%lld",
- mChannel->getName().string(), seq,
- deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
- downTime, eventTime);
-#endif
-
- if (!seq) {
- ALOGE("Attempted to publish a key event with sequence number 0.");
- return BAD_VALUE;
- }
-
- InputMessage msg;
- msg.header.type = InputMessage::TYPE_KEY;
- msg.body.key.seq = seq;
- msg.body.key.deviceId = deviceId;
- msg.body.key.source = source;
- msg.body.key.action = action;
- msg.body.key.flags = flags;
- msg.body.key.keyCode = keyCode;
- msg.body.key.scanCode = scanCode;
- msg.body.key.metaState = metaState;
- msg.body.key.repeatCount = repeatCount;
- msg.body.key.downTime = downTime;
- msg.body.key.eventTime = eventTime;
- return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::publishMotionEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
- "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
- "xOffset=%f, yOffset=%f, "
- "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
- "pointerCount=%d",
- mChannel->getName().string(), seq,
- deviceId, source, action, flags, edgeFlags, metaState, buttonState,
- xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
-#endif
-
- if (!seq) {
- ALOGE("Attempted to publish a motion event with sequence number 0.");
- return BAD_VALUE;
- }
-
- if (pointerCount > MAX_POINTERS || pointerCount < 1) {
- ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
- mChannel->getName().string(), pointerCount);
- return BAD_VALUE;
- }
-
- InputMessage msg;
- msg.header.type = InputMessage::TYPE_MOTION;
- msg.body.motion.seq = seq;
- msg.body.motion.deviceId = deviceId;
- msg.body.motion.source = source;
- msg.body.motion.action = action;
- msg.body.motion.flags = flags;
- msg.body.motion.edgeFlags = edgeFlags;
- msg.body.motion.metaState = metaState;
- msg.body.motion.buttonState = buttonState;
- msg.body.motion.xOffset = xOffset;
- msg.body.motion.yOffset = yOffset;
- msg.body.motion.xPrecision = xPrecision;
- msg.body.motion.yPrecision = yPrecision;
- msg.body.motion.downTime = downTime;
- msg.body.motion.eventTime = eventTime;
- msg.body.motion.pointerCount = pointerCount;
- for (size_t i = 0; i < pointerCount; i++) {
- msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
- msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
- }
- return mChannel->sendMessage(&msg);
-}
-
-status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
- mChannel->getName().string());
-#endif
-
- InputMessage msg;
- status_t result = mChannel->receiveMessage(&msg);
- if (result) {
- *outSeq = 0;
- *outHandled = false;
- return result;
- }
- if (msg.header.type != InputMessage::TYPE_FINISHED) {
- ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
- mChannel->getName().string(), msg.header.type);
- return UNKNOWN_ERROR;
- }
- *outSeq = msg.body.finished.seq;
- *outHandled = msg.body.finished.handled;
- return OK;
-}
-
-// --- InputConsumer ---
-
-InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
- mResampleTouch(isTouchResamplingEnabled()),
- mChannel(channel), mMsgDeferred(false) {
-}
-
-InputConsumer::~InputConsumer() {
-}
-
-bool InputConsumer::isTouchResamplingEnabled() {
- char value[PROPERTY_VALUE_MAX];
- int length = property_get("debug.inputconsumer.resample", value, NULL);
- if (length > 0) {
- if (!strcmp("0", value)) {
- return false;
- }
- if (strcmp("1", value)) {
- ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'. "
- "Use '1' or '0'.");
- }
- }
- return true;
-}
-
-status_t InputConsumer::consume(InputEventFactoryInterface* factory,
- bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
- mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
-#endif
-
- *outSeq = 0;
- *outEvent = NULL;
-
- // Fetch the next input message.
- // Loop until an event can be returned or no additional events are received.
- while (!*outEvent) {
- if (mMsgDeferred) {
- // mMsg contains a valid input message from the previous call to consume
- // that has not yet been processed.
- mMsgDeferred = false;
- } else {
- // Receive a fresh message.
- status_t result = mChannel->receiveMessage(&mMsg);
- if (result) {
- // Consume the next batched event unless batches are being held for later.
- if (consumeBatches || result != WOULD_BLOCK) {
- result = consumeBatch(factory, frameTime, outSeq, outEvent);
- if (*outEvent) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
- mChannel->getName().string(), *outSeq);
-#endif
- break;
- }
- }
- return result;
- }
- }
-
- switch (mMsg.header.type) {
- case InputMessage::TYPE_KEY: {
- KeyEvent* keyEvent = factory->createKeyEvent();
- if (!keyEvent) return NO_MEMORY;
-
- initializeKeyEvent(keyEvent, &mMsg);
- *outSeq = mMsg.body.key.seq;
- *outEvent = keyEvent;
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
- mChannel->getName().string(), *outSeq);
-#endif
- break;
- }
-
- case AINPUT_EVENT_TYPE_MOTION: {
- ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
- if (batchIndex >= 0) {
- Batch& batch = mBatches.editItemAt(batchIndex);
- if (canAddSample(batch, &mMsg)) {
- batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ appended to batch event",
- mChannel->getName().string());
-#endif
- break;
- } else {
- // We cannot append to the batch in progress, so we need to consume
- // the previous batch right now and defer the new message until later.
- mMsgDeferred = true;
- status_t result = consumeSamples(factory,
- batch, batch.samples.size(), outSeq, outEvent);
- mBatches.removeAt(batchIndex);
- if (result) {
- return result;
- }
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ consumed batch event and "
- "deferred current event, seq=%u",
- mChannel->getName().string(), *outSeq);
-#endif
- break;
- }
- }
-
- // Start a new batch if needed.
- if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
- || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
- mBatches.push();
- Batch& batch = mBatches.editTop();
- batch.samples.push(mMsg);
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ started batch event",
- mChannel->getName().string());
-#endif
- break;
- }
-
- MotionEvent* motionEvent = factory->createMotionEvent();
- if (! motionEvent) return NO_MEMORY;
-
- updateTouchState(&mMsg);
- initializeMotionEvent(motionEvent, &mMsg);
- *outSeq = mMsg.body.motion.seq;
- *outEvent = motionEvent;
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
- mChannel->getName().string(), *outSeq);
-#endif
- break;
- }
-
- default:
- ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
- mChannel->getName().string(), mMsg.header.type);
- return UNKNOWN_ERROR;
- }
- }
- return OK;
-}
-
-status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
- status_t result;
- for (size_t i = mBatches.size(); i-- > 0; ) {
- Batch& batch = mBatches.editItemAt(i);
- if (frameTime < 0) {
- result = consumeSamples(factory, batch, batch.samples.size(),
- outSeq, outEvent);
- mBatches.removeAt(i);
- return result;
- }
-
- nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
- ssize_t split = findSampleNoLaterThan(batch, sampleTime);
- if (split < 0) {
- continue;
- }
-
- result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
- const InputMessage* next;
- if (batch.samples.isEmpty()) {
- mBatches.removeAt(i);
- next = NULL;
- } else {
- next = &batch.samples.itemAt(0);
- }
- if (!result) {
- resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
- }
- return result;
- }
-
- return WOULD_BLOCK;
-}
-
-status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
- Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
- MotionEvent* motionEvent = factory->createMotionEvent();
- if (! motionEvent) return NO_MEMORY;
-
- uint32_t chain = 0;
- for (size_t i = 0; i < count; i++) {
- InputMessage& msg = batch.samples.editItemAt(i);
- updateTouchState(&msg);
- if (i) {
- SeqChain seqChain;
- seqChain.seq = msg.body.motion.seq;
- seqChain.chain = chain;
- mSeqChains.push(seqChain);
- addSample(motionEvent, &msg);
- } else {
- initializeMotionEvent(motionEvent, &msg);
- }
- chain = msg.body.motion.seq;
- }
- batch.samples.removeItemsAt(0, count);
-
- *outSeq = chain;
- *outEvent = motionEvent;
- return OK;
-}
-
-void InputConsumer::updateTouchState(InputMessage* msg) {
- if (!mResampleTouch ||
- !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
- return;
- }
-
- int32_t deviceId = msg->body.motion.deviceId;
- int32_t source = msg->body.motion.source;
- nsecs_t eventTime = msg->body.motion.eventTime;
-
- // Update the touch state history to incorporate the new input message.
- // If the message is in the past relative to the most recently produced resampled
- // touch, then use the resampled time and coordinates instead.
- switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
- case AMOTION_EVENT_ACTION_DOWN: {
- ssize_t index = findTouchState(deviceId, source);
- if (index < 0) {
- mTouchStates.push();
- index = mTouchStates.size() - 1;
- }
- TouchState& touchState = mTouchStates.editItemAt(index);
- touchState.initialize(deviceId, source);
- touchState.addHistory(msg);
- break;
- }
-
- case AMOTION_EVENT_ACTION_MOVE: {
- ssize_t index = findTouchState(deviceId, source);
- if (index >= 0) {
- TouchState& touchState = mTouchStates.editItemAt(index);
- touchState.addHistory(msg);
- if (eventTime < touchState.lastResample.eventTime) {
- rewriteMessage(touchState, msg);
- } else {
- touchState.lastResample.idBits.clear();
- }
- }
- break;
- }
-
- case AMOTION_EVENT_ACTION_POINTER_DOWN: {
- ssize_t index = findTouchState(deviceId, source);
- if (index >= 0) {
- TouchState& touchState = mTouchStates.editItemAt(index);
- touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
- rewriteMessage(touchState, msg);
- }
- break;
- }
-
- case AMOTION_EVENT_ACTION_POINTER_UP: {
- ssize_t index = findTouchState(deviceId, source);
- if (index >= 0) {
- TouchState& touchState = mTouchStates.editItemAt(index);
- rewriteMessage(touchState, msg);
- touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
- }
- break;
- }
-
- case AMOTION_EVENT_ACTION_SCROLL: {
- ssize_t index = findTouchState(deviceId, source);
- if (index >= 0) {
- const TouchState& touchState = mTouchStates.itemAt(index);
- rewriteMessage(touchState, msg);
- }
- break;
- }
-
- case AMOTION_EVENT_ACTION_UP:
- case AMOTION_EVENT_ACTION_CANCEL: {
- ssize_t index = findTouchState(deviceId, source);
- if (index >= 0) {
- const TouchState& touchState = mTouchStates.itemAt(index);
- rewriteMessage(touchState, msg);
- mTouchStates.removeAt(index);
- }
- break;
- }
- }
-}
-
-void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
- for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
- uint32_t id = msg->body.motion.pointers[i].properties.id;
- if (state.lastResample.idBits.hasBit(id)) {
- PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
- const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
-#if DEBUG_RESAMPLING
- ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
- resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
- resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
- msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
- msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
-#endif
- msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
- msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
- }
- }
-}
-
-void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
- const InputMessage* next) {
- if (!mResampleTouch
- || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
- || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
- return;
- }
-
- ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
- if (index < 0) {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, no touch state for device.");
-#endif
- return;
- }
-
- TouchState& touchState = mTouchStates.editItemAt(index);
- if (touchState.historySize < 1) {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, no history for device.");
-#endif
- return;
- }
-
- // Ensure that the current sample has all of the pointers that need to be reported.
- const History* current = touchState.getHistory(0);
- size_t pointerCount = event->getPointerCount();
- for (size_t i = 0; i < pointerCount; i++) {
- uint32_t id = event->getPointerId(i);
- if (!current->idBits.hasBit(id)) {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, missing id %d", id);
-#endif
- return;
- }
- }
-
- // Find the data to use for resampling.
- const History* other;
- History future;
- float alpha;
- if (next) {
- // Interpolate between current sample and future sample.
- // So current->eventTime <= sampleTime <= future.eventTime.
- future.initializeFrom(next);
- other = &future;
- nsecs_t delta = future.eventTime - current->eventTime;
- if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
- return;
- }
- alpha = float(sampleTime - current->eventTime) / delta;
- } else if (touchState.historySize >= 2) {
- // Extrapolate future sample using current sample and past sample.
- // So other->eventTime <= current->eventTime <= sampleTime.
- other = touchState.getHistory(1);
- nsecs_t delta = current->eventTime - other->eventTime;
- if (delta < RESAMPLE_MIN_DELTA) {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, delta time is %lld ns.", delta);
-#endif
- return;
- }
- nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
- if (sampleTime > maxPredict) {
-#if DEBUG_RESAMPLING
- ALOGD("Sample time is too far in the future, adjusting prediction "
- "from %lld to %lld ns.",
- sampleTime - current->eventTime, maxPredict - current->eventTime);
-#endif
- sampleTime = maxPredict;
- }
- alpha = float(current->eventTime - sampleTime) / delta;
- } else {
-#if DEBUG_RESAMPLING
- ALOGD("Not resampled, insufficient data.");
-#endif
- return;
- }
-
- // Resample touch coordinates.
- touchState.lastResample.eventTime = sampleTime;
- touchState.lastResample.idBits.clear();
- for (size_t i = 0; i < pointerCount; i++) {
- uint32_t id = event->getPointerId(i);
- touchState.lastResample.idToIndex[id] = i;
- touchState.lastResample.idBits.markBit(id);
- PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
- const PointerCoords& currentCoords = current->getPointerById(id);
- if (other->idBits.hasBit(id)
- && shouldResampleTool(event->getToolType(i))) {
- const PointerCoords& otherCoords = other->getPointerById(id);
- resampledCoords.copyFrom(currentCoords);
- resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
- lerp(currentCoords.getX(), otherCoords.getX(), alpha));
- resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
- lerp(currentCoords.getY(), otherCoords.getY(), alpha));
-#if DEBUG_RESAMPLING
- ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
- "other (%0.3f, %0.3f), alpha %0.3f",
- id, resampledCoords.getX(), resampledCoords.getY(),
- currentCoords.getX(), currentCoords.getY(),
- otherCoords.getX(), otherCoords.getY(),
- alpha);
-#endif
- } else {
- resampledCoords.copyFrom(currentCoords);
-#if DEBUG_RESAMPLING
- ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
- id, resampledCoords.getX(), resampledCoords.getY(),
- currentCoords.getX(), currentCoords.getY());
-#endif
- }
- }
-
- event->addSample(sampleTime, touchState.lastResample.pointers);
-}
-
-bool InputConsumer::shouldResampleTool(int32_t toolType) {
- return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
- || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
-#if DEBUG_TRANSPORT_ACTIONS
- ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
- mChannel->getName().string(), seq, handled ? "true" : "false");
-#endif
-
- if (!seq) {
- ALOGE("Attempted to send a finished signal with sequence number 0.");
- return BAD_VALUE;
- }
-
- // Send finished signals for the batch sequence chain first.
- size_t seqChainCount = mSeqChains.size();
- if (seqChainCount) {
- uint32_t currentSeq = seq;
- uint32_t chainSeqs[seqChainCount];
- size_t chainIndex = 0;
- for (size_t i = seqChainCount; i-- > 0; ) {
- const SeqChain& seqChain = mSeqChains.itemAt(i);
- if (seqChain.seq == currentSeq) {
- currentSeq = seqChain.chain;
- chainSeqs[chainIndex++] = currentSeq;
- mSeqChains.removeAt(i);
- }
- }
- status_t status = OK;
- while (!status && chainIndex-- > 0) {
- status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
- }
- if (status) {
- // An error occurred so at least one signal was not sent, reconstruct the chain.
- do {
- SeqChain seqChain;
- seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
- seqChain.chain = chainSeqs[chainIndex];
- mSeqChains.push(seqChain);
- } while (chainIndex-- > 0);
- return status;
- }
- }
-
- // Send finished signal for the last message in the batch.
- return sendUnchainedFinishedSignal(seq, handled);
-}
-
-status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
- InputMessage msg;
- msg.header.type = InputMessage::TYPE_FINISHED;
- msg.body.finished.seq = seq;
- msg.body.finished.handled = handled;
- return mChannel->sendMessage(&msg);
-}
-
-bool InputConsumer::hasDeferredEvent() const {
- return mMsgDeferred;
-}
-
-bool InputConsumer::hasPendingBatch() const {
- return !mBatches.isEmpty();
-}
-
-ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
- for (size_t i = 0; i < mBatches.size(); i++) {
- const Batch& batch = mBatches.itemAt(i);
- const InputMessage& head = batch.samples.itemAt(0);
- if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
- return i;
- }
- }
- return -1;
-}
-
-ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
- for (size_t i = 0; i < mTouchStates.size(); i++) {
- const TouchState& touchState = mTouchStates.itemAt(i);
- if (touchState.deviceId == deviceId && touchState.source == source) {
- return i;
- }
- }
- return -1;
-}
-
-void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
- event->initialize(
- msg->body.key.deviceId,
- msg->body.key.source,
- msg->body.key.action,
- msg->body.key.flags,
- msg->body.key.keyCode,
- msg->body.key.scanCode,
- msg->body.key.metaState,
- msg->body.key.repeatCount,
- msg->body.key.downTime,
- msg->body.key.eventTime);
-}
-
-void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
- size_t pointerCount = msg->body.motion.pointerCount;
- PointerProperties pointerProperties[pointerCount];
- PointerCoords pointerCoords[pointerCount];
- for (size_t i = 0; i < pointerCount; i++) {
- pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
- pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
- }
-
- event->initialize(
- msg->body.motion.deviceId,
- msg->body.motion.source,
- msg->body.motion.action,
- msg->body.motion.flags,
- msg->body.motion.edgeFlags,
- msg->body.motion.metaState,
- msg->body.motion.buttonState,
- msg->body.motion.xOffset,
- msg->body.motion.yOffset,
- msg->body.motion.xPrecision,
- msg->body.motion.yPrecision,
- msg->body.motion.downTime,
- msg->body.motion.eventTime,
- pointerCount,
- pointerProperties,
- pointerCoords);
-}
-
-void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
- size_t pointerCount = msg->body.motion.pointerCount;
- PointerCoords pointerCoords[pointerCount];
- for (size_t i = 0; i < pointerCount; i++) {
- pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
- }
-
- event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
- event->addSample(msg->body.motion.eventTime, pointerCoords);
-}
-
-bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
- const InputMessage& head = batch.samples.itemAt(0);
- size_t pointerCount = msg->body.motion.pointerCount;
- if (head.body.motion.pointerCount != pointerCount
- || head.body.motion.action != msg->body.motion.action) {
- return false;
- }
- for (size_t i = 0; i < pointerCount; i++) {
- if (head.body.motion.pointers[i].properties
- != msg->body.motion.pointers[i].properties) {
- return false;
- }
- }
- return true;
-}
-
-ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
- size_t numSamples = batch.samples.size();
- size_t index = 0;
- while (index < numSamples
- && batch.samples.itemAt(index).body.motion.eventTime <= time) {
- index += 1;
- }
- return ssize_t(index) - 1;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputTransport.h b/widget/gonk/libui/InputTransport.h
deleted file mode 100644
index 66ef2850a..000000000
--- a/widget/gonk/libui/InputTransport.h
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_INPUT_TRANSPORT_H
-#define _ANDROIDFW_INPUT_TRANSPORT_H
-
-/**
- * Native input transport.
- *
- * The InputChannel provides a mechanism for exchanging InputMessage structures across processes.
- *
- * The InputPublisher and InputConsumer each handle one end-point of an input channel.
- * The InputPublisher is used by the input dispatcher to send events to the application.
- * The InputConsumer is used by the application to receive events from the input dispatcher.
- */
-
-#include "Input.h"
-#include <utils/Errors.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-/*
- * Intermediate representation used to send input events and related signals.
- */
-struct InputMessage {
- enum {
- TYPE_KEY = 1,
- TYPE_MOTION = 2,
- TYPE_FINISHED = 3,
- };
-
- struct Header {
- uint32_t type;
- uint32_t padding; // 8 byte alignment for the body that follows
- } header;
-
- union Body {
- struct Key {
- uint32_t seq;
- nsecs_t eventTime;
- int32_t deviceId;
- int32_t source;
- int32_t action;
- int32_t flags;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- int32_t repeatCount;
- nsecs_t downTime;
-
- inline size_t size() const {
- return sizeof(Key);
- }
- } key;
-
- struct Motion {
- uint32_t seq;
- nsecs_t eventTime;
- int32_t deviceId;
- int32_t source;
- int32_t action;
- int32_t flags;
- int32_t metaState;
- int32_t buttonState;
- int32_t edgeFlags;
- nsecs_t downTime;
- float xOffset;
- float yOffset;
- float xPrecision;
- float yPrecision;
- size_t pointerCount;
- struct Pointer {
- PointerProperties properties;
- PointerCoords coords;
- } pointers[MAX_POINTERS];
-
- int32_t getActionId() const {
- uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
- >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
- return pointers[index].properties.id;
- }
-
- inline size_t size() const {
- return sizeof(Motion) - sizeof(Pointer) * MAX_POINTERS
- + sizeof(Pointer) * pointerCount;
- }
- } motion;
-
- struct Finished {
- uint32_t seq;
- bool handled;
-
- inline size_t size() const {
- return sizeof(Finished);
- }
- } finished;
- } body;
-
- bool isValid(size_t actualSize) const;
- size_t size() const;
-};
-
-/*
- * An input channel consists of a local unix domain socket used to send and receive
- * input messages across processes. Each channel has a descriptive name for debugging purposes.
- *
- * Each endpoint has its own InputChannel object that specifies its file descriptor.
- *
- * The input channel is closed when all references to it are released.
- */
-class InputChannel : public RefBase {
-protected:
- virtual ~InputChannel();
-
-public:
- InputChannel(const String8& name, int fd);
-
- /* Creates a pair of input channels.
- *
- * Returns OK on success.
- */
- static status_t openInputChannelPair(const String8& name,
- sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
-
- inline String8 getName() const { return mName; }
- inline int getFd() const { return mFd; }
-
- /* Sends a message to the other endpoint.
- *
- * If the channel is full then the message is guaranteed not to have been sent at all.
- * Try again after the consumer has sent a finished signal indicating that it has
- * consumed some of the pending messages from the channel.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if the channel is full.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Other errors probably indicate that the channel is broken.
- */
- status_t sendMessage(const InputMessage* msg);
-
- /* Receives a message sent by the other endpoint.
- *
- * If there is no message present, try again after poll() indicates that the fd
- * is readable.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if there is no message present.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Other errors probably indicate that the channel is broken.
- */
- status_t receiveMessage(InputMessage* msg);
-
- /* Returns a new object that has a duplicate of this channel's fd. */
- sp<InputChannel> dup() const;
-
-private:
- String8 mName;
- int mFd;
-};
-
-/*
- * Publishes input events to an input channel.
- */
-class InputPublisher {
-public:
- /* Creates a publisher associated with an input channel. */
- explicit InputPublisher(const sp<InputChannel>& channel);
-
- /* Destroys the publisher and releases its input channel. */
- ~InputPublisher();
-
- /* Gets the underlying input channel. */
- inline sp<InputChannel> getChannel() { return mChannel; }
-
- /* Publishes a key event to the input channel.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if the channel is full.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Returns BAD_VALUE if seq is 0.
- * Other errors probably indicate that the channel is broken.
- */
- status_t publishKeyEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t keyCode,
- int32_t scanCode,
- int32_t metaState,
- int32_t repeatCount,
- nsecs_t downTime,
- nsecs_t eventTime);
-
- /* Publishes a motion event to the input channel.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if the channel is full.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
- * Other errors probably indicate that the channel is broken.
- */
- status_t publishMotionEvent(
- uint32_t seq,
- int32_t deviceId,
- int32_t source,
- int32_t action,
- int32_t flags,
- int32_t edgeFlags,
- int32_t metaState,
- int32_t buttonState,
- float xOffset,
- float yOffset,
- float xPrecision,
- float yPrecision,
- nsecs_t downTime,
- nsecs_t eventTime,
- size_t pointerCount,
- const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords);
-
- /* Receives the finished signal from the consumer in reply to the original dispatch signal.
- * If a signal was received, returns the message sequence number,
- * and whether the consumer handled the message.
- *
- * The returned sequence number is never 0 unless the operation failed.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if there is no signal present.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Other errors probably indicate that the channel is broken.
- */
- status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
-
-private:
- sp<InputChannel> mChannel;
-};
-
-/*
- * Consumes input events from an input channel.
- */
-class InputConsumer {
-public:
- /* Creates a consumer associated with an input channel. */
- explicit InputConsumer(const sp<InputChannel>& channel);
-
- /* Destroys the consumer and releases its input channel. */
- ~InputConsumer();
-
- /* Gets the underlying input channel. */
- inline sp<InputChannel> getChannel() { return mChannel; }
-
- /* Consumes an input event from the input channel and copies its contents into
- * an InputEvent object created using the specified factory.
- *
- * Tries to combine a series of move events into larger batches whenever possible.
- *
- * If consumeBatches is false, then defers consuming pending batched events if it
- * is possible for additional samples to be added to them later. Call hasPendingBatch()
- * to determine whether a pending batch is available to be consumed.
- *
- * If consumeBatches is true, then events are still batched but they are consumed
- * immediately as soon as the input channel is exhausted.
- *
- * The frameTime parameter specifies the time when the current display frame started
- * rendering in the CLOCK_MONOTONIC time base, or -1 if unknown.
- *
- * The returned sequence number is never 0 unless the operation failed.
- *
- * Returns OK on success.
- * Returns WOULD_BLOCK if there is no event present.
- * Returns DEAD_OBJECT if the channel's peer has been closed.
- * Returns NO_MEMORY if the event could not be created.
- * Other errors probably indicate that the channel is broken.
- */
- status_t consume(InputEventFactoryInterface* factory, bool consumeBatches,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
-
- /* Sends a finished signal to the publisher to inform it that the message
- * with the specified sequence number has finished being process and whether
- * the message was handled by the consumer.
- *
- * Returns OK on success.
- * Returns BAD_VALUE if seq is 0.
- * Other errors probably indicate that the channel is broken.
- */
- status_t sendFinishedSignal(uint32_t seq, bool handled);
-
- /* Returns true if there is a deferred event waiting.
- *
- * Should be called after calling consume() to determine whether the consumer
- * has a deferred event to be processed. Deferred events are somewhat special in
- * that they have already been removed from the input channel. If the input channel
- * becomes empty, the client may need to do extra work to ensure that it processes
- * the deferred event despite the fact that the input channel's file descriptor
- * is not readable.
- *
- * One option is simply to call consume() in a loop until it returns WOULD_BLOCK.
- * This guarantees that all deferred events will be processed.
- *
- * Alternately, the caller can call hasDeferredEvent() to determine whether there is
- * a deferred event waiting and then ensure that its event loop wakes up at least
- * one more time to consume the deferred event.
- */
- bool hasDeferredEvent() const;
-
- /* Returns true if there is a pending batch.
- *
- * Should be called after calling consume() with consumeBatches == false to determine
- * whether consume() should be called again later on with consumeBatches == true.
- */
- bool hasPendingBatch() const;
-
-private:
- // True if touch resampling is enabled.
- const bool mResampleTouch;
-
- // The input channel.
- sp<InputChannel> mChannel;
-
- // The current input message.
- InputMessage mMsg;
-
- // True if mMsg contains a valid input message that was deferred from the previous
- // call to consume and that still needs to be handled.
- bool mMsgDeferred;
-
- // Batched motion events per device and source.
- struct Batch {
- Vector<InputMessage> samples;
- };
- Vector<Batch> mBatches;
-
- // Touch state per device and source, only for sources of class pointer.
- struct History {
- nsecs_t eventTime;
- BitSet32 idBits;
- int32_t idToIndex[MAX_POINTER_ID + 1];
- PointerCoords pointers[MAX_POINTERS];
-
- void initializeFrom(const InputMessage* msg) {
- eventTime = msg->body.motion.eventTime;
- idBits.clear();
- for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
- uint32_t id = msg->body.motion.pointers[i].properties.id;
- idBits.markBit(id);
- idToIndex[id] = i;
- pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
- }
- }
-
- const PointerCoords& getPointerById(uint32_t id) const {
- return pointers[idToIndex[id]];
- }
- };
- struct TouchState {
- int32_t deviceId;
- int32_t source;
- size_t historyCurrent;
- size_t historySize;
- History history[2];
- History lastResample;
-
- void initialize(int32_t deviceId, int32_t source) {
- this->deviceId = deviceId;
- this->source = source;
- historyCurrent = 0;
- historySize = 0;
- lastResample.eventTime = 0;
- lastResample.idBits.clear();
- }
-
- void addHistory(const InputMessage* msg) {
- historyCurrent ^= 1;
- if (historySize < 2) {
- historySize += 1;
- }
- history[historyCurrent].initializeFrom(msg);
- }
-
- const History* getHistory(size_t index) const {
- return &history[(historyCurrent + index) & 1];
- }
- };
- Vector<TouchState> mTouchStates;
-
- // Chain of batched sequence numbers. When multiple input messages are combined into
- // a batch, we append a record here that associates the last sequence number in the
- // batch with the previous one. When the finished signal is sent, we traverse the
- // chain to individually finish all input messages that were part of the batch.
- struct SeqChain {
- uint32_t seq; // sequence number of batched input message
- uint32_t chain; // sequence number of previous batched input message
- };
- Vector<SeqChain> mSeqChains;
-
- status_t consumeBatch(InputEventFactoryInterface* factory,
- nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
- status_t consumeSamples(InputEventFactoryInterface* factory,
- Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent);
-
- void updateTouchState(InputMessage* msg);
- void rewriteMessage(const TouchState& state, InputMessage* msg);
- void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
- const InputMessage *next);
-
- ssize_t findBatch(int32_t deviceId, int32_t source) const;
- ssize_t findTouchState(int32_t deviceId, int32_t source) const;
-
- status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);
-
- static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg);
- static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg);
- static void addSample(MotionEvent* event, const InputMessage* msg);
- static bool canAddSample(const Batch& batch, const InputMessage* msg);
- static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);
- static bool shouldResampleTool(int32_t toolType);
-
- static bool isTouchResamplingEnabled();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_INPUT_TRANSPORT_H
diff --git a/widget/gonk/libui/InputWindow.cpp b/widget/gonk/libui/InputWindow.cpp
deleted file mode 100644
index 3aea445a0..000000000
--- a/widget/gonk/libui/InputWindow.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputWindow"
-
-#include "InputWindow.h"
-
-#include "cutils_log.h"
-
-namespace android {
-
-// --- InputWindowInfo ---
-
-bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
- return touchableRegion.contains(x, y);
-}
-
-bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
- return x >= frameLeft && x <= frameRight
- && y >= frameTop && y <= frameBottom;
-}
-
-bool InputWindowInfo::isTrustedOverlay() const {
- return layoutParamsType == TYPE_INPUT_METHOD
- || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
- || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
-}
-
-bool InputWindowInfo::supportsSplitTouch() const {
- return layoutParamsFlags & FLAG_SPLIT_TOUCH;
-}
-
-
-// --- InputWindowHandle ---
-
-InputWindowHandle::InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
- inputApplicationHandle(inputApplicationHandle), mInfo(NULL) {
-}
-
-InputWindowHandle::~InputWindowHandle() {
- delete mInfo;
-}
-
-void InputWindowHandle::releaseInfo() {
- if (mInfo) {
- delete mInfo;
- mInfo = NULL;
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/InputWindow.h b/widget/gonk/libui/InputWindow.h
deleted file mode 100644
index cce5fd4fe..000000000
--- a/widget/gonk/libui/InputWindow.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_WINDOW_H
-#define _UI_INPUT_WINDOW_H
-
-#include "Input.h"
-#include "InputTransport.h"
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-#include <utils/String8.h>
-
-#include <SkRegion.h>
-
-#include "InputApplication.h"
-
-namespace android {
-
-/*
- * Describes the properties of a window that can receive input.
- */
-struct InputWindowInfo {
- // Window flags from WindowManager.LayoutParams
- enum {
- FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001,
- FLAG_DIM_BEHIND = 0x00000002,
- FLAG_BLUR_BEHIND = 0x00000004,
- FLAG_NOT_FOCUSABLE = 0x00000008,
- FLAG_NOT_TOUCHABLE = 0x00000010,
- FLAG_NOT_TOUCH_MODAL = 0x00000020,
- FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
- FLAG_KEEP_SCREEN_ON = 0x00000080,
- FLAG_LAYOUT_IN_SCREEN = 0x00000100,
- FLAG_LAYOUT_NO_LIMITS = 0x00000200,
- FLAG_FULLSCREEN = 0x00000400,
- FLAG_FORCE_NOT_FULLSCREEN = 0x00000800,
- FLAG_DITHER = 0x00001000,
- FLAG_SECURE = 0x00002000,
- FLAG_SCALED = 0x00004000,
- FLAG_IGNORE_CHEEK_PRESSES = 0x00008000,
- FLAG_LAYOUT_INSET_DECOR = 0x00010000,
- FLAG_ALT_FOCUSABLE_IM = 0x00020000,
- FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
- FLAG_SHOW_WHEN_LOCKED = 0x00080000,
- FLAG_SHOW_WALLPAPER = 0x00100000,
- FLAG_TURN_SCREEN_ON = 0x00200000,
- FLAG_DISMISS_KEYGUARD = 0x00400000,
- FLAG_SPLIT_TOUCH = 0x00800000,
- FLAG_HARDWARE_ACCELERATED = 0x01000000,
- FLAG_HARDWARE_ACCELERATED_SYSTEM = 0x02000000,
- FLAG_SLIPPERY = 0x04000000,
- FLAG_NEEDS_MENU_KEY = 0x08000000,
- FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000,
- FLAG_COMPATIBLE_WINDOW = 0x20000000,
- FLAG_SYSTEM_ERROR = 0x40000000,
- };
-
- // Window types from WindowManager.LayoutParams
- enum {
- FIRST_APPLICATION_WINDOW = 1,
- TYPE_BASE_APPLICATION = 1,
- TYPE_APPLICATION = 2,
- TYPE_APPLICATION_STARTING = 3,
- LAST_APPLICATION_WINDOW = 99,
- FIRST_SUB_WINDOW = 1000,
- TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW,
- TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1,
- TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
- TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
- TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4,
- LAST_SUB_WINDOW = 1999,
- FIRST_SYSTEM_WINDOW = 2000,
- TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW,
- TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1,
- TYPE_PHONE = FIRST_SYSTEM_WINDOW+2,
- TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3,
- TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4,
- TYPE_TOAST = FIRST_SYSTEM_WINDOW+5,
- TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6,
- TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7,
- TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8,
- TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9,
- TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10,
- TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11,
- TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
- TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13,
- TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14,
- TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
- TYPE_DRAG = FIRST_SYSTEM_WINDOW+16,
- TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17,
- TYPE_POINTER = FIRST_SYSTEM_WINDOW+18,
- TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19,
- TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20,
- TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21,
- LAST_SYSTEM_WINDOW = 2999,
- };
-
- enum {
- INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
- INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
- INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
- };
-
- sp<InputChannel> inputChannel;
- String8 name;
- int32_t layoutParamsFlags;
- int32_t layoutParamsType;
- nsecs_t dispatchingTimeout;
- int32_t frameLeft;
- int32_t frameTop;
- int32_t frameRight;
- int32_t frameBottom;
- float scaleFactor;
- SkRegion touchableRegion;
- bool visible;
- bool canReceiveKeys;
- bool hasFocus;
- bool hasWallpaper;
- bool paused;
- int32_t layer;
- int32_t ownerPid;
- int32_t ownerUid;
- int32_t inputFeatures;
- int32_t displayId;
-
- bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
- bool frameContainsPoint(int32_t x, int32_t y) const;
-
- /* Returns true if the window is of a trusted type that is allowed to silently
- * overlay other windows for the purpose of implementing the secure views feature.
- * Trusted overlays, such as IME windows, can partly obscure other windows without causing
- * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
- */
- bool isTrustedOverlay() const;
-
- bool supportsSplitTouch() const;
-};
-
-
-/*
- * Handle for a window that can receive input.
- *
- * Used by the native input dispatcher to indirectly refer to the window manager objects
- * that describe a window.
- */
-class InputWindowHandle : public RefBase {
-public:
- const sp<InputApplicationHandle> inputApplicationHandle;
-
- inline const InputWindowInfo* getInfo() const {
- return mInfo;
- }
-
- inline sp<InputChannel> getInputChannel() const {
- return mInfo ? mInfo->inputChannel : NULL;
- }
-
- inline String8 getName() const {
- return mInfo ? mInfo->name : String8("<invalid>");
- }
-
- inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
- return mInfo ? mInfo->dispatchingTimeout : defaultValue;
- }
-
- /**
- * Requests that the state of this object be updated to reflect
- * the most current available information about the application.
- *
- * This method should only be called from within the input dispatcher's
- * critical section.
- *
- * Returns true on success, or false if the handle is no longer valid.
- */
- virtual bool updateInfo() = 0;
-
- /**
- * Releases the storage used by the associated information when it is
- * no longer needed.
- */
- void releaseInfo();
-
-protected:
- InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle);
- virtual ~InputWindowHandle();
-
- InputWindowInfo* mInfo;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_WINDOW_H
diff --git a/widget/gonk/libui/KeyCharacterMap.cpp b/widget/gonk/libui/KeyCharacterMap.cpp
deleted file mode 100644
index cec0666ce..000000000
--- a/widget/gonk/libui/KeyCharacterMap.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "KeyCharacterMap"
-#include "cutils_log.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include "android_keycodes.h"
-#include "Keyboard.h"
-#include "KeyCharacterMap.h"
-
-#if HAVE_ANDROID_OS
-#include <binder/Parcel.h>
-#endif
-
-#include <utils/Errors.h>
-#include "Tokenizer.h"
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_PROPERTY_DELIMITER = " \t\r,:";
-
-struct Modifier {
- const char* label;
- int32_t metaState;
-};
-static const Modifier modifiers[] = {
- { "shift", AMETA_SHIFT_ON },
- { "lshift", AMETA_SHIFT_LEFT_ON },
- { "rshift", AMETA_SHIFT_RIGHT_ON },
- { "alt", AMETA_ALT_ON },
- { "lalt", AMETA_ALT_LEFT_ON },
- { "ralt", AMETA_ALT_RIGHT_ON },
- { "ctrl", AMETA_CTRL_ON },
- { "lctrl", AMETA_CTRL_LEFT_ON },
- { "rctrl", AMETA_CTRL_RIGHT_ON },
- { "meta", AMETA_META_ON },
- { "lmeta", AMETA_META_LEFT_ON },
- { "rmeta", AMETA_META_RIGHT_ON },
- { "sym", AMETA_SYM_ON },
- { "fn", AMETA_FUNCTION_ON },
- { "capslock", AMETA_CAPS_LOCK_ON },
- { "numlock", AMETA_NUM_LOCK_ON },
- { "scrolllock", AMETA_SCROLL_LOCK_ON },
-};
-
-#if DEBUG_MAPPING
-static String8 toString(const char16_t* chars, size_t numChars) {
- String8 result;
- for (size_t i = 0; i < numChars; i++) {
- result.appendFormat(i == 0 ? "%d" : ", %d", chars[i]);
- }
- return result;
-}
-#endif
-
-
-// --- KeyCharacterMap ---
-
-sp<KeyCharacterMap> KeyCharacterMap::sEmpty = new KeyCharacterMap();
-
-KeyCharacterMap::KeyCharacterMap() :
- mType(KEYBOARD_TYPE_UNKNOWN) {
-}
-
-KeyCharacterMap::KeyCharacterMap(const KeyCharacterMap& other) :
- RefBase(), mType(other.mType), mKeysByScanCode(other.mKeysByScanCode),
- mKeysByUsageCode(other.mKeysByUsageCode) {
- for (size_t i = 0; i < other.mKeys.size(); i++) {
- mKeys.add(other.mKeys.keyAt(i), new Key(*other.mKeys.valueAt(i)));
- }
-}
-
-KeyCharacterMap::~KeyCharacterMap() {
- for (size_t i = 0; i < mKeys.size(); i++) {
- Key* key = mKeys.editValueAt(i);
- delete key;
- }
-}
-
-status_t KeyCharacterMap::load(const String8& filename,
- Format format, sp<KeyCharacterMap>* outMap) {
- outMap->clear();
-
- Tokenizer* tokenizer;
- status_t status = Tokenizer::open(filename, &tokenizer);
- if (status) {
- ALOGE("Error %d opening key character map file %s.", status, filename.string());
- } else {
- status = load(tokenizer, format, outMap);
- delete tokenizer;
- }
- return status;
-}
-
-status_t KeyCharacterMap::loadContents(const String8& filename, const char* contents,
- Format format, sp<KeyCharacterMap>* outMap) {
- outMap->clear();
-
- Tokenizer* tokenizer;
- status_t status = Tokenizer::fromContents(filename, contents, &tokenizer);
- if (status) {
- ALOGE("Error %d opening key character map.", status);
- } else {
- status = load(tokenizer, format, outMap);
- delete tokenizer;
- }
- return status;
-}
-
-status_t KeyCharacterMap::load(Tokenizer* tokenizer,
- Format format, sp<KeyCharacterMap>* outMap) {
- status_t status = OK;
- sp<KeyCharacterMap> map = new KeyCharacterMap();
- if (!map.get()) {
- ALOGE("Error allocating key character map.");
- status = NO_MEMORY;
- } else {
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
- Parser parser(map.get(), tokenizer, format);
- status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
- ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
- tokenizer->getFilename().string(), tokenizer->getLineNumber(),
- elapsedTime / 1000000.0);
-#endif
- if (!status) {
- *outMap = map;
- }
- }
- return status;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::combine(const sp<KeyCharacterMap>& base,
- const sp<KeyCharacterMap>& overlay) {
- if (overlay == NULL) {
- return base;
- }
- if (base == NULL) {
- return overlay;
- }
-
- sp<KeyCharacterMap> map = new KeyCharacterMap(*base.get());
- for (size_t i = 0; i < overlay->mKeys.size(); i++) {
- int32_t keyCode = overlay->mKeys.keyAt(i);
- Key* key = overlay->mKeys.valueAt(i);
- ssize_t oldIndex = map->mKeys.indexOfKey(keyCode);
- if (oldIndex >= 0) {
- delete map->mKeys.valueAt(oldIndex);
- map->mKeys.editValueAt(oldIndex) = new Key(*key);
- } else {
- map->mKeys.add(keyCode, new Key(*key));
- }
- }
-
- for (size_t i = 0; i < overlay->mKeysByScanCode.size(); i++) {
- map->mKeysByScanCode.replaceValueFor(overlay->mKeysByScanCode.keyAt(i),
- overlay->mKeysByScanCode.valueAt(i));
- }
-
- for (size_t i = 0; i < overlay->mKeysByUsageCode.size(); i++) {
- map->mKeysByUsageCode.replaceValueFor(overlay->mKeysByUsageCode.keyAt(i),
- overlay->mKeysByUsageCode.valueAt(i));
- }
- return map;
-}
-
-sp<KeyCharacterMap> KeyCharacterMap::empty() {
- return sEmpty;
-}
-
-int32_t KeyCharacterMap::getKeyboardType() const {
- return mType;
-}
-
-char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
- char16_t result = 0;
- const Key* key;
- if (getKey(keyCode, &key)) {
- result = key->label;
- }
-#if DEBUG_MAPPING
- ALOGD("getDisplayLabel: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
- return result;
-}
-
-char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
- char16_t result = 0;
- const Key* key;
- if (getKey(keyCode, &key)) {
- result = key->number;
- }
-#if DEBUG_MAPPING
- ALOGD("getNumber: keyCode=%d ~ Result %d.", keyCode, result);
-#endif
- return result;
-}
-
-char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
- char16_t result = 0;
- const Key* key;
- const Behavior* behavior;
- if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
- result = behavior->character;
- }
-#if DEBUG_MAPPING
- ALOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
-#endif
- return result;
-}
-
-bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
- FallbackAction* outFallbackAction) const {
- outFallbackAction->keyCode = 0;
- outFallbackAction->metaState = 0;
-
- bool result = false;
- const Key* key;
- const Behavior* behavior;
- if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
- if (behavior->fallbackKeyCode) {
- outFallbackAction->keyCode = behavior->fallbackKeyCode;
- outFallbackAction->metaState = metaState & ~behavior->metaState;
- result = true;
- }
- }
-#if DEBUG_MAPPING
- ALOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
- "fallback keyCode=%d, fallback metaState=0x%08x.",
- keyCode, metaState, result ? "true" : "false",
- outFallbackAction->keyCode, outFallbackAction->metaState);
-#endif
- return result;
-}
-
-char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
- int32_t metaState) const {
- char16_t result = 0;
- const Key* key;
- if (getKey(keyCode, &key)) {
- // Try to find the most general behavior that maps to this character.
- // For example, the base key behavior will usually be last in the list.
- // However, if we find a perfect meta state match for one behavior then use that one.
- for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
- if (behavior->character) {
- for (size_t i = 0; i < numChars; i++) {
- if (behavior->character == chars[i]) {
- result = behavior->character;
- if ((behavior->metaState & metaState) == behavior->metaState) {
- goto ExactMatch;
- }
- break;
- }
- }
- }
- }
- ExactMatch: ;
- }
-#if DEBUG_MAPPING
- ALOGD("getMatch: keyCode=%d, chars=[%s], metaState=0x%08x ~ Result %d.",
- keyCode, toString(chars, numChars).string(), metaState, result);
-#endif
- return result;
-}
-
-bool KeyCharacterMap::getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
- Vector<KeyEvent>& outEvents) const {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
- for (size_t i = 0; i < numChars; i++) {
- int32_t keyCode, metaState;
- char16_t ch = chars[i];
- if (!findKey(ch, &keyCode, &metaState)) {
-#if DEBUG_MAPPING
- ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Failed to find mapping for character %d.",
- deviceId, toString(chars, numChars).string(), ch);
-#endif
- return false;
- }
-
- int32_t currentMetaState = 0;
- addMetaKeys(outEvents, deviceId, metaState, true, now, &currentMetaState);
- addKey(outEvents, deviceId, keyCode, currentMetaState, true, now);
- addKey(outEvents, deviceId, keyCode, currentMetaState, false, now);
- addMetaKeys(outEvents, deviceId, metaState, false, now, &currentMetaState);
- }
-#if DEBUG_MAPPING
- ALOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
- deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
- for (size_t i = 0; i < outEvents.size(); i++) {
- ALOGD(" Key: keyCode=%d, metaState=0x%08x, %s.",
- outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
- outEvents[i].getAction() == AKEY_EVENT_ACTION_DOWN ? "down" : "up");
- }
-#endif
- return true;
-}
-
-status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const {
- if (usageCode) {
- ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
- if (index >= 0) {
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
- scanCode, usageCode, *outKeyCode);
-#endif
- *outKeyCode = mKeysByUsageCode.valueAt(index);
- return OK;
- }
- }
- if (scanCode) {
- ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
- if (index >= 0) {
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
- scanCode, usageCode, *outKeyCode);
-#endif
- *outKeyCode = mKeysByScanCode.valueAt(index);
- return OK;
- }
- }
-
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
- *outKeyCode = AKEYCODE_UNKNOWN;
- return NAME_NOT_FOUND;
-}
-
-bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- *outKey = mKeys.valueAt(index);
- return true;
- }
- return false;
-}
-
-bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
- const Key** outKey, const Behavior** outBehavior) const {
- const Key* key;
- if (getKey(keyCode, &key)) {
- const Behavior* behavior = key->firstBehavior;
- while (behavior) {
- if (matchesMetaState(metaState, behavior->metaState)) {
- *outKey = key;
- *outBehavior = behavior;
- return true;
- }
- behavior = behavior->next;
- }
- }
- return false;
-}
-
-bool KeyCharacterMap::matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState) {
- // Behavior must have at least the set of meta states specified.
- // And if the key event has CTRL, ALT or META then the behavior must exactly
- // match those, taking into account that a behavior can specify that it handles
- // one, both or either of a left/right modifier pair.
- if ((eventMetaState & behaviorMetaState) == behaviorMetaState) {
- const int32_t EXACT_META_STATES =
- AMETA_CTRL_ON | AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON
- | AMETA_ALT_ON | AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON
- | AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON;
- int32_t unmatchedMetaState = eventMetaState & ~behaviorMetaState & EXACT_META_STATES;
- if (behaviorMetaState & AMETA_CTRL_ON) {
- unmatchedMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON);
- } else if (behaviorMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
- unmatchedMetaState &= ~AMETA_CTRL_ON;
- }
- if (behaviorMetaState & AMETA_ALT_ON) {
- unmatchedMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON);
- } else if (behaviorMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
- unmatchedMetaState &= ~AMETA_ALT_ON;
- }
- if (behaviorMetaState & AMETA_META_ON) {
- unmatchedMetaState &= ~(AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
- } else if (behaviorMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
- unmatchedMetaState &= ~AMETA_META_ON;
- }
- return !unmatchedMetaState;
- }
- return false;
-}
-
-bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
- if (!ch) {
- return false;
- }
-
- for (size_t i = 0; i < mKeys.size(); i++) {
- const Key* key = mKeys.valueAt(i);
-
- // Try to find the most general behavior that maps to this character.
- // For example, the base key behavior will usually be last in the list.
- const Behavior* found = NULL;
- for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
- if (behavior->character == ch) {
- found = behavior;
- }
- }
- if (found) {
- *outKeyCode = mKeys.keyAt(i);
- *outMetaState = found->metaState;
- return true;
- }
- }
- return false;
-}
-
-void KeyCharacterMap::addKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time) {
- outEvents.push();
- KeyEvent& event = outEvents.editTop();
- event.initialize(deviceId, AINPUT_SOURCE_KEYBOARD,
- down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
- 0, keyCode, 0, metaState, 0, time, time);
-}
-
-void KeyCharacterMap::addMetaKeys(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t* currentMetaState) {
- // Add and remove meta keys symmetrically.
- if (down) {
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
-
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
- AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
- AMETA_SHIFT_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
- AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
- AMETA_ALT_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
- AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
- AMETA_CTRL_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
- AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
- AMETA_META_ON, currentMetaState);
-
- addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
- addSingleEphemeralMetaKey(outEvents, deviceId, metaState, true, time,
- AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
- } else {
- addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_FUNCTION, AMETA_FUNCTION_ON, currentMetaState);
- addSingleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_SYM, AMETA_SYM_ON, currentMetaState);
-
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_META_LEFT, AMETA_META_LEFT_ON,
- AKEYCODE_META_RIGHT, AMETA_META_RIGHT_ON,
- AMETA_META_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_CTRL_LEFT, AMETA_CTRL_LEFT_ON,
- AKEYCODE_CTRL_RIGHT, AMETA_CTRL_RIGHT_ON,
- AMETA_CTRL_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON,
- AKEYCODE_ALT_RIGHT, AMETA_ALT_RIGHT_ON,
- AMETA_ALT_ON, currentMetaState);
- addDoubleEphemeralMetaKey(outEvents, deviceId, metaState, false, time,
- AKEYCODE_SHIFT_LEFT, AMETA_SHIFT_LEFT_ON,
- AKEYCODE_SHIFT_RIGHT, AMETA_SHIFT_RIGHT_ON,
- AMETA_SHIFT_ON, currentMetaState);
-
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, currentMetaState);
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_NUM_LOCK, AMETA_NUM_LOCK_ON, currentMetaState);
- addLockedMetaKey(outEvents, deviceId, metaState, time,
- AKEYCODE_CAPS_LOCK, AMETA_CAPS_LOCK_ON, currentMetaState);
- }
-}
-
-bool KeyCharacterMap::addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t keyCode, int32_t keyMetaState,
- int32_t* currentMetaState) {
- if ((metaState & keyMetaState) == keyMetaState) {
- *currentMetaState = updateMetaState(keyCode, down, *currentMetaState);
- addKey(outEvents, deviceId, keyCode, *currentMetaState, down, time);
- return true;
- }
- return false;
-}
-
-void KeyCharacterMap::addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t leftKeyCode, int32_t leftKeyMetaState,
- int32_t rightKeyCode, int32_t rightKeyMetaState,
- int32_t eitherKeyMetaState,
- int32_t* currentMetaState) {
- bool specific = false;
- specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
- leftKeyCode, leftKeyMetaState, currentMetaState);
- specific |= addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
- rightKeyCode, rightKeyMetaState, currentMetaState);
-
- if (!specific) {
- addSingleEphemeralMetaKey(outEvents, deviceId, metaState, down, time,
- leftKeyCode, eitherKeyMetaState, currentMetaState);
- }
-}
-
-void KeyCharacterMap::addLockedMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, nsecs_t time,
- int32_t keyCode, int32_t keyMetaState,
- int32_t* currentMetaState) {
- if ((metaState & keyMetaState) == keyMetaState) {
- *currentMetaState = updateMetaState(keyCode, true, *currentMetaState);
- addKey(outEvents, deviceId, keyCode, *currentMetaState, true, time);
- *currentMetaState = updateMetaState(keyCode, false, *currentMetaState);
- addKey(outEvents, deviceId, keyCode, *currentMetaState, false, time);
- }
-}
-
-#if HAVE_ANDROID_OS
-sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) {
- sp<KeyCharacterMap> map = new KeyCharacterMap();
- map->mType = parcel->readInt32();
- size_t numKeys = parcel->readInt32();
- if (parcel->errorCheck()) {
- return NULL;
- }
-
- for (size_t i = 0; i < numKeys; i++) {
- int32_t keyCode = parcel->readInt32();
- char16_t label = parcel->readInt32();
- char16_t number = parcel->readInt32();
- if (parcel->errorCheck()) {
- return NULL;
- }
-
- Key* key = new Key();
- key->label = label;
- key->number = number;
- map->mKeys.add(keyCode, key);
-
- Behavior* lastBehavior = NULL;
- while (parcel->readInt32()) {
- int32_t metaState = parcel->readInt32();
- char16_t character = parcel->readInt32();
- int32_t fallbackKeyCode = parcel->readInt32();
- if (parcel->errorCheck()) {
- return NULL;
- }
-
- Behavior* behavior = new Behavior();
- behavior->metaState = metaState;
- behavior->character = character;
- behavior->fallbackKeyCode = fallbackKeyCode;
- if (lastBehavior) {
- lastBehavior->next = behavior;
- } else {
- key->firstBehavior = behavior;
- }
- lastBehavior = behavior;
- }
-
- if (parcel->errorCheck()) {
- return NULL;
- }
- }
- return map;
-}
-
-void KeyCharacterMap::writeToParcel(Parcel* parcel) const {
- parcel->writeInt32(mType);
-
- size_t numKeys = mKeys.size();
- parcel->writeInt32(numKeys);
- for (size_t i = 0; i < numKeys; i++) {
- int32_t keyCode = mKeys.keyAt(i);
- const Key* key = mKeys.valueAt(i);
- parcel->writeInt32(keyCode);
- parcel->writeInt32(key->label);
- parcel->writeInt32(key->number);
- for (const Behavior* behavior = key->firstBehavior; behavior != NULL;
- behavior = behavior->next) {
- parcel->writeInt32(1);
- parcel->writeInt32(behavior->metaState);
- parcel->writeInt32(behavior->character);
- parcel->writeInt32(behavior->fallbackKeyCode);
- }
- parcel->writeInt32(0);
- }
-}
-#endif
-
-
-// --- KeyCharacterMap::Key ---
-
-KeyCharacterMap::Key::Key() :
- label(0), number(0), firstBehavior(NULL) {
-}
-
-KeyCharacterMap::Key::Key(const Key& other) :
- label(other.label), number(other.number),
- firstBehavior(other.firstBehavior ? new Behavior(*other.firstBehavior) : NULL) {
-}
-
-KeyCharacterMap::Key::~Key() {
- Behavior* behavior = firstBehavior;
- while (behavior) {
- Behavior* next = behavior->next;
- delete behavior;
- behavior = next;
- }
-}
-
-
-// --- KeyCharacterMap::Behavior ---
-
-KeyCharacterMap::Behavior::Behavior() :
- next(NULL), metaState(0), character(0), fallbackKeyCode(0) {
-}
-
-KeyCharacterMap::Behavior::Behavior(const Behavior& other) :
- next(other.next ? new Behavior(*other.next) : NULL),
- metaState(other.metaState), character(other.character),
- fallbackKeyCode(other.fallbackKeyCode) {
-}
-
-
-// --- KeyCharacterMap::Parser ---
-
-KeyCharacterMap::Parser::Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format) :
- mMap(map), mTokenizer(tokenizer), mFormat(format), mState(STATE_TOP) {
-}
-
-KeyCharacterMap::Parser::~Parser() {
-}
-
-status_t KeyCharacterMap::Parser::parse() {
- while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
- ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
-#endif
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- switch (mState) {
- case STATE_TOP: {
- String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
- if (keywordToken == "type") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseType();
- if (status) return status;
- } else if (keywordToken == "map") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseMap();
- if (status) return status;
- } else if (keywordToken == "key") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseKey();
- if (status) return status;
- } else {
- ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
- keywordToken.string());
- return BAD_VALUE;
- }
- break;
- }
-
- case STATE_KEY: {
- status_t status = parseKeyProperty();
- if (status) return status;
- break;
- }
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
- mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
- return BAD_VALUE;
- }
- }
-
- mTokenizer->nextLine();
- }
-
- if (mState != STATE_TOP) {
- ALOGE("%s: Unterminated key description at end of file.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- if (mMap->mType == KEYBOARD_TYPE_UNKNOWN) {
- ALOGE("%s: Keyboard layout missing required keyboard 'type' declaration.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- if (mFormat == FORMAT_BASE) {
- if (mMap->mType == KEYBOARD_TYPE_OVERLAY) {
- ALOGE("%s: Base keyboard layout must specify a keyboard 'type' other than 'OVERLAY'.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- } else if (mFormat == FORMAT_OVERLAY) {
- if (mMap->mType != KEYBOARD_TYPE_OVERLAY) {
- ALOGE("%s: Overlay keyboard layout missing required keyboard "
- "'type OVERLAY' declaration.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- }
-
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseType() {
- if (mMap->mType != KEYBOARD_TYPE_UNKNOWN) {
- ALOGE("%s: Duplicate keyboard 'type' declaration.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- KeyboardType type;
- String8 typeToken = mTokenizer->nextToken(WHITESPACE);
- if (typeToken == "NUMERIC") {
- type = KEYBOARD_TYPE_NUMERIC;
- } else if (typeToken == "PREDICTIVE") {
- type = KEYBOARD_TYPE_PREDICTIVE;
- } else if (typeToken == "ALPHA") {
- type = KEYBOARD_TYPE_ALPHA;
- } else if (typeToken == "FULL") {
- type = KEYBOARD_TYPE_FULL;
- } else if (typeToken == "SPECIAL_FUNCTION") {
- type = KEYBOARD_TYPE_SPECIAL_FUNCTION;
- } else if (typeToken == "OVERLAY") {
- type = KEYBOARD_TYPE_OVERLAY;
- } else {
- ALOGE("%s: Expected keyboard type label, got '%s'.", mTokenizer->getLocation().string(),
- typeToken.string());
- return BAD_VALUE;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed type: type=%d.", type);
-#endif
- mMap->mType = type;
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseMap() {
- String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
- if (keywordToken == "key") {
- mTokenizer->skipDelimiters(WHITESPACE);
- return parseMapKey();
- }
- ALOGE("%s: Expected keyword after 'map', got '%s'.", mTokenizer->getLocation().string(),
- keywordToken.string());
- return BAD_VALUE;
-}
-
-status_t KeyCharacterMap::Parser::parseMapKey() {
- String8 codeToken = mTokenizer->nextToken(WHITESPACE);
- bool mapUsage = false;
- if (codeToken == "usage") {
- mapUsage = true;
- mTokenizer->skipDelimiters(WHITESPACE);
- codeToken = mTokenizer->nextToken(WHITESPACE);
- }
-
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
- KeyedVector<int32_t, int32_t>& map =
- mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
- if (map.indexOfKey(code) >= 0) {
- ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
- if (!keyCode) {
- ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
- keyCodeToken.string());
- return BAD_VALUE;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed map key %s: code=%d, keyCode=%d.",
- mapUsage ? "usage" : "scan code", code, keyCode);
-#endif
- map.add(code, keyCode);
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKey() {
- String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
- if (!keyCode) {
- ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
- keyCodeToken.string());
- return BAD_VALUE;
- }
- if (mMap->mKeys.indexOfKey(keyCode) >= 0) {
- ALOGE("%s: Duplicate entry for key code '%s'.", mTokenizer->getLocation().string(),
- keyCodeToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 openBraceToken = mTokenizer->nextToken(WHITESPACE);
- if (openBraceToken != "{") {
- ALOGE("%s: Expected '{' after key code label, got '%s'.",
- mTokenizer->getLocation().string(), openBraceToken.string());
- return BAD_VALUE;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed beginning of key: keyCode=%d.", keyCode);
-#endif
- mKeyCode = keyCode;
- mMap->mKeys.add(keyCode, new Key());
- mState = STATE_KEY;
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseKeyProperty() {
- Key* key = mMap->mKeys.valueFor(mKeyCode);
- String8 token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
- if (token == "}") {
- mState = STATE_TOP;
- return finishKey(key);
- }
-
- Vector<Property> properties;
-
- // Parse all comma-delimited property names up to the first colon.
- for (;;) {
- if (token == "label") {
- properties.add(Property(PROPERTY_LABEL));
- } else if (token == "number") {
- properties.add(Property(PROPERTY_NUMBER));
- } else {
- int32_t metaState;
- status_t status = parseModifier(token, &metaState);
- if (status) {
- ALOGE("%s: Expected a property name or modifier, got '%s'.",
- mTokenizer->getLocation().string(), token.string());
- return status;
- }
- properties.add(Property(PROPERTY_META, metaState));
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol()) {
- char ch = mTokenizer->nextChar();
- if (ch == ':') {
- break;
- } else if (ch == ',') {
- mTokenizer->skipDelimiters(WHITESPACE);
- token = mTokenizer->nextToken(WHITESPACE_OR_PROPERTY_DELIMITER);
- continue;
- }
- }
-
- ALOGE("%s: Expected ',' or ':' after property name.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- // Parse behavior after the colon.
- mTokenizer->skipDelimiters(WHITESPACE);
-
- Behavior behavior;
- bool haveCharacter = false;
- bool haveFallback = false;
-
- do {
- char ch = mTokenizer->peekChar();
- if (ch == '\'') {
- char16_t character;
- status_t status = parseCharacterLiteral(&character);
- if (status || !character) {
- ALOGE("%s: Invalid character literal for key.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- if (haveCharacter) {
- ALOGE("%s: Cannot combine multiple character literals or 'none'.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- behavior.character = character;
- haveCharacter = true;
- } else {
- token = mTokenizer->nextToken(WHITESPACE);
- if (token == "none") {
- if (haveCharacter) {
- ALOGE("%s: Cannot combine multiple character literals or 'none'.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- haveCharacter = true;
- } else if (token == "fallback") {
- mTokenizer->skipDelimiters(WHITESPACE);
- token = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = getKeyCodeByLabel(token.string());
- if (!keyCode) {
- ALOGE("%s: Invalid key code label for fallback behavior, got '%s'.",
- mTokenizer->getLocation().string(),
- token.string());
- return BAD_VALUE;
- }
- if (haveFallback) {
- ALOGE("%s: Cannot combine multiple fallback key codes.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- behavior.fallbackKeyCode = keyCode;
- haveFallback = true;
- } else {
- ALOGE("%s: Expected a key behavior after ':'.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- } while (!mTokenizer->isEol() && mTokenizer->peekChar() != '#');
-
- // Add the behavior.
- for (size_t i = 0; i < properties.size(); i++) {
- const Property& property = properties.itemAt(i);
- switch (property.property) {
- case PROPERTY_LABEL:
- if (key->label) {
- ALOGE("%s: Duplicate label for key.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- key->label = behavior.character;
-#if DEBUG_PARSER
- ALOGD("Parsed key label: keyCode=%d, label=%d.", mKeyCode, key->label);
-#endif
- break;
- case PROPERTY_NUMBER:
- if (key->number) {
- ALOGE("%s: Duplicate number for key.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- key->number = behavior.character;
-#if DEBUG_PARSER
- ALOGD("Parsed key number: keyCode=%d, number=%d.", mKeyCode, key->number);
-#endif
- break;
- case PROPERTY_META: {
- for (Behavior* b = key->firstBehavior; b; b = b->next) {
- if (b->metaState == property.metaState) {
- ALOGE("%s: Duplicate key behavior for modifier.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- }
- Behavior* newBehavior = new Behavior(behavior);
- newBehavior->metaState = property.metaState;
- newBehavior->next = key->firstBehavior;
- key->firstBehavior = newBehavior;
-#if DEBUG_PARSER
- ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode,
- newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode);
-#endif
- break;
- }
- }
- }
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::finishKey(Key* key) {
- // Fill in default number property.
- if (!key->number) {
- char16_t digit = 0;
- char16_t symbol = 0;
- for (Behavior* b = key->firstBehavior; b; b = b->next) {
- char16_t ch = b->character;
- if (ch) {
- if (ch >= '0' && ch <= '9') {
- digit = ch;
- } else if (ch == '(' || ch == ')' || ch == '#' || ch == '*'
- || ch == '-' || ch == '+' || ch == ',' || ch == '.'
- || ch == '\'' || ch == ':' || ch == ';' || ch == '/') {
- symbol = ch;
- }
- }
- }
- key->number = digit ? digit : symbol;
- }
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseModifier(const String8& token, int32_t* outMetaState) {
- if (token == "base") {
- *outMetaState = 0;
- return NO_ERROR;
- }
-
- int32_t combinedMeta = 0;
-
- const char* str = token.string();
- const char* start = str;
- for (const char* cur = str; ; cur++) {
- char ch = *cur;
- if (ch == '+' || ch == '\0') {
- size_t len = cur - start;
- int32_t metaState = 0;
- for (size_t i = 0; i < sizeof(modifiers) / sizeof(Modifier); i++) {
- if (strlen(modifiers[i].label) == len
- && strncmp(modifiers[i].label, start, len) == 0) {
- metaState = modifiers[i].metaState;
- break;
- }
- }
- if (!metaState) {
- return BAD_VALUE;
- }
- if (combinedMeta & metaState) {
- ALOGE("%s: Duplicate modifier combination '%s'.",
- mTokenizer->getLocation().string(), token.string());
- return BAD_VALUE;
- }
-
- combinedMeta |= metaState;
- start = cur + 1;
-
- if (ch == '\0') {
- break;
- }
- }
- }
- *outMetaState = combinedMeta;
- return NO_ERROR;
-}
-
-status_t KeyCharacterMap::Parser::parseCharacterLiteral(char16_t* outCharacter) {
- char ch = mTokenizer->nextChar();
- if (ch != '\'') {
- goto Error;
- }
-
- ch = mTokenizer->nextChar();
- if (ch == '\\') {
- // Escape sequence.
- ch = mTokenizer->nextChar();
- if (ch == 'n') {
- *outCharacter = '\n';
- } else if (ch == 't') {
- *outCharacter = '\t';
- } else if (ch == '\\') {
- *outCharacter = '\\';
- } else if (ch == '\'') {
- *outCharacter = '\'';
- } else if (ch == '"') {
- *outCharacter = '"';
- } else if (ch == 'u') {
- *outCharacter = 0;
- for (int i = 0; i < 4; i++) {
- ch = mTokenizer->nextChar();
- int digit;
- if (ch >= '0' && ch <= '9') {
- digit = ch - '0';
- } else if (ch >= 'A' && ch <= 'F') {
- digit = ch - 'A' + 10;
- } else if (ch >= 'a' && ch <= 'f') {
- digit = ch - 'a' + 10;
- } else {
- goto Error;
- }
- *outCharacter = (*outCharacter << 4) | digit;
- }
- } else {
- goto Error;
- }
- } else if (ch >= 32 && ch <= 126 && ch != '\'') {
- // ASCII literal character.
- *outCharacter = ch;
- } else {
- goto Error;
- }
-
- ch = mTokenizer->nextChar();
- if (ch != '\'') {
- goto Error;
- }
-
- // Ensure that we consumed the entire token.
- if (mTokenizer->nextToken(WHITESPACE).isEmpty()) {
- return NO_ERROR;
- }
-
-Error:
- ALOGE("%s: Malformed character literal.", mTokenizer->getLocation().string());
- return BAD_VALUE;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/KeyCharacterMap.h b/widget/gonk/libui/KeyCharacterMap.h
deleted file mode 100644
index c7a684105..000000000
--- a/widget/gonk/libui/KeyCharacterMap.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_KEY_CHARACTER_MAP_H
-#define _ANDROIDFW_KEY_CHARACTER_MAP_H
-
-#include <stdint.h>
-
-#if HAVE_ANDROID_OS
-#include <binder/IBinder.h>
-#endif
-
-#include "Input.h"
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include "Tokenizer.h"
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-/**
- * Describes a mapping from Android key codes to characters.
- * Also specifies other functions of the keyboard such as the keyboard type
- * and key modifier semantics.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyCharacterMap : public RefBase {
-public:
- enum KeyboardType {
- KEYBOARD_TYPE_UNKNOWN = 0,
- KEYBOARD_TYPE_NUMERIC = 1,
- KEYBOARD_TYPE_PREDICTIVE = 2,
- KEYBOARD_TYPE_ALPHA = 3,
- KEYBOARD_TYPE_FULL = 4,
- KEYBOARD_TYPE_SPECIAL_FUNCTION = 5,
- KEYBOARD_TYPE_OVERLAY = 6,
- };
-
- enum Format {
- // Base keyboard layout, may contain device-specific options, such as "type" declaration.
- FORMAT_BASE = 0,
- // Overlay keyboard layout, more restrictive, may be published by applications,
- // cannot override device-specific options.
- FORMAT_OVERLAY = 1,
- // Either base or overlay layout ok.
- FORMAT_ANY = 2,
- };
-
- // Substitute key code and meta state for fallback action.
- struct FallbackAction {
- int32_t keyCode;
- int32_t metaState;
- };
-
- /* Loads a key character map from a file. */
- static status_t load(const String8& filename, Format format, sp<KeyCharacterMap>* outMap);
-
- /* Loads a key character map from its string contents. */
- static status_t loadContents(const String8& filename,
- const char* contents, Format format, sp<KeyCharacterMap>* outMap);
-
- /* Combines a base key character map and an overlay. */
- static sp<KeyCharacterMap> combine(const sp<KeyCharacterMap>& base,
- const sp<KeyCharacterMap>& overlay);
-
- /* Returns an empty key character map. */
- static sp<KeyCharacterMap> empty();
-
- /* Gets the keyboard type. */
- int32_t getKeyboardType() const;
-
- /* Gets the primary character for this key as in the label physically printed on it.
- * Returns 0 if none (eg. for non-printing keys). */
- char16_t getDisplayLabel(int32_t keyCode) const;
-
- /* Gets the Unicode character for the number or symbol generated by the key
- * when the keyboard is used as a dialing pad.
- * Returns 0 if no number or symbol is generated.
- */
- char16_t getNumber(int32_t keyCode) const;
-
- /* Gets the Unicode character generated by the key and meta key modifiers.
- * Returns 0 if no character is generated.
- */
- char16_t getCharacter(int32_t keyCode, int32_t metaState) const;
-
- /* Gets the fallback action to use by default if the application does not
- * handle the specified key.
- * Returns true if an action was available, false if none.
- */
- bool getFallbackAction(int32_t keyCode, int32_t metaState,
- FallbackAction* outFallbackAction) const;
-
- /* Gets the first matching Unicode character that can be generated by the key,
- * preferring the one with the specified meta key modifiers.
- * Returns 0 if no matching character is generated.
- */
- char16_t getMatch(int32_t keyCode, const char16_t* chars,
- size_t numChars, int32_t metaState) const;
-
- /* Gets a sequence of key events that could plausibly generate the specified
- * character sequence. Returns false if some of the characters cannot be generated.
- */
- bool getEvents(int32_t deviceId, const char16_t* chars, size_t numChars,
- Vector<KeyEvent>& outEvents) const;
-
- /* Maps a scan code and usage code to a key code, in case this key map overrides
- * the mapping in some way. */
- status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const;
-
-#if HAVE_ANDROID_OS
- /* Reads a key map from a parcel. */
- static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
-
- /* Writes a key map to a parcel. */
- void writeToParcel(Parcel* parcel) const;
-#endif
-
-protected:
- virtual ~KeyCharacterMap();
-
-private:
- struct Behavior {
- Behavior();
- Behavior(const Behavior& other);
-
- /* The next behavior in the list, or NULL if none. */
- Behavior* next;
-
- /* The meta key modifiers for this behavior. */
- int32_t metaState;
-
- /* The character to insert. */
- char16_t character;
-
- /* The fallback keycode if the key is not handled. */
- int32_t fallbackKeyCode;
- };
-
- struct Key {
- Key();
- Key(const Key& other);
- ~Key();
-
- /* The single character label printed on the key, or 0 if none. */
- char16_t label;
-
- /* The number or symbol character generated by the key, or 0 if none. */
- char16_t number;
-
- /* The list of key behaviors sorted from most specific to least specific
- * meta key binding. */
- Behavior* firstBehavior;
- };
-
- class Parser {
- enum State {
- STATE_TOP = 0,
- STATE_KEY = 1,
- };
-
- enum {
- PROPERTY_LABEL = 1,
- PROPERTY_NUMBER = 2,
- PROPERTY_META = 3,
- };
-
- struct Property {
- inline Property(int32_t property = 0, int32_t metaState = 0) :
- property(property), metaState(metaState) { }
-
- int32_t property;
- int32_t metaState;
- };
-
- KeyCharacterMap* mMap;
- Tokenizer* mTokenizer;
- Format mFormat;
- State mState;
- int32_t mKeyCode;
-
- public:
- Parser(KeyCharacterMap* map, Tokenizer* tokenizer, Format format);
- ~Parser();
- status_t parse();
-
- private:
- status_t parseType();
- status_t parseMap();
- status_t parseMapKey();
- status_t parseKey();
- status_t parseKeyProperty();
- status_t finishKey(Key* key);
- status_t parseModifier(const String8& token, int32_t* outMetaState);
- status_t parseCharacterLiteral(char16_t* outCharacter);
- };
-
- static sp<KeyCharacterMap> sEmpty;
-
- KeyedVector<int32_t, Key*> mKeys;
- int mType;
-
- KeyedVector<int32_t, int32_t> mKeysByScanCode;
- KeyedVector<int32_t, int32_t> mKeysByUsageCode;
-
- KeyCharacterMap();
- KeyCharacterMap(const KeyCharacterMap& other);
-
- bool getKey(int32_t keyCode, const Key** outKey) const;
- bool getKeyBehavior(int32_t keyCode, int32_t metaState,
- const Key** outKey, const Behavior** outBehavior) const;
- static bool matchesMetaState(int32_t eventMetaState, int32_t behaviorMetaState);
-
- bool findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const;
-
- static status_t load(Tokenizer* tokenizer, Format format, sp<KeyCharacterMap>* outMap);
-
- static void addKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t keyCode, int32_t metaState, bool down, nsecs_t time);
- static void addMetaKeys(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t* currentMetaState);
- static bool addSingleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t keyCode, int32_t keyMetaState,
- int32_t* currentMetaState);
- static void addDoubleEphemeralMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, bool down, nsecs_t time,
- int32_t leftKeyCode, int32_t leftKeyMetaState,
- int32_t rightKeyCode, int32_t rightKeyMetaState,
- int32_t eitherKeyMetaState,
- int32_t* currentMetaState);
- static void addLockedMetaKey(Vector<KeyEvent>& outEvents,
- int32_t deviceId, int32_t metaState, nsecs_t time,
- int32_t keyCode, int32_t keyMetaState,
- int32_t* currentMetaState);
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/widget/gonk/libui/KeyLayoutMap.cpp b/widget/gonk/libui/KeyLayoutMap.cpp
deleted file mode 100644
index 8af4b84e0..000000000
--- a/widget/gonk/libui/KeyLayoutMap.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "KeyLayoutMap"
-#include "cutils_log.h"
-
-#include <stdlib.h>
-#include "android_keycodes.h"
-#include "Keyboard.h"
-#include "KeyLayoutMap.h"
-#include <utils/Errors.h>
-#include "Tokenizer.h"
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-// Enables debug output for mapping.
-#define DEBUG_MAPPING 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-
-// --- KeyLayoutMap ---
-
-KeyLayoutMap::KeyLayoutMap() {
-}
-
-KeyLayoutMap::~KeyLayoutMap() {
-}
-
-status_t KeyLayoutMap::load(const String8& filename, sp<KeyLayoutMap>* outMap) {
- outMap->clear();
-
- Tokenizer* tokenizer;
- status_t status = Tokenizer::open(filename, &tokenizer);
- if (status) {
- ALOGE("Error %d opening key layout map file %s.", status, filename.string());
- } else {
- sp<KeyLayoutMap> map = new KeyLayoutMap();
- if (!map.get()) {
- ALOGE("Error allocating key layout map.");
- status = NO_MEMORY;
- } else {
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
- Parser parser(map.get(), tokenizer);
- status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
- ALOGD("Parsed key layout map file '%s' %d lines in %0.3fms.",
- tokenizer->getFilename().string(), tokenizer->getLineNumber(),
- elapsedTime / 1000000.0);
-#endif
- if (!status) {
- *outMap = map;
- }
- }
- delete tokenizer;
- }
- return status;
-}
-
-status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t usageCode,
- int32_t* outKeyCode, uint32_t* outFlags) const {
- const Key* key = getKey(scanCode, usageCode);
- if (!key) {
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode);
-#endif
- *outKeyCode = AKEYCODE_UNKNOWN;
- *outFlags = 0;
- return NAME_NOT_FOUND;
- }
-
- *outKeyCode = key->keyCode;
- *outFlags = key->flags;
-
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d, outFlags=0x%08x.",
- scanCode, usageCode, *outKeyCode, *outFlags);
-#endif
- return NO_ERROR;
-}
-
-const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCode) const {
- if (usageCode) {
- ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
- if (index >= 0) {
- return &mKeysByUsageCode.valueAt(index);
- }
- }
- if (scanCode) {
- ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
- if (index >= 0) {
- return &mKeysByScanCode.valueAt(index);
- }
- }
- return NULL;
-}
-
-status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
- const size_t N = mKeysByScanCode.size();
- for (size_t i=0; i<N; i++) {
- if (mKeysByScanCode.valueAt(i).keyCode == keyCode) {
- outScanCodes->add(mKeysByScanCode.keyAt(i));
- }
- }
- return NO_ERROR;
-}
-
-status_t KeyLayoutMap::mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
- ssize_t index = mAxes.indexOfKey(scanCode);
- if (index < 0) {
-#if DEBUG_MAPPING
- ALOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
-#endif
- return NAME_NOT_FOUND;
- }
-
- *outAxisInfo = mAxes.valueAt(index);
-
-#if DEBUG_MAPPING
- ALOGD("mapAxis: scanCode=%d ~ Result mode=%d, axis=%d, highAxis=%d, "
- "splitValue=%d, flatOverride=%d.",
- scanCode,
- outAxisInfo->mode, outAxisInfo->axis, outAxisInfo->highAxis,
- outAxisInfo->splitValue, outAxisInfo->flatOverride);
-#endif
- return NO_ERROR;
-}
-
-status_t KeyLayoutMap::findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const {
- const size_t N = mLedsByScanCode.size();
- for (size_t i = 0; i < N; i++) {
- if (mLedsByScanCode.valueAt(i).ledCode == ledCode) {
- *outScanCode = mLedsByScanCode.keyAt(i);
-#if DEBUG_MAPPING
- ALOGD("findScanCodeForLed: ledCode=%d, scanCode=%d.", ledCode, *outScanCode);
-#endif
- return NO_ERROR;
- }
- }
-#if DEBUG_MAPPING
- ALOGD("findScanCodeForLed: ledCode=%d ~ Not found.", ledCode);
-#endif
- return NAME_NOT_FOUND;
-}
-
-status_t KeyLayoutMap::findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const {
- const size_t N = mLedsByUsageCode.size();
- for (size_t i = 0; i < N; i++) {
- if (mLedsByUsageCode.valueAt(i).ledCode == ledCode) {
- *outUsageCode = mLedsByUsageCode.keyAt(i);
-#if DEBUG_MAPPING
- ALOGD("findUsageForLed: ledCode=%d, usage=%x.", ledCode, *outUsageCode);
-#endif
- return NO_ERROR;
- }
- }
-#if DEBUG_MAPPING
- ALOGD("findUsageForLed: ledCode=%d ~ Not found.", ledCode);
-#endif
- return NAME_NOT_FOUND;
-}
-
-
-// --- KeyLayoutMap::Parser ---
-
-KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
- mMap(map), mTokenizer(tokenizer) {
-}
-
-KeyLayoutMap::Parser::~Parser() {
-}
-
-status_t KeyLayoutMap::Parser::parse() {
- while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
- ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
-#endif
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
- if (keywordToken == "key") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseKey();
- if (status) return status;
- } else if (keywordToken == "axis") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseAxis();
- if (status) return status;
- } else if (keywordToken == "led") {
- mTokenizer->skipDelimiters(WHITESPACE);
- status_t status = parseLed();
- if (status) return status;
- } else {
- ALOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
- keywordToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
- mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
- return BAD_VALUE;
- }
- }
-
- mTokenizer->nextLine();
- }
- return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseKey() {
- String8 codeToken = mTokenizer->nextToken(WHITESPACE);
- bool mapUsage = false;
- if (codeToken == "usage") {
- mapUsage = true;
- mTokenizer->skipDelimiters(WHITESPACE);
- codeToken = mTokenizer->nextToken(WHITESPACE);
- }
-
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected key %s number, got '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
- KeyedVector<int32_t, Key>& map =
- mapUsage ? mMap->mKeysByUsageCode : mMap->mKeysByScanCode;
- if (map.indexOfKey(code) >= 0) {
- ALOGE("%s: Duplicate entry for key %s '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 keyCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t keyCode = getKeyCodeByLabel(keyCodeToken.string());
- if (!keyCode) {
- ALOGE("%s: Expected key code label, got '%s'.", mTokenizer->getLocation().string(),
- keyCodeToken.string());
- return BAD_VALUE;
- }
-
- uint32_t flags = 0;
- for (;;) {
- mTokenizer->skipDelimiters(WHITESPACE);
- if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') break;
-
- String8 flagToken = mTokenizer->nextToken(WHITESPACE);
- uint32_t flag = getKeyFlagByLabel(flagToken.string());
- if (!flag) {
- ALOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
- flagToken.string());
- return BAD_VALUE;
- }
- if (flags & flag) {
- ALOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
- flagToken.string());
- return BAD_VALUE;
- }
- flags |= flag;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed key %s: code=%d, keyCode=%d, flags=0x%08x.",
- mapUsage ? "usage" : "scan code", code, keyCode, flags);
-#endif
- Key key;
- key.keyCode = keyCode;
- key.flags = flags;
- map.add(code, key);
- return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseAxis() {
- String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
- char* end;
- int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
- scanCodeToken.string());
- return BAD_VALUE;
- }
- if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
- ALOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
- scanCodeToken.string());
- return BAD_VALUE;
- }
-
- AxisInfo axisInfo;
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 token = mTokenizer->nextToken(WHITESPACE);
- if (token == "invert") {
- axisInfo.mode = AxisInfo::MODE_INVERT;
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 axisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.axis = getAxisByLabel(axisToken.string());
- if (axisInfo.axis < 0) {
- ALOGE("%s: Expected inverted axis label, got '%s'.",
- mTokenizer->getLocation().string(), axisToken.string());
- return BAD_VALUE;
- }
- } else if (token == "split") {
- axisInfo.mode = AxisInfo::MODE_SPLIT;
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 splitToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.splitValue = int32_t(strtol(splitToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected split value, got '%s'.",
- mTokenizer->getLocation().string(), splitToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 lowAxisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.axis = getAxisByLabel(lowAxisToken.string());
- if (axisInfo.axis < 0) {
- ALOGE("%s: Expected low axis label, got '%s'.",
- mTokenizer->getLocation().string(), lowAxisToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 highAxisToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.highAxis = getAxisByLabel(highAxisToken.string());
- if (axisInfo.highAxis < 0) {
- ALOGE("%s: Expected high axis label, got '%s'.",
- mTokenizer->getLocation().string(), highAxisToken.string());
- return BAD_VALUE;
- }
- } else {
- axisInfo.axis = getAxisByLabel(token.string());
- if (axisInfo.axis < 0) {
- ALOGE("%s: Expected axis label, 'split' or 'invert', got '%s'.",
- mTokenizer->getLocation().string(), token.string());
- return BAD_VALUE;
- }
- }
-
- for (;;) {
- mTokenizer->skipDelimiters(WHITESPACE);
- if (mTokenizer->isEol() || mTokenizer->peekChar() == '#') {
- break;
- }
- String8 keywordToken = mTokenizer->nextToken(WHITESPACE);
- if (keywordToken == "flat") {
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 flatToken = mTokenizer->nextToken(WHITESPACE);
- axisInfo.flatOverride = int32_t(strtol(flatToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected flat value, got '%s'.",
- mTokenizer->getLocation().string(), flatToken.string());
- return BAD_VALUE;
- }
- } else {
- ALOGE("%s: Expected keyword 'flat', got '%s'.",
- mTokenizer->getLocation().string(), keywordToken.string());
- return BAD_VALUE;
- }
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed axis: scanCode=%d, mode=%d, axis=%d, highAxis=%d, "
- "splitValue=%d, flatOverride=%d.",
- scanCode,
- axisInfo.mode, axisInfo.axis, axisInfo.highAxis,
- axisInfo.splitValue, axisInfo.flatOverride);
-#endif
- mMap->mAxes.add(scanCode, axisInfo);
- return NO_ERROR;
-}
-
-status_t KeyLayoutMap::Parser::parseLed() {
- String8 codeToken = mTokenizer->nextToken(WHITESPACE);
- bool mapUsage = false;
- if (codeToken == "usage") {
- mapUsage = true;
- mTokenizer->skipDelimiters(WHITESPACE);
- codeToken = mTokenizer->nextToken(WHITESPACE);
- }
- char* end;
- int32_t code = int32_t(strtol(codeToken.string(), &end, 0));
- if (*end) {
- ALOGE("%s: Expected led %s number, got '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
-
- KeyedVector<int32_t, Led>& map = mapUsage ? mMap->mLedsByUsageCode : mMap->mLedsByScanCode;
- if (map.indexOfKey(code) >= 0) {
- ALOGE("%s: Duplicate entry for led %s '%s'.", mTokenizer->getLocation().string(),
- mapUsage ? "usage" : "scan code", codeToken.string());
- return BAD_VALUE;
- }
-
- mTokenizer->skipDelimiters(WHITESPACE);
- String8 ledCodeToken = mTokenizer->nextToken(WHITESPACE);
- int32_t ledCode = getLedByLabel(ledCodeToken.string());
- if (ledCode < 0) {
- ALOGE("%s: Expected LED code label, got '%s'.", mTokenizer->getLocation().string(),
- ledCodeToken.string());
- return BAD_VALUE;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed led %s: code=%d, ledCode=%d.",
- mapUsage ? "usage" : "scan code", code, ledCode);
-#endif
-
- Led led;
- led.ledCode = ledCode;
- map.add(code, led);
- return NO_ERROR;
-}
-};
diff --git a/widget/gonk/libui/KeyLayoutMap.h b/widget/gonk/libui/KeyLayoutMap.h
deleted file mode 100644
index 8a6113447..000000000
--- a/widget/gonk/libui/KeyLayoutMap.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_KEY_LAYOUT_MAP_H
-#define _ANDROIDFW_KEY_LAYOUT_MAP_H
-
-#include <stdint.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include "Tokenizer.h"
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct AxisInfo {
- enum Mode {
- // Axis value is reported directly.
- MODE_NORMAL = 0,
- // Axis value should be inverted before reporting.
- MODE_INVERT = 1,
- // Axis value should be split into two axes
- MODE_SPLIT = 2,
- };
-
- // Axis mode.
- Mode mode;
-
- // Axis id.
- // When split, this is the axis used for values smaller than the split position.
- int32_t axis;
-
- // When split, this is the axis used for values after higher than the split position.
- int32_t highAxis;
-
- // The split value, or 0 if not split.
- int32_t splitValue;
-
- // The flat value, or -1 if none.
- int32_t flatOverride;
-
- AxisInfo() : mode(MODE_NORMAL), axis(-1), highAxis(-1), splitValue(0), flatOverride(-1) {
- }
-};
-
-/**
- * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
- *
- * This object is immutable after it has been loaded.
- */
-class KeyLayoutMap : public RefBase {
-public:
- static status_t load(const String8& filename, sp<KeyLayoutMap>* outMap);
-
- status_t mapKey(int32_t scanCode, int32_t usageCode,
- int32_t* outKeyCode, uint32_t* outFlags) const;
- status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
- status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const;
- status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const;
-
- status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const;
-
-protected:
- virtual ~KeyLayoutMap();
-
-private:
- struct Key {
- int32_t keyCode;
- uint32_t flags;
- };
-
- struct Led {
- int32_t ledCode;
- };
-
-
- KeyedVector<int32_t, Key> mKeysByScanCode;
- KeyedVector<int32_t, Key> mKeysByUsageCode;
- KeyedVector<int32_t, AxisInfo> mAxes;
- KeyedVector<int32_t, Led> mLedsByScanCode;
- KeyedVector<int32_t, Led> mLedsByUsageCode;
-
- KeyLayoutMap();
-
- const Key* getKey(int32_t scanCode, int32_t usageCode) const;
-
- class Parser {
- KeyLayoutMap* mMap;
- Tokenizer* mTokenizer;
-
- public:
- Parser(KeyLayoutMap* map, Tokenizer* tokenizer);
- ~Parser();
- status_t parse();
-
- private:
- status_t parseKey();
- status_t parseAxis();
- status_t parseLed();
- };
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_LAYOUT_MAP_H
diff --git a/widget/gonk/libui/Keyboard.cpp b/widget/gonk/libui/Keyboard.cpp
deleted file mode 100644
index 62bb53b7b..000000000
--- a/widget/gonk/libui/Keyboard.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Keyboard"
-#include "cutils_log.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "Keyboard.h"
-#include "KeycodeLabels.h"
-#include "KeyLayoutMap.h"
-#include "KeyCharacterMap.h"
-#include "InputDevice.h"
-#include <utils/Errors.h>
-#include <cutils/properties.h>
-
-namespace android {
-
-// --- KeyMap ---
-
-KeyMap::KeyMap() {
-}
-
-KeyMap::~KeyMap() {
-}
-
-status_t KeyMap::load(const InputDeviceIdentifier& deviceIdenfifier,
- const PropertyMap* deviceConfiguration) {
- // Use the configured key layout if available.
- if (deviceConfiguration) {
- String8 keyLayoutName;
- if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
- keyLayoutName)) {
- status_t status = loadKeyLayout(deviceIdenfifier, keyLayoutName);
- if (status == NAME_NOT_FOUND) {
- ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
- "it was not found.",
- deviceIdenfifier.name.string(), keyLayoutName.string());
- }
- }
-
- String8 keyCharacterMapName;
- if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
- keyCharacterMapName)) {
- status_t status = loadKeyCharacterMap(deviceIdenfifier, keyCharacterMapName);
- if (status == NAME_NOT_FOUND) {
- ALOGE("Configuration for keyboard device '%s' requested keyboard character "
- "map '%s' but it was not found.",
- deviceIdenfifier.name.string(), keyLayoutName.string());
- }
- }
-
- if (isComplete()) {
- return OK;
- }
- }
-
- // Try searching by device identifier.
- if (probeKeyMap(deviceIdenfifier, String8::empty())) {
- return OK;
- }
-
- // Fall back on the Generic key map.
- // TODO Apply some additional heuristics here to figure out what kind of
- // generic key map to use (US English, etc.) for typical external keyboards.
- if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
- return OK;
- }
-
- // Try the Virtual key map as a last resort.
- if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
- return OK;
- }
-
- // Give up!
- ALOGE("Could not determine key map for device '%s' and no default key maps were found!",
- deviceIdenfifier.name.string());
- return NAME_NOT_FOUND;
-}
-
-bool KeyMap::probeKeyMap(const InputDeviceIdentifier& deviceIdentifier,
- const String8& keyMapName) {
- if (!haveKeyLayout()) {
- loadKeyLayout(deviceIdentifier, keyMapName);
- }
- if (!haveKeyCharacterMap()) {
- loadKeyCharacterMap(deviceIdentifier, keyMapName);
- }
- return isComplete();
-}
-
-status_t KeyMap::loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier,
- const String8& name) {
- String8 path(getPath(deviceIdentifier, name,
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_LAYOUT));
- if (path.isEmpty()) {
- return NAME_NOT_FOUND;
- }
-
- status_t status = KeyLayoutMap::load(path, &keyLayoutMap);
- if (status) {
- return status;
- }
-
- keyLayoutFile.setTo(path);
- return OK;
-}
-
-status_t KeyMap::loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
- const String8& name) {
- String8 path(getPath(deviceIdentifier, name,
- INPUT_DEVICE_CONFIGURATION_FILE_TYPE_KEY_CHARACTER_MAP));
- if (path.isEmpty()) {
- return NAME_NOT_FOUND;
- }
-
- status_t status = KeyCharacterMap::load(path,
- KeyCharacterMap::FORMAT_BASE, &keyCharacterMap);
- if (status) {
- return status;
- }
-
- keyCharacterMapFile.setTo(path);
- return OK;
-}
-
-String8 KeyMap::getPath(const InputDeviceIdentifier& deviceIdentifier,
- const String8& name, InputDeviceConfigurationFileType type) {
- return name.isEmpty()
- ? getInputDeviceConfigurationFilePathByDeviceIdentifier(deviceIdentifier, type)
- : getInputDeviceConfigurationFilePathByName(name, type);
-}
-
-
-// --- Global functions ---
-
-bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
- const PropertyMap* deviceConfiguration, const KeyMap* keyMap) {
- if (!keyMap->haveKeyCharacterMap()
- || keyMap->keyCharacterMap->getKeyboardType()
- == KeyCharacterMap::KEYBOARD_TYPE_SPECIAL_FUNCTION) {
- return false;
- }
-
- if (deviceConfiguration) {
- bool builtIn = false;
- if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
- && builtIn) {
- return true;
- }
- }
-
- return strstr(deviceIdentifier.name.string(), "-keypad");
-}
-
-static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
- while (list->literal) {
- if (strcmp(literal, list->literal) == 0) {
- return list->value;
- }
- list++;
- }
- return list->value;
-}
-
-static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
- while (list->literal) {
- if (list->value == value) {
- return list->literal;
- }
- list++;
- }
- return NULL;
-}
-
-int32_t getKeyCodeByLabel(const char* label) {
- return int32_t(lookupValueByLabel(label, KEYCODES));
-}
-
-uint32_t getKeyFlagByLabel(const char* label) {
- return uint32_t(lookupValueByLabel(label, FLAGS));
-}
-
-int32_t getAxisByLabel(const char* label) {
- return int32_t(lookupValueByLabel(label, AXES));
-}
-
-const char* getAxisLabel(int32_t axisId) {
- return lookupLabelByValue(axisId, AXES);
-}
-
-int32_t getLedByLabel(const char* label) {
- return int32_t(lookupValueByLabel(label, LEDS));
-}
-static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
- int32_t newMetaState;
- if (down) {
- newMetaState = oldMetaState | mask;
- } else {
- newMetaState = oldMetaState &
- ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON);
- }
-
- if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
- newMetaState |= AMETA_ALT_ON;
- }
-
- if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
- newMetaState |= AMETA_SHIFT_ON;
- }
-
- if (newMetaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
- newMetaState |= AMETA_CTRL_ON;
- }
-
- if (newMetaState & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
- newMetaState |= AMETA_META_ON;
- }
- return newMetaState;
-}
-
-static int32_t toggleLockedMetaState(int32_t mask, bool down, int32_t oldMetaState) {
- if (down) {
- return oldMetaState;
- } else {
- return oldMetaState ^ mask;
- }
-}
-
-int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
- switch (keyCode) {
- case AKEYCODE_ALT_LEFT:
- return setEphemeralMetaState(AMETA_ALT_LEFT_ON, down, oldMetaState);
- case AKEYCODE_ALT_RIGHT:
- return setEphemeralMetaState(AMETA_ALT_RIGHT_ON, down, oldMetaState);
- case AKEYCODE_SHIFT_LEFT:
- return setEphemeralMetaState(AMETA_SHIFT_LEFT_ON, down, oldMetaState);
- case AKEYCODE_SHIFT_RIGHT:
- return setEphemeralMetaState(AMETA_SHIFT_RIGHT_ON, down, oldMetaState);
- case AKEYCODE_SYM:
- return setEphemeralMetaState(AMETA_SYM_ON, down, oldMetaState);
- case AKEYCODE_FUNCTION:
- return setEphemeralMetaState(AMETA_FUNCTION_ON, down, oldMetaState);
- case AKEYCODE_CTRL_LEFT:
- return setEphemeralMetaState(AMETA_CTRL_LEFT_ON, down, oldMetaState);
- case AKEYCODE_CTRL_RIGHT:
- return setEphemeralMetaState(AMETA_CTRL_RIGHT_ON, down, oldMetaState);
- case AKEYCODE_META_LEFT:
- return setEphemeralMetaState(AMETA_META_LEFT_ON, down, oldMetaState);
- case AKEYCODE_META_RIGHT:
- return setEphemeralMetaState(AMETA_META_RIGHT_ON, down, oldMetaState);
- case AKEYCODE_CAPS_LOCK:
- return toggleLockedMetaState(AMETA_CAPS_LOCK_ON, down, oldMetaState);
- case AKEYCODE_NUM_LOCK:
- return toggleLockedMetaState(AMETA_NUM_LOCK_ON, down, oldMetaState);
- case AKEYCODE_SCROLL_LOCK:
- return toggleLockedMetaState(AMETA_SCROLL_LOCK_ON, down, oldMetaState);
- default:
- return oldMetaState;
- }
-}
-
-bool isMetaKey(int32_t keyCode) {
- switch (keyCode) {
- case AKEYCODE_ALT_LEFT:
- case AKEYCODE_ALT_RIGHT:
- case AKEYCODE_SHIFT_LEFT:
- case AKEYCODE_SHIFT_RIGHT:
- case AKEYCODE_SYM:
- case AKEYCODE_FUNCTION:
- case AKEYCODE_CTRL_LEFT:
- case AKEYCODE_CTRL_RIGHT:
- case AKEYCODE_META_LEFT:
- case AKEYCODE_META_RIGHT:
- case AKEYCODE_CAPS_LOCK:
- case AKEYCODE_NUM_LOCK:
- case AKEYCODE_SCROLL_LOCK:
- return true;
- default:
- return false;
- }
-}
-
-
-} // namespace android
diff --git a/widget/gonk/libui/Keyboard.h b/widget/gonk/libui/Keyboard.h
deleted file mode 100644
index 65921b25b..000000000
--- a/widget/gonk/libui/Keyboard.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_KEYBOARD_H
-#define _ANDROIDFW_KEYBOARD_H
-
-#include "Input.h"
-#include "InputDevice.h"
-#include <utils/Errors.h>
-#include <utils/String8.h>
-#include <utils/PropertyMap.h>
-
-namespace android {
-
-enum {
- /* Device id of the built in keyboard. */
- DEVICE_ID_BUILT_IN_KEYBOARD = 0,
-
- /* Device id of a generic virtual keyboard with a full layout that can be used
- * to synthesize key events. */
- DEVICE_ID_VIRTUAL_KEYBOARD = -1,
-};
-
-class KeyLayoutMap;
-class KeyCharacterMap;
-
-/**
- * Loads the key layout map and key character map for a keyboard device.
- */
-class KeyMap {
-public:
- String8 keyLayoutFile;
- sp<KeyLayoutMap> keyLayoutMap;
-
- String8 keyCharacterMapFile;
- sp<KeyCharacterMap> keyCharacterMap;
-
- KeyMap();
- ~KeyMap();
-
- status_t load(const InputDeviceIdentifier& deviceIdenfier,
- const PropertyMap* deviceConfiguration);
-
- inline bool haveKeyLayout() const {
- return !keyLayoutFile.isEmpty();
- }
-
- inline bool haveKeyCharacterMap() const {
- return !keyCharacterMapFile.isEmpty();
- }
-
- inline bool isComplete() const {
- return haveKeyLayout() && haveKeyCharacterMap();
- }
-
-private:
- bool probeKeyMap(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
- status_t loadKeyLayout(const InputDeviceIdentifier& deviceIdentifier, const String8& name);
- status_t loadKeyCharacterMap(const InputDeviceIdentifier& deviceIdentifier,
- const String8& name);
- String8 getPath(const InputDeviceIdentifier& deviceIdentifier,
- const String8& name, InputDeviceConfigurationFileType type);
-};
-
-/**
- * Returns true if the keyboard is eligible for use as a built-in keyboard.
- */
-extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,
- const PropertyMap* deviceConfiguration, const KeyMap* keyMap);
-
-/**
- * Gets a key code by its short form label, eg. "HOME".
- * Returns 0 if unknown.
- */
-extern int32_t getKeyCodeByLabel(const char* label);
-
-/**
- * Gets a key flag by its short form label, eg. "WAKE".
- * Returns 0 if unknown.
- */
-extern uint32_t getKeyFlagByLabel(const char* label);
-
-/**
- * Gets a axis by its short form label, eg. "X".
- * Returns -1 if unknown.
- */
-extern int32_t getAxisByLabel(const char* label);
-
-/**
- * Gets a axis label by its id.
- * Returns NULL if unknown.
- */
-extern const char* getAxisLabel(int32_t axisId);
-
-extern int32_t getLedByLabel(const char* label);
-
-/**
- * Updates a meta state field when a key is pressed or released.
- */
-extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
-
-/**
- * Returns true if a key is a meta key like ALT or CAPS_LOCK.
- */
-extern bool isMetaKey(int32_t keyCode);
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEYBOARD_H
diff --git a/widget/gonk/libui/KeycodeLabels.h b/widget/gonk/libui/KeycodeLabels.h
deleted file mode 100644
index 9f994597b..000000000
--- a/widget/gonk/libui/KeycodeLabels.h
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_KEYCODE_LABELS_H
-#define _ANDROIDFW_KEYCODE_LABELS_H
-
-#include "android_keycodes.h"
-
-struct KeycodeLabel {
- const char *literal;
- int value;
-};
-
-static const KeycodeLabel KEYCODES[] = {
- { "SOFT_LEFT", 1 },
- { "SOFT_RIGHT", 2 },
- { "HOME", 3 },
- { "BACK", 4 },
- { "CALL", 5 },
- { "ENDCALL", 6 },
- { "0", 7 },
- { "1", 8 },
- { "2", 9 },
- { "3", 10 },
- { "4", 11 },
- { "5", 12 },
- { "6", 13 },
- { "7", 14 },
- { "8", 15 },
- { "9", 16 },
- { "STAR", 17 },
- { "POUND", 18 },
- { "DPAD_UP", 19 },
- { "DPAD_DOWN", 20 },
- { "DPAD_LEFT", 21 },
- { "DPAD_RIGHT", 22 },
- { "DPAD_CENTER", 23 },
- { "VOLUME_UP", 24 },
- { "VOLUME_DOWN", 25 },
- { "POWER", 26 },
- { "CAMERA", 27 },
- { "CLEAR", 28 },
- { "A", 29 },
- { "B", 30 },
- { "C", 31 },
- { "D", 32 },
- { "E", 33 },
- { "F", 34 },
- { "G", 35 },
- { "H", 36 },
- { "I", 37 },
- { "J", 38 },
- { "K", 39 },
- { "L", 40 },
- { "M", 41 },
- { "N", 42 },
- { "O", 43 },
- { "P", 44 },
- { "Q", 45 },
- { "R", 46 },
- { "S", 47 },
- { "T", 48 },
- { "U", 49 },
- { "V", 50 },
- { "W", 51 },
- { "X", 52 },
- { "Y", 53 },
- { "Z", 54 },
- { "COMMA", 55 },
- { "PERIOD", 56 },
- { "ALT_LEFT", 57 },
- { "ALT_RIGHT", 58 },
- { "SHIFT_LEFT", 59 },
- { "SHIFT_RIGHT", 60 },
- { "TAB", 61 },
- { "SPACE", 62 },
- { "SYM", 63 },
- { "EXPLORER", 64 },
- { "ENVELOPE", 65 },
- { "ENTER", 66 },
- { "DEL", 67 },
- { "GRAVE", 68 },
- { "MINUS", 69 },
- { "EQUALS", 70 },
- { "LEFT_BRACKET", 71 },
- { "RIGHT_BRACKET", 72 },
- { "BACKSLASH", 73 },
- { "SEMICOLON", 74 },
- { "APOSTROPHE", 75 },
- { "SLASH", 76 },
- { "AT", 77 },
- { "NUM", 78 },
- { "HEADSETHOOK", 79 },
- { "FOCUS", 80 },
- { "PLUS", 81 },
- { "MENU", 82 },
- { "NOTIFICATION", 83 },
- { "SEARCH", 84 },
- { "MEDIA_PLAY_PAUSE", 85 },
- { "MEDIA_STOP", 86 },
- { "MEDIA_NEXT", 87 },
- { "MEDIA_PREVIOUS", 88 },
- { "MEDIA_REWIND", 89 },
- { "MEDIA_FAST_FORWARD", 90 },
- { "MUTE", 91 },
- { "PAGE_UP", 92 },
- { "PAGE_DOWN", 93 },
- { "PICTSYMBOLS", 94 },
- { "SWITCH_CHARSET", 95 },
- { "BUTTON_A", 96 },
- { "BUTTON_B", 97 },
- { "BUTTON_C", 98 },
- { "BUTTON_X", 99 },
- { "BUTTON_Y", 100 },
- { "BUTTON_Z", 101 },
- { "BUTTON_L1", 102 },
- { "BUTTON_R1", 103 },
- { "BUTTON_L2", 104 },
- { "BUTTON_R2", 105 },
- { "BUTTON_THUMBL", 106 },
- { "BUTTON_THUMBR", 107 },
- { "BUTTON_START", 108 },
- { "BUTTON_SELECT", 109 },
- { "BUTTON_MODE", 110 },
- { "ESCAPE", 111 },
- { "FORWARD_DEL", 112 },
- { "CTRL_LEFT", 113 },
- { "CTRL_RIGHT", 114 },
- { "CAPS_LOCK", 115 },
- { "SCROLL_LOCK", 116 },
- { "META_LEFT", 117 },
- { "META_RIGHT", 118 },
- { "FUNCTION", 119 },
- { "SYSRQ", 120 },
- { "BREAK", 121 },
- { "MOVE_HOME", 122 },
- { "MOVE_END", 123 },
- { "INSERT", 124 },
- { "FORWARD", 125 },
- { "MEDIA_PLAY", 126 },
- { "MEDIA_PAUSE", 127 },
- { "MEDIA_CLOSE", 128 },
- { "MEDIA_EJECT", 129 },
- { "MEDIA_RECORD", 130 },
- { "F1", 131 },
- { "F2", 132 },
- { "F3", 133 },
- { "F4", 134 },
- { "F5", 135 },
- { "F6", 136 },
- { "F7", 137 },
- { "F8", 138 },
- { "F9", 139 },
- { "F10", 140 },
- { "F11", 141 },
- { "F12", 142 },
- { "NUM_LOCK", 143 },
- { "NUMPAD_0", 144 },
- { "NUMPAD_1", 145 },
- { "NUMPAD_2", 146 },
- { "NUMPAD_3", 147 },
- { "NUMPAD_4", 148 },
- { "NUMPAD_5", 149 },
- { "NUMPAD_6", 150 },
- { "NUMPAD_7", 151 },
- { "NUMPAD_8", 152 },
- { "NUMPAD_9", 153 },
- { "NUMPAD_DIVIDE", 154 },
- { "NUMPAD_MULTIPLY", 155 },
- { "NUMPAD_SUBTRACT", 156 },
- { "NUMPAD_ADD", 157 },
- { "NUMPAD_DOT", 158 },
- { "NUMPAD_COMMA", 159 },
- { "NUMPAD_ENTER", 160 },
- { "NUMPAD_EQUALS", 161 },
- { "NUMPAD_LEFT_PAREN", 162 },
- { "NUMPAD_RIGHT_PAREN", 163 },
- { "VOLUME_MUTE", 164 },
- { "INFO", 165 },
- { "CHANNEL_UP", 166 },
- { "CHANNEL_DOWN", 167 },
- { "ZOOM_IN", 168 },
- { "ZOOM_OUT", 169 },
- { "TV", 170 },
- { "WINDOW", 171 },
- { "GUIDE", 172 },
- { "DVR", 173 },
- { "BOOKMARK", 174 },
- { "CAPTIONS", 175 },
- { "SETTINGS", 176 },
- { "TV_POWER", 177 },
- { "TV_INPUT", 178 },
- { "STB_POWER", 179 },
- { "STB_INPUT", 180 },
- { "AVR_POWER", 181 },
- { "AVR_INPUT", 182 },
- { "PROG_RED", 183 },
- { "PROG_GREEN", 184 },
- { "PROG_YELLOW", 185 },
- { "PROG_BLUE", 186 },
- { "APP_SWITCH", 187 },
- { "BUTTON_1", 188 },
- { "BUTTON_2", 189 },
- { "BUTTON_3", 190 },
- { "BUTTON_4", 191 },
- { "BUTTON_5", 192 },
- { "BUTTON_6", 193 },
- { "BUTTON_7", 194 },
- { "BUTTON_8", 195 },
- { "BUTTON_9", 196 },
- { "BUTTON_10", 197 },
- { "BUTTON_11", 198 },
- { "BUTTON_12", 199 },
- { "BUTTON_13", 200 },
- { "BUTTON_14", 201 },
- { "BUTTON_15", 202 },
- { "BUTTON_16", 203 },
- { "LANGUAGE_SWITCH", 204 },
- { "MANNER_MODE", 205 },
- { "3D_MODE", 206 },
- { "CONTACTS", 207 },
- { "CALENDAR", 208 },
- { "MUSIC", 209 },
- { "CALCULATOR", 210 },
- { "ZENKAKU_HANKAKU", 211 },
- { "EISU", 212 },
- { "MUHENKAN", 213 },
- { "HENKAN", 214 },
- { "KATAKANA_HIRAGANA", 215 },
- { "YEN", 216 },
- { "RO", 217 },
- { "KANA", 218 },
- { "ASSIST", 219 },
- { "BRIGHTNESS_DOWN", 220 },
- { "BRIGHTNESS_UP", 221 },
- { "MEDIA_AUDIO_TRACK", 222 },
- { "SLEEP", 223 },
- { "WAKEUP", 224 },
- { "PAIRING", 225 },
- { "MEDIA_TOP_MENU", 226 },
- { "11", 227 },
- { "12", 228 },
- { "LAST_CHANNEL", 229 },
- { "TV_DATA_SERVICE", 230 },
- { "VOICE_ASSIST", 231 },
- { "TV_RADIO_SERVICE", 232 },
- { "TV_TELETEXT", 233 },
- { "TV_NUMBER_ENTRY", 234 },
- { "TV_TERRESTRIAL_ANALOG", 235 },
- { "TV_TERRESTRIAL_DIGITAL", 236 },
- { "TV_SATELLITE", 237 },
- { "TV_SATELLITE_BS", 238 },
- { "TV_SATELLITE_CS", 239 },
- { "TV_SATELLITE_SERVICE", 240 },
- { "TV_NETWORK", 241 },
- { "TV_ANTENNA_CABLE", 242 },
- { "TV_INPUT_HDMI_1", 243 },
- { "TV_INPUT_HDMI_2", 244 },
- { "TV_INPUT_HDMI_3", 245 },
- { "TV_INPUT_HDMI_4", 246 },
- { "TV_INPUT_COMPOSITE_1", 247 },
- { "TV_INPUT_COMPOSITE_2", 248 },
- { "TV_INPUT_COMPONENT_1", 249 },
- { "TV_INPUT_COMPONENT_2", 250 },
- { "TV_INPUT_VGA_1", 251 },
- { "TV_AUDIO_DESCRIPTION", 252 },
- { "TV_AUDIO_DESCRIPTION_MIX_UP", 253 },
- { "TV_AUDIO_DESCRIPTION_MIX_DOWN", 254 },
- { "TV_ZOOM_MODE", 255 },
- { "TV_CONTENTS_MENU", 256 },
- { "TV_MEDIA_CONTEXT_MENU", 257 },
- { "TV_TIMER_PROGRAMMING", 258 },
- { "HELP", 259 },
-
- // NOTE: If you add a new keycode here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-
- { NULL, 0 }
-};
-
-// NOTE: If you edit these flags, also edit policy flags in Input.h.
-static const KeycodeLabel FLAGS[] = {
- { "WAKE", 0x00000001 },
- { "WAKE_DROPPED", 0x00000002 },
- { "SHIFT", 0x00000004 },
- { "CAPS_LOCK", 0x00000008 },
- { "ALT", 0x00000010 },
- { "ALT_GR", 0x00000020 },
- { "MENU", 0x00000040 },
- { "LAUNCHER", 0x00000080 },
- { "VIRTUAL", 0x00000100 },
- { "FUNCTION", 0x00000200 },
- { NULL, 0 }
-};
-
-static const KeycodeLabel AXES[] = {
- { "X", 0 },
- { "Y", 1 },
- { "PRESSURE", 2 },
- { "SIZE", 3 },
- { "TOUCH_MAJOR", 4 },
- { "TOUCH_MINOR", 5 },
- { "TOOL_MAJOR", 6 },
- { "TOOL_MINOR", 7 },
- { "ORIENTATION", 8 },
- { "VSCROLL", 9 },
- { "HSCROLL", 10 },
- { "Z", 11 },
- { "RX", 12 },
- { "RY", 13 },
- { "RZ", 14 },
- { "HAT_X", 15 },
- { "HAT_Y", 16 },
- { "LTRIGGER", 17 },
- { "RTRIGGER", 18 },
- { "THROTTLE", 19 },
- { "RUDDER", 20 },
- { "WHEEL", 21 },
- { "GAS", 22 },
- { "BRAKE", 23 },
- { "DISTANCE", 24 },
- { "TILT", 25 },
- { "GENERIC_1", 32 },
- { "GENERIC_2", 33 },
- { "GENERIC_3", 34 },
- { "GENERIC_4", 35 },
- { "GENERIC_5", 36 },
- { "GENERIC_6", 37 },
- { "GENERIC_7", 38 },
- { "GENERIC_8", 39 },
- { "GENERIC_9", 40 },
- { "GENERIC_10", 41 },
- { "GENERIC_11", 42 },
- { "GENERIC_12", 43 },
- { "GENERIC_13", 44 },
- { "GENERIC_14", 45 },
- { "GENERIC_15", 46 },
- { "GENERIC_16", 47 },
-
- // NOTE: If you add a new axis here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
-
- { NULL, -1 }
-};
-
-static const KeycodeLabel LEDS[] = {
- { "NUM_LOCK", 1},
- { "CAPS_LOCK", 2},
- { "SCROLL_LOCK", 3},
- { "COMPOSE", 4},
- { "KANA", 5},
- { "SLEEP", 6},
- { "SUSPEND", 7},
- { "MUTE", 8},
- { "MISC", 9},
- { "MAIL", 10},
- { "CHARGING", 11},
- { "CONTROLLER_1", 12},
- { "CONTROLLER_2", 13},
- { "CONTROLLER_3", 14},
- { "CONTROLLER_4", 15},
-
- // NOTE: If you add new LEDs here, you must also add them to Input.h
- { NULL, 0 }
-};
-
-#endif // _ANDROIDFW_KEYCODE_LABELS_H
diff --git a/widget/gonk/libui/PointerController.cpp b/widget/gonk/libui/PointerController.cpp
deleted file mode 100644
index ff80a0a9f..000000000
--- a/widget/gonk/libui/PointerController.cpp
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "PointerController"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages about pointer updates
-#define DEBUG_POINTER_UPDATES 0
-
-#include "PointerController.h"
-
-#include "cutils_log.h"
-
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-#include <SkXfermode.h>
-
-namespace android {
-
-// --- PointerController ---
-
-// Time to wait before starting the fade when the pointer is inactive.
-static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL = 15 * 1000 * 1000000LL; // 15 seconds
-static const nsecs_t INACTIVITY_TIMEOUT_DELAY_TIME_SHORT = 3 * 1000 * 1000000LL; // 3 seconds
-
-// Time to wait between animation frames.
-static const nsecs_t ANIMATION_FRAME_INTERVAL = 1000000000LL / 60;
-
-// Time to spend fading out the spot completely.
-static const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
-
-// Time to spend fading out the pointer completely.
-static const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
-
-
-// --- PointerController ---
-
-PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
- const sp<Looper>& looper, const sp<SpriteController>& spriteController) :
- mPolicy(policy), mLooper(looper), mSpriteController(spriteController) {
- mHandler = new WeakMessageHandler(this);
-
- AutoMutex _l(mLock);
-
- mLocked.animationPending = false;
-
- mLocked.displayWidth = -1;
- mLocked.displayHeight = -1;
- mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
-
- mLocked.presentation = PRESENTATION_POINTER;
- mLocked.presentationChanged = false;
-
- mLocked.inactivityTimeout = INACTIVITY_TIMEOUT_NORMAL;
-
- mLocked.pointerFadeDirection = 0;
- mLocked.pointerX = 0;
- mLocked.pointerY = 0;
- mLocked.pointerAlpha = 0.0f; // pointer is initially faded
- mLocked.pointerSprite = mSpriteController->createSprite();
- mLocked.pointerIconChanged = false;
-
- mLocked.buttonState = 0;
-
- loadResources();
-}
-
-PointerController::~PointerController() {
- mLooper->removeMessages(mHandler);
-
- AutoMutex _l(mLock);
-
- mLocked.pointerSprite.clear();
-
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- delete mLocked.spots.itemAt(i);
- }
- mLocked.spots.clear();
- mLocked.recycledSprites.clear();
-}
-
-bool PointerController::getBounds(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const {
- AutoMutex _l(mLock);
-
- return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
-}
-
-bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const {
- if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
- return false;
- }
-
- *outMinX = 0;
- *outMinY = 0;
- switch (mLocked.displayOrientation) {
- case DISPLAY_ORIENTATION_90:
- case DISPLAY_ORIENTATION_270:
- *outMaxX = mLocked.displayHeight - 1;
- *outMaxY = mLocked.displayWidth - 1;
- break;
- default:
- *outMaxX = mLocked.displayWidth - 1;
- *outMaxY = mLocked.displayHeight - 1;
- break;
- }
- return true;
-}
-
-void PointerController::move(float deltaX, float deltaY) {
-#if DEBUG_POINTER_UPDATES
- ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
-#endif
- if (deltaX == 0.0f && deltaY == 0.0f) {
- return;
- }
-
- AutoMutex _l(mLock);
-
- setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
-}
-
-void PointerController::setButtonState(int32_t buttonState) {
-#if DEBUG_POINTER_UPDATES
- ALOGD("Set button state 0x%08x", buttonState);
-#endif
- AutoMutex _l(mLock);
-
- if (mLocked.buttonState != buttonState) {
- mLocked.buttonState = buttonState;
- }
-}
-
-int32_t PointerController::getButtonState() const {
- AutoMutex _l(mLock);
-
- return mLocked.buttonState;
-}
-
-void PointerController::setPosition(float x, float y) {
-#if DEBUG_POINTER_UPDATES
- ALOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
-#endif
- AutoMutex _l(mLock);
-
- setPositionLocked(x, y);
-}
-
-void PointerController::setPositionLocked(float x, float y) {
- float minX, minY, maxX, maxY;
- if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
- if (x <= minX) {
- mLocked.pointerX = minX;
- } else if (x >= maxX) {
- mLocked.pointerX = maxX;
- } else {
- mLocked.pointerX = x;
- }
- if (y <= minY) {
- mLocked.pointerY = minY;
- } else if (y >= maxY) {
- mLocked.pointerY = maxY;
- } else {
- mLocked.pointerY = y;
- }
- updatePointerLocked();
- }
-}
-
-void PointerController::getPosition(float* outX, float* outY) const {
- AutoMutex _l(mLock);
-
- *outX = mLocked.pointerX;
- *outY = mLocked.pointerY;
-}
-
-void PointerController::fade(Transition transition) {
- AutoMutex _l(mLock);
-
- // Remove the inactivity timeout, since we are fading now.
- removeInactivityTimeoutLocked();
-
- // Start fading.
- if (transition == TRANSITION_IMMEDIATE) {
- mLocked.pointerFadeDirection = 0;
- mLocked.pointerAlpha = 0.0f;
- updatePointerLocked();
- } else {
- mLocked.pointerFadeDirection = -1;
- startAnimationLocked();
- }
-}
-
-void PointerController::unfade(Transition transition) {
- AutoMutex _l(mLock);
-
- // Always reset the inactivity timer.
- resetInactivityTimeoutLocked();
-
- // Start unfading.
- if (transition == TRANSITION_IMMEDIATE) {
- mLocked.pointerFadeDirection = 0;
- mLocked.pointerAlpha = 1.0f;
- updatePointerLocked();
- } else {
- mLocked.pointerFadeDirection = 1;
- startAnimationLocked();
- }
-}
-
-void PointerController::setPresentation(Presentation presentation) {
- AutoMutex _l(mLock);
-
- if (mLocked.presentation != presentation) {
- mLocked.presentation = presentation;
- mLocked.presentationChanged = true;
-
- if (presentation != PRESENTATION_SPOT) {
- fadeOutAndReleaseAllSpotsLocked();
- }
-
- updatePointerLocked();
- }
-}
-
-void PointerController::setSpots(const PointerCoords* spotCoords,
- const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
-#if DEBUG_POINTER_UPDATES
- ALOGD("setSpots: idBits=%08x", spotIdBits.value);
- for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- const PointerCoords& c = spotCoords[spotIdToIndex[id]];
- ALOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id,
- c.getAxisValue(AMOTION_EVENT_AXIS_X),
- c.getAxisValue(AMOTION_EVENT_AXIS_Y),
- c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
- }
-#endif
-
- AutoMutex _l(mLock);
-
- mSpriteController->openTransaction();
-
- // Add or move spots for fingers that are down.
- for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.clearFirstMarkedBit();
- const PointerCoords& c = spotCoords[spotIdToIndex[id]];
- const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
- ? mResources.spotTouch : mResources.spotHover;
- float x = c.getAxisValue(AMOTION_EVENT_AXIS_X);
- float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
-
- Spot* spot = getSpotLocked(id);
- if (!spot) {
- spot = createAndAddSpotLocked(id);
- }
-
- spot->updateSprite(&icon, x, y);
- }
-
- // Remove spots for fingers that went up.
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- Spot* spot = mLocked.spots.itemAt(i);
- if (spot->id != Spot::INVALID_ID
- && !spotIdBits.hasBit(spot->id)) {
- fadeOutAndReleaseSpotLocked(spot);
- }
- }
-
- mSpriteController->closeTransaction();
-}
-
-void PointerController::clearSpots() {
-#if DEBUG_POINTER_UPDATES
- ALOGD("clearSpots");
-#endif
-
- AutoMutex _l(mLock);
-
- fadeOutAndReleaseAllSpotsLocked();
-}
-
-void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
- AutoMutex _l(mLock);
-
- if (mLocked.inactivityTimeout != inactivityTimeout) {
- mLocked.inactivityTimeout = inactivityTimeout;
- resetInactivityTimeoutLocked();
- }
-}
-
-void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
- AutoMutex _l(mLock);
-
- // Adjust to use the display's unrotated coordinate frame.
- if (orientation == DISPLAY_ORIENTATION_90
- || orientation == DISPLAY_ORIENTATION_270) {
- int32_t temp = height;
- height = width;
- width = temp;
- }
-
- if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
- mLocked.displayWidth = width;
- mLocked.displayHeight = height;
-
- float minX, minY, maxX, maxY;
- if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
- mLocked.pointerX = (minX + maxX) * 0.5f;
- mLocked.pointerY = (minY + maxY) * 0.5f;
- } else {
- mLocked.pointerX = 0;
- mLocked.pointerY = 0;
- }
-
- fadeOutAndReleaseAllSpotsLocked();
- }
-
- if (mLocked.displayOrientation != orientation) {
- // Apply offsets to convert from the pixel top-left corner position to the pixel center.
- // This creates an invariant frame of reference that we can easily rotate when
- // taking into account that the pointer may be located at fractional pixel offsets.
- float x = mLocked.pointerX + 0.5f;
- float y = mLocked.pointerY + 0.5f;
- float temp;
-
- // Undo the previous rotation.
- switch (mLocked.displayOrientation) {
- case DISPLAY_ORIENTATION_90:
- temp = x;
- x = mLocked.displayWidth - y;
- y = temp;
- break;
- case DISPLAY_ORIENTATION_180:
- x = mLocked.displayWidth - x;
- y = mLocked.displayHeight - y;
- break;
- case DISPLAY_ORIENTATION_270:
- temp = x;
- x = y;
- y = mLocked.displayHeight - temp;
- break;
- }
-
- // Perform the new rotation.
- switch (orientation) {
- case DISPLAY_ORIENTATION_90:
- temp = x;
- x = y;
- y = mLocked.displayWidth - temp;
- break;
- case DISPLAY_ORIENTATION_180:
- x = mLocked.displayWidth - x;
- y = mLocked.displayHeight - y;
- break;
- case DISPLAY_ORIENTATION_270:
- temp = x;
- x = mLocked.displayHeight - y;
- y = temp;
- break;
- }
-
- // Apply offsets to convert from the pixel center to the pixel top-left corner position
- // and save the results.
- mLocked.pointerX = x - 0.5f;
- mLocked.pointerY = y - 0.5f;
- mLocked.displayOrientation = orientation;
- }
-
- updatePointerLocked();
-}
-
-void PointerController::setPointerIcon(const SpriteIcon& icon) {
- AutoMutex _l(mLock);
-
- mLocked.pointerIcon = icon.copy();
- mLocked.pointerIconChanged = true;
-
- updatePointerLocked();
-}
-
-void PointerController::handleMessage(const Message& message) {
- switch (message.what) {
- case MSG_ANIMATE:
- doAnimate();
- break;
- case MSG_INACTIVITY_TIMEOUT:
- doInactivityTimeout();
- break;
- }
-}
-
-void PointerController::doAnimate() {
- AutoMutex _l(mLock);
-
- bool keepAnimating = false;
- mLocked.animationPending = false;
- nsecs_t frameDelay = systemTime(SYSTEM_TIME_MONOTONIC) - mLocked.animationTime;
-
- // Animate pointer fade.
- if (mLocked.pointerFadeDirection < 0) {
- mLocked.pointerAlpha -= float(frameDelay) / POINTER_FADE_DURATION;
- if (mLocked.pointerAlpha <= 0.0f) {
- mLocked.pointerAlpha = 0.0f;
- mLocked.pointerFadeDirection = 0;
- } else {
- keepAnimating = true;
- }
- updatePointerLocked();
- } else if (mLocked.pointerFadeDirection > 0) {
- mLocked.pointerAlpha += float(frameDelay) / POINTER_FADE_DURATION;
- if (mLocked.pointerAlpha >= 1.0f) {
- mLocked.pointerAlpha = 1.0f;
- mLocked.pointerFadeDirection = 0;
- } else {
- keepAnimating = true;
- }
- updatePointerLocked();
- }
-
- // Animate spots that are fading out and being removed.
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- Spot* spot = mLocked.spots.itemAt(i);
- if (spot->id == Spot::INVALID_ID) {
- spot->alpha -= float(frameDelay) / SPOT_FADE_DURATION;
- if (spot->alpha <= 0) {
- mLocked.spots.removeAt(i--);
- releaseSpotLocked(spot);
- } else {
- spot->sprite->setAlpha(spot->alpha);
- keepAnimating = true;
- }
- }
- }
-
- if (keepAnimating) {
- startAnimationLocked();
- }
-}
-
-void PointerController::doInactivityTimeout() {
- fade(TRANSITION_GRADUAL);
-}
-
-void PointerController::startAnimationLocked() {
- if (!mLocked.animationPending) {
- mLocked.animationPending = true;
- mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
- mLooper->sendMessageDelayed(ANIMATION_FRAME_INTERVAL, mHandler, Message(MSG_ANIMATE));
- }
-}
-
-void PointerController::resetInactivityTimeoutLocked() {
- mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
-
- nsecs_t timeout = mLocked.inactivityTimeout == INACTIVITY_TIMEOUT_SHORT
- ? INACTIVITY_TIMEOUT_DELAY_TIME_SHORT : INACTIVITY_TIMEOUT_DELAY_TIME_NORMAL;
- mLooper->sendMessageDelayed(timeout, mHandler, MSG_INACTIVITY_TIMEOUT);
-}
-
-void PointerController::removeInactivityTimeoutLocked() {
- mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT);
-}
-
-void PointerController::updatePointerLocked() {
- mSpriteController->openTransaction();
-
- mLocked.pointerSprite->setLayer(Sprite::BASE_LAYER_POINTER);
- mLocked.pointerSprite->setPosition(mLocked.pointerX, mLocked.pointerY);
-
- if (mLocked.pointerAlpha > 0) {
- mLocked.pointerSprite->setAlpha(mLocked.pointerAlpha);
- mLocked.pointerSprite->setVisible(true);
- } else {
- mLocked.pointerSprite->setVisible(false);
- }
-
- if (mLocked.pointerIconChanged || mLocked.presentationChanged) {
- mLocked.pointerSprite->setIcon(mLocked.presentation == PRESENTATION_POINTER
- ? mLocked.pointerIcon : mResources.spotAnchor);
- mLocked.pointerIconChanged = false;
- mLocked.presentationChanged = false;
- }
-
- mSpriteController->closeTransaction();
-}
-
-PointerController::Spot* PointerController::getSpotLocked(uint32_t id) {
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- Spot* spot = mLocked.spots.itemAt(i);
- if (spot->id == id) {
- return spot;
- }
- }
- return NULL;
-}
-
-PointerController::Spot* PointerController::createAndAddSpotLocked(uint32_t id) {
- // Remove spots until we have fewer than MAX_SPOTS remaining.
- while (mLocked.spots.size() >= MAX_SPOTS) {
- Spot* spot = removeFirstFadingSpotLocked();
- if (!spot) {
- spot = mLocked.spots.itemAt(0);
- mLocked.spots.removeAt(0);
- }
- releaseSpotLocked(spot);
- }
-
- // Obtain a sprite from the recycled pool.
- sp<Sprite> sprite;
- if (! mLocked.recycledSprites.isEmpty()) {
- sprite = mLocked.recycledSprites.top();
- mLocked.recycledSprites.pop();
- } else {
- sprite = mSpriteController->createSprite();
- }
-
- // Return the new spot.
- Spot* spot = new Spot(id, sprite);
- mLocked.spots.push(spot);
- return spot;
-}
-
-PointerController::Spot* PointerController::removeFirstFadingSpotLocked() {
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- Spot* spot = mLocked.spots.itemAt(i);
- if (spot->id == Spot::INVALID_ID) {
- mLocked.spots.removeAt(i);
- return spot;
- }
- }
- return NULL;
-}
-
-void PointerController::releaseSpotLocked(Spot* spot) {
- spot->sprite->clearIcon();
-
- if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
- mLocked.recycledSprites.push(spot->sprite);
- }
-
- delete spot;
-}
-
-void PointerController::fadeOutAndReleaseSpotLocked(Spot* spot) {
- if (spot->id != Spot::INVALID_ID) {
- spot->id = Spot::INVALID_ID;
- startAnimationLocked();
- }
-}
-
-void PointerController::fadeOutAndReleaseAllSpotsLocked() {
- for (size_t i = 0; i < mLocked.spots.size(); i++) {
- Spot* spot = mLocked.spots.itemAt(i);
- fadeOutAndReleaseSpotLocked(spot);
- }
-}
-
-void PointerController::loadResources() {
- mPolicy->loadPointerResources(&mResources);
-}
-
-
-// --- PointerController::Spot ---
-
-void PointerController::Spot::updateSprite(const SpriteIcon* icon, float x, float y) {
- sprite->setLayer(Sprite::BASE_LAYER_SPOT + id);
- sprite->setAlpha(alpha);
- sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale));
- sprite->setPosition(x, y);
-
- this->x = x;
- this->y = y;
-
- if (icon != lastIcon) {
- lastIcon = icon;
- if (icon) {
- sprite->setIcon(*icon);
- sprite->setVisible(true);
- } else {
- sprite->setVisible(false);
- }
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/PointerController.h b/widget/gonk/libui/PointerController.h
deleted file mode 100644
index eb48d9a1f..000000000
--- a/widget/gonk/libui/PointerController.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_POINTER_CONTROLLER_H
-#define _UI_POINTER_CONTROLLER_H
-
-#include "SpriteController.h"
-
-#include <ui/DisplayInfo.h>
-#include "Input.h"
-#include <utils/BitSet.h>
-#include <utils/RefBase.h>
-#include <utils/Looper.h>
-#include <utils/String8.h>
-
-#include <SkBitmap.h>
-
-namespace android {
-
-/**
- * Interface for tracking a mouse / touch pad pointer and touch pad spots.
- *
- * The spots are sprites on screen that visually represent the positions of
- * fingers
- *
- * The pointer controller is responsible for providing synchronization and for tracking
- * display orientation changes if needed.
- */
-class PointerControllerInterface : public virtual RefBase {
-protected:
- PointerControllerInterface() { }
- virtual ~PointerControllerInterface() { }
-
-public:
- /* Gets the bounds of the region that the pointer can traverse.
- * Returns true if the bounds are available. */
- virtual bool getBounds(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const = 0;
-
- /* Move the pointer. */
- virtual void move(float deltaX, float deltaY) = 0;
-
- /* Sets a mask that indicates which buttons are pressed. */
- virtual void setButtonState(int32_t buttonState) = 0;
-
- /* Gets a mask that indicates which buttons are pressed. */
- virtual int32_t getButtonState() const = 0;
-
- /* Sets the absolute location of the pointer. */
- virtual void setPosition(float x, float y) = 0;
-
- /* Gets the absolute location of the pointer. */
- virtual void getPosition(float* outX, float* outY) const = 0;
-
- enum Transition {
- // Fade/unfade immediately.
- TRANSITION_IMMEDIATE,
- // Fade/unfade gradually.
- TRANSITION_GRADUAL,
- };
-
- /* Fades the pointer out now. */
- virtual void fade(Transition transition) = 0;
-
- /* Makes the pointer visible if it has faded out.
- * The pointer never unfades itself automatically. This method must be called
- * by the client whenever the pointer is moved or a button is pressed and it
- * wants to ensure that the pointer becomes visible again. */
- virtual void unfade(Transition transition) = 0;
-
- enum Presentation {
- // Show the mouse pointer.
- PRESENTATION_POINTER,
- // Show spots and a spot anchor in place of the mouse pointer.
- PRESENTATION_SPOT,
- };
-
- /* Sets the mode of the pointer controller. */
- virtual void setPresentation(Presentation presentation) = 0;
-
- /* Sets the spots for the current gesture.
- * The spots are not subject to the inactivity timeout like the pointer
- * itself it since they are expected to remain visible for so long as
- * the fingers are on the touch pad.
- *
- * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
- * For spotCoords, pressure != 0 indicates that the spot's location is being
- * pressed (not hovering).
- */
- virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
- BitSet32 spotIdBits) = 0;
-
- /* Removes all spots. */
- virtual void clearSpots() = 0;
-};
-
-
-/*
- * Pointer resources.
- */
-struct PointerResources {
- SpriteIcon spotHover;
- SpriteIcon spotTouch;
- SpriteIcon spotAnchor;
-};
-
-
-/*
- * Pointer controller policy interface.
- *
- * The pointer controller policy is used by the pointer controller to interact with
- * the Window Manager and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI. This interface is also mocked in the unit tests.
- */
-class PointerControllerPolicyInterface : public virtual RefBase {
-protected:
- PointerControllerPolicyInterface() { }
- virtual ~PointerControllerPolicyInterface() { }
-
-public:
- virtual void loadPointerResources(PointerResources* outResources) = 0;
-};
-
-
-/*
- * Tracks pointer movements and draws the pointer sprite to a surface.
- *
- * Handles pointer acceleration and animation.
- */
-class PointerController : public PointerControllerInterface, public MessageHandler {
-protected:
- virtual ~PointerController();
-
-public:
- enum InactivityTimeout {
- INACTIVITY_TIMEOUT_NORMAL = 0,
- INACTIVITY_TIMEOUT_SHORT = 1,
- };
-
- PointerController(const sp<PointerControllerPolicyInterface>& policy,
- const sp<Looper>& looper, const sp<SpriteController>& spriteController);
-
- virtual bool getBounds(float* outMinX, float* outMinY,
- float* outMaxX, float* outMaxY) const;
- virtual void move(float deltaX, float deltaY);
- virtual void setButtonState(int32_t buttonState);
- virtual int32_t getButtonState() const;
- virtual void setPosition(float x, float y);
- virtual void getPosition(float* outX, float* outY) const;
- virtual void fade(Transition transition);
- virtual void unfade(Transition transition);
-
- virtual void setPresentation(Presentation presentation);
- virtual void setSpots(const PointerCoords* spotCoords,
- const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
- virtual void clearSpots();
-
- void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
- void setPointerIcon(const SpriteIcon& icon);
- void setInactivityTimeout(InactivityTimeout inactivityTimeout);
-
-private:
- static const size_t MAX_RECYCLED_SPRITES = 12;
- static const size_t MAX_SPOTS = 12;
-
- enum {
- MSG_ANIMATE,
- MSG_INACTIVITY_TIMEOUT,
- };
-
- struct Spot {
- static const uint32_t INVALID_ID = 0xffffffff;
-
- uint32_t id;
- sp<Sprite> sprite;
- float alpha;
- float scale;
- float x, y;
-
- inline Spot(uint32_t id, const sp<Sprite>& sprite)
- : id(id), sprite(sprite), alpha(1.0f), scale(1.0f),
- x(0.0f), y(0.0f), lastIcon(NULL) { }
-
- void updateSprite(const SpriteIcon* icon, float x, float y);
-
- private:
- const SpriteIcon* lastIcon;
- };
-
- mutable Mutex mLock;
-
- sp<PointerControllerPolicyInterface> mPolicy;
- sp<Looper> mLooper;
- sp<SpriteController> mSpriteController;
- sp<WeakMessageHandler> mHandler;
-
- PointerResources mResources;
-
- struct Locked {
- bool animationPending;
- nsecs_t animationTime;
-
- int32_t displayWidth;
- int32_t displayHeight;
- int32_t displayOrientation;
-
- InactivityTimeout inactivityTimeout;
-
- Presentation presentation;
- bool presentationChanged;
-
- int32_t pointerFadeDirection;
- float pointerX;
- float pointerY;
- float pointerAlpha;
- sp<Sprite> pointerSprite;
- SpriteIcon pointerIcon;
- bool pointerIconChanged;
-
- int32_t buttonState;
-
- Vector<Spot*> spots;
- Vector<sp<Sprite> > recycledSprites;
- } mLocked;
-
- bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
- void setPositionLocked(float x, float y);
-
- void handleMessage(const Message& message);
- void doAnimate();
- void doInactivityTimeout();
-
- void startAnimationLocked();
-
- void resetInactivityTimeoutLocked();
- void removeInactivityTimeoutLocked();
- void updatePointerLocked();
-
- Spot* getSpotLocked(uint32_t id);
- Spot* createAndAddSpotLocked(uint32_t id);
- Spot* removeFirstFadingSpotLocked();
- void releaseSpotLocked(Spot* spot);
- void fadeOutAndReleaseSpotLocked(Spot* spot);
- void fadeOutAndReleaseAllSpotsLocked();
-
- void loadResources();
-};
-
-} // namespace android
-
-#endif // _UI_POINTER_CONTROLLER_H
diff --git a/widget/gonk/libui/PowerManager.h b/widget/gonk/libui/PowerManager.h
deleted file mode 100644
index ba98db07c..000000000
--- a/widget/gonk/libui/PowerManager.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_POWER_MANAGER_H
-#define _ANDROIDFW_POWER_MANAGER_H
-
-
-namespace android {
-
-enum {
- USER_ACTIVITY_EVENT_OTHER = 0,
- USER_ACTIVITY_EVENT_BUTTON = 1,
- USER_ACTIVITY_EVENT_TOUCH = 2,
-
- USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code.
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_POWER_MANAGER_H
diff --git a/widget/gonk/libui/SpriteController.cpp b/widget/gonk/libui/SpriteController.cpp
deleted file mode 100644
index 8677476b1..000000000
--- a/widget/gonk/libui/SpriteController.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Sprites"
-
-//#define LOG_NDEBUG 0
-
-#include "SpriteController.h"
-
-#include "cutils_log.h"
-#include <utils/String8.h>
-#ifdef HAVE_ANDROID_OS
-#include <gui/Surface.h>
-#endif
-
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-#include <SkXfermode.h>
-#include <android/native_window.h>
-
-namespace android {
-
-// --- SpriteController ---
-
-SpriteController::SpriteController(const sp<Looper>& looper, int32_t overlayLayer) :
- mLooper(looper), mOverlayLayer(overlayLayer) {
-#ifdef HAVE_ANDROID_OS
- mHandler = new WeakMessageHandler(this);
-#endif
-
- mLocked.transactionNestingCount = 0;
- mLocked.deferredSpriteUpdate = false;
-}
-
-SpriteController::~SpriteController() {
-#ifdef HAVE_ANDROID_OS
- mLooper->removeMessages(mHandler);
-
- if (mSurfaceComposerClient != NULL) {
- mSurfaceComposerClient->dispose();
- mSurfaceComposerClient.clear();
- }
-#endif
-}
-
-sp<Sprite> SpriteController::createSprite() {
- return new SpriteImpl(this);
-}
-
-void SpriteController::openTransaction() {
- AutoMutex _l(mLock);
-
- mLocked.transactionNestingCount += 1;
-}
-
-void SpriteController::closeTransaction() {
- AutoMutex _l(mLock);
-
- LOG_ALWAYS_FATAL_IF(mLocked.transactionNestingCount == 0,
- "Sprite closeTransaction() called but there is no open sprite transaction");
-
- mLocked.transactionNestingCount -= 1;
- if (mLocked.transactionNestingCount == 0 && mLocked.deferredSpriteUpdate) {
- mLocked.deferredSpriteUpdate = false;
-#ifdef HAVE_ANDROID_OS
- mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES));
-#endif
- }
-}
-
-void SpriteController::invalidateSpriteLocked(const sp<SpriteImpl>& sprite) {
- bool wasEmpty = mLocked.invalidatedSprites.isEmpty();
- mLocked.invalidatedSprites.push(sprite);
- if (wasEmpty) {
- if (mLocked.transactionNestingCount != 0) {
- mLocked.deferredSpriteUpdate = true;
- } else {
-#ifdef HAVE_ANDROID_OS
- mLooper->sendMessage(mHandler, Message(MSG_UPDATE_SPRITES));
-#endif
- }
- }
-}
-
-#ifdef HAVE_ANDROID_OS
-void SpriteController::disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl) {
- bool wasEmpty = mLocked.disposedSurfaces.isEmpty();
- mLocked.disposedSurfaces.push(surfaceControl);
- if (wasEmpty) {
- mLooper->sendMessage(mHandler, Message(MSG_DISPOSE_SURFACES));
- }
-}
-
-void SpriteController::handleMessage(const Message& message) {
- switch (message.what) {
- case MSG_UPDATE_SPRITES:
- doUpdateSprites();
- break;
- case MSG_DISPOSE_SURFACES:
- doDisposeSurfaces();
- break;
- }
-}
-#endif
-
-void SpriteController::doUpdateSprites() {
- // Collect information about sprite updates.
- // Each sprite update record includes a reference to its associated sprite so we can
- // be certain the sprites will not be deleted while this function runs. Sprites
- // may invalidate themselves again during this time but we will handle those changes
- // in the next iteration.
- Vector<SpriteUpdate> updates;
- size_t numSprites;
- { // acquire lock
- AutoMutex _l(mLock);
-
- numSprites = mLocked.invalidatedSprites.size();
- for (size_t i = 0; i < numSprites; i++) {
- const sp<SpriteImpl>& sprite = mLocked.invalidatedSprites.itemAt(i);
-
- updates.push(SpriteUpdate(sprite, sprite->getStateLocked()));
- sprite->resetDirtyLocked();
- }
- mLocked.invalidatedSprites.clear();
- } // release lock
-
- // Create missing surfaces.
- bool surfaceChanged = false;
-#ifdef HAVE_ANDROID_OS
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- if (update.state.surfaceControl == NULL && update.state.wantSurfaceVisible()) {
- update.state.surfaceWidth = update.state.icon.bitmap.width();
- update.state.surfaceHeight = update.state.icon.bitmap.height();
- update.state.surfaceDrawn = false;
- update.state.surfaceVisible = false;
- update.state.surfaceControl = obtainSurface(
- update.state.surfaceWidth, update.state.surfaceHeight);
- if (update.state.surfaceControl != NULL) {
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
-#endif
-
- // Resize sprites if needed, inside a global transaction.
-#ifdef HAVE_ANDROID_OS
- bool haveGlobalTransaction = false;
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- if (update.state.surfaceControl != NULL && update.state.wantSurfaceVisible()) {
- int32_t desiredWidth = update.state.icon.bitmap.width();
- int32_t desiredHeight = update.state.icon.bitmap.height();
- if (update.state.surfaceWidth < desiredWidth
- || update.state.surfaceHeight < desiredHeight) {
- if (!haveGlobalTransaction) {
- SurfaceComposerClient::openGlobalTransaction();
- haveGlobalTransaction = true;
- }
-
- status_t status = update.state.surfaceControl->setSize(desiredWidth, desiredHeight);
- if (status) {
- ALOGE("Error %d resizing sprite surface from %dx%d to %dx%d",
- status, update.state.surfaceWidth, update.state.surfaceHeight,
- desiredWidth, desiredHeight);
- } else {
- update.state.surfaceWidth = desiredWidth;
- update.state.surfaceHeight = desiredHeight;
- update.state.surfaceDrawn = false;
- update.surfaceChanged = surfaceChanged = true;
-
- if (update.state.surfaceVisible) {
- status = update.state.surfaceControl->hide();
- if (status) {
- ALOGE("Error %d hiding sprite surface after resize.", status);
- } else {
- update.state.surfaceVisible = false;
- }
- }
- }
- }
- }
- }
-#endif
-#ifdef HAVE_ANDROID_OS
- if (haveGlobalTransaction) {
- SurfaceComposerClient::closeGlobalTransaction();
- }
-#endif
-
- // Redraw sprites if needed.
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
-
- if ((update.state.dirty & DIRTY_BITMAP) && update.state.surfaceDrawn) {
- update.state.surfaceDrawn = false;
- update.surfaceChanged = surfaceChanged = true;
- }
-
-#ifdef HAVE_ANDROID_OS
- if (update.state.surfaceControl != NULL && !update.state.surfaceDrawn
- && update.state.wantSurfaceVisible()) {
- sp<Surface> surface = update.state.surfaceControl->getSurface();
- ANativeWindow_Buffer outBuffer;
- status_t status = surface->lock(&outBuffer, NULL);
- if (status) {
- ALOGE("Error %d locking sprite surface before drawing.", status);
- } else {
- SkBitmap surfaceBitmap;
- ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
- surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config,
- outBuffer.width, outBuffer.height, bpr);
- surfaceBitmap.setPixels(outBuffer.bits);
-
- SkCanvas surfaceCanvas(surfaceBitmap);
-
- SkPaint paint;
- paint.setXfermodeMode(SkXfermode::kSrc_Mode);
- surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
-
- if (outBuffer.width > uint32_t(update.state.icon.bitmap.width())) {
- paint.setColor(0); // transparent fill color
- surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
- outBuffer.width, update.state.icon.bitmap.height(), paint);
- }
- if (outBuffer.height > uint32_t(update.state.icon.bitmap.height())) {
- paint.setColor(0); // transparent fill color
- surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
- outBuffer.width, outBuffer.height, paint);
- }
-
- status = surface->unlockAndPost();
- if (status) {
- ALOGE("Error %d unlocking and posting sprite surface after drawing.", status);
- } else {
- update.state.surfaceDrawn = true;
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
-#endif
- }
-
-#ifdef HAVE_ANDROID_OS
- // Set sprite surface properties and make them visible.
- bool haveTransaction = false;
- for (size_t i = 0; i < numSprites; i++) {
- SpriteUpdate& update = updates.editItemAt(i);
- bool wantSurfaceVisibleAndDrawn = update.state.wantSurfaceVisible()
- && update.state.surfaceDrawn;
- bool becomingVisible = wantSurfaceVisibleAndDrawn && !update.state.surfaceVisible;
- bool becomingHidden = !wantSurfaceVisibleAndDrawn && update.state.surfaceVisible;
- if (update.state.surfaceControl != NULL && (becomingVisible || becomingHidden
- || (wantSurfaceVisibleAndDrawn && (update.state.dirty & (DIRTY_ALPHA
- | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER
- | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) {
- status_t status;
- if (!haveTransaction) {
- SurfaceComposerClient::openGlobalTransaction();
- haveTransaction = true;
- }
-
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & DIRTY_ALPHA))) {
- status = update.state.surfaceControl->setAlpha(update.state.alpha);
- if (status) {
- ALOGE("Error %d setting sprite surface alpha.", status);
- }
- }
-
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & (DIRTY_POSITION
- | DIRTY_HOTSPOT)))) {
- status = update.state.surfaceControl->setPosition(
- update.state.positionX - update.state.icon.hotSpotX,
- update.state.positionY - update.state.icon.hotSpotY);
- if (status) {
- ALOGE("Error %d setting sprite surface position.", status);
- }
- }
-
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible
- || (update.state.dirty & DIRTY_TRANSFORMATION_MATRIX))) {
- status = update.state.surfaceControl->setMatrix(
- update.state.transformationMatrix.dsdx,
- update.state.transformationMatrix.dtdx,
- update.state.transformationMatrix.dsdy,
- update.state.transformationMatrix.dtdy);
- if (status) {
- ALOGE("Error %d setting sprite surface transformation matrix.", status);
- }
- }
-
- int32_t surfaceLayer = mOverlayLayer + update.state.layer;
- if (wantSurfaceVisibleAndDrawn
- && (becomingVisible || (update.state.dirty & DIRTY_LAYER))) {
- status = update.state.surfaceControl->setLayer(surfaceLayer);
- if (status) {
- ALOGE("Error %d setting sprite surface layer.", status);
- }
- }
-
- if (becomingVisible) {
- status = update.state.surfaceControl->show();
- if (status) {
- ALOGE("Error %d showing sprite surface.", status);
- } else {
- update.state.surfaceVisible = true;
- update.surfaceChanged = surfaceChanged = true;
- }
- } else if (becomingHidden) {
- status = update.state.surfaceControl->hide();
- if (status) {
- ALOGE("Error %d hiding sprite surface.", status);
- } else {
- update.state.surfaceVisible = false;
- update.surfaceChanged = surfaceChanged = true;
- }
- }
- }
- }
-#endif
-
-#ifdef HAVE_ANDROID_OS
- if (haveTransaction) {
- SurfaceComposerClient::closeGlobalTransaction();
- }
-#endif
-
-#ifdef HAVE_ANDROID_OS
- // If any surfaces were changed, write back the new surface properties to the sprites.
- if (surfaceChanged) { // acquire lock
- AutoMutex _l(mLock);
-
- for (size_t i = 0; i < numSprites; i++) {
- const SpriteUpdate& update = updates.itemAt(i);
-
- if (update.surfaceChanged) {
- update.sprite->setSurfaceLocked(update.state.surfaceControl,
- update.state.surfaceWidth, update.state.surfaceHeight,
- update.state.surfaceDrawn, update.state.surfaceVisible);
- }
- }
- } // release lock
-#endif
-
- // Clear the sprite update vector outside the lock. It is very important that
- // we do not clear sprite references inside the lock since we could be releasing
- // the last remaining reference to the sprite here which would result in the
- // sprite being deleted and the lock being reacquired by the sprite destructor
- // while already held.
- updates.clear();
-}
-
-void SpriteController::doDisposeSurfaces() {
-#ifdef HAVE_ANDROID_OS
- // Collect disposed surfaces.
- Vector<sp<SurfaceControl> > disposedSurfaces;
- { // acquire lock
- AutoMutex _l(mLock);
-
- disposedSurfaces = mLocked.disposedSurfaces;
- mLocked.disposedSurfaces.clear();
- } // release lock
-
- // Release the last reference to each surface outside of the lock.
- // We don't want the surfaces to be deleted while we are holding our lock.
- disposedSurfaces.clear();
-#endif
-}
-
-void SpriteController::ensureSurfaceComposerClient() {
-#ifdef HAVE_ANDROID_OS
- if (mSurfaceComposerClient == NULL) {
- mSurfaceComposerClient = new SurfaceComposerClient();
- }
-#endif
-}
-
-#ifdef HAVE_ANDROID_OS
-sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height) {
- ensureSurfaceComposerClient();
-
- sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface(
- String8("Sprite"), width, height, PIXEL_FORMAT_RGBA_8888,
- ISurfaceComposerClient::eHidden);
- if (surfaceControl == NULL || !surfaceControl->isValid()) {
- ALOGE("Error creating sprite surface.");
- return NULL;
- }
- return surfaceControl;
-}
-#endif
-
-
-// --- SpriteController::SpriteImpl ---
-
-SpriteController::SpriteImpl::SpriteImpl(const sp<SpriteController> controller) :
- mController(controller) {
-}
-
-SpriteController::SpriteImpl::~SpriteImpl() {
- AutoMutex _m(mController->mLock);
-
-#ifdef HAVE_ANDROID_OS
- // Let the controller take care of deleting the last reference to sprite
- // surfaces so that we do not block the caller on an IPC here.
- if (mLocked.state.surfaceControl != NULL) {
- mController->disposeSurfaceLocked(mLocked.state.surfaceControl);
- mLocked.state.surfaceControl.clear();
- }
-#endif
-}
-
-void SpriteController::SpriteImpl::setIcon(const SpriteIcon& icon) {
- AutoMutex _l(mController->mLock);
-
-#ifdef HAVE_ANDROID_OS
- uint32_t dirty;
- if (icon.isValid()) {
- icon.bitmap.copyTo(&mLocked.state.icon.bitmap, SkBitmap::kARGB_8888_Config);
-
- if (!mLocked.state.icon.isValid()
- || mLocked.state.icon.hotSpotX != icon.hotSpotX
- || mLocked.state.icon.hotSpotY != icon.hotSpotY) {
- mLocked.state.icon.hotSpotX = icon.hotSpotX;
- mLocked.state.icon.hotSpotY = icon.hotSpotY;
- dirty = DIRTY_BITMAP | DIRTY_HOTSPOT;
- } else {
- dirty = DIRTY_BITMAP;
- }
- } else if (mLocked.state.icon.isValid()) {
- mLocked.state.icon.bitmap.reset();
- dirty = DIRTY_BITMAP | DIRTY_HOTSPOT;
- } else {
- return; // setting to invalid icon and already invalid so nothing to do
- }
-
- invalidateLocked(dirty);
-#endif
-}
-
-void SpriteController::SpriteImpl::setVisible(bool visible) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.visible != visible) {
- mLocked.state.visible = visible;
- invalidateLocked(DIRTY_VISIBILITY);
- }
-}
-
-void SpriteController::SpriteImpl::setPosition(float x, float y) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.positionX != x || mLocked.state.positionY != y) {
- mLocked.state.positionX = x;
- mLocked.state.positionY = y;
- invalidateLocked(DIRTY_POSITION);
- }
-}
-
-void SpriteController::SpriteImpl::setLayer(int32_t layer) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.layer != layer) {
- mLocked.state.layer = layer;
- invalidateLocked(DIRTY_LAYER);
- }
-}
-
-void SpriteController::SpriteImpl::setAlpha(float alpha) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.alpha != alpha) {
- mLocked.state.alpha = alpha;
- invalidateLocked(DIRTY_ALPHA);
- }
-}
-
-void SpriteController::SpriteImpl::setTransformationMatrix(
- const SpriteTransformationMatrix& matrix) {
- AutoMutex _l(mController->mLock);
-
- if (mLocked.state.transformationMatrix != matrix) {
- mLocked.state.transformationMatrix = matrix;
- invalidateLocked(DIRTY_TRANSFORMATION_MATRIX);
- }
-}
-
-void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) {
- bool wasDirty = mLocked.state.dirty;
- mLocked.state.dirty |= dirty;
-
- if (!wasDirty) {
- mController->invalidateSpriteLocked(this);
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/SpriteController.h b/widget/gonk/libui/SpriteController.h
deleted file mode 100644
index 4926095ec..000000000
--- a/widget/gonk/libui/SpriteController.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_SPRITES_H
-#define _UI_SPRITES_H
-
-#include <utils/RefBase.h>
-#include <utils/Looper.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <gui/SurfaceComposerClient.h>
-#endif
-
-#include <SkBitmap.h>
-
-namespace android {
-
-/*
- * Transformation matrix for a sprite.
- */
-struct SpriteTransformationMatrix {
- inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
- inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
- dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
-
- float dsdx;
- float dtdx;
- float dsdy;
- float dtdy;
-
- inline bool operator== (const SpriteTransformationMatrix& other) {
- return dsdx == other.dsdx
- && dtdx == other.dtdx
- && dsdy == other.dsdy
- && dtdy == other.dtdy;
- }
-
- inline bool operator!= (const SpriteTransformationMatrix& other) {
- return !(*this == other);
- }
-};
-
-/*
- * Icon that a sprite displays, including its hotspot.
- */
-struct SpriteIcon {
- inline SpriteIcon() : hotSpotX(0), hotSpotY(0) { }
-#ifdef HAVE_ANDROID_OS
- inline SpriteIcon(const SkBitmap& bitmap, float hotSpotX, float hotSpotY) :
- bitmap(bitmap), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
-
- SkBitmap bitmap;
-#endif
- float hotSpotX;
- float hotSpotY;
-
- inline SpriteIcon copy() const {
-#ifdef HAVE_ANDROID_OS
- SkBitmap bitmapCopy;
- bitmap.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config);
- return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
-#else
- return SpriteIcon();
-#endif
- }
-
- inline void reset() {
-#ifdef HAVE_ANDROID_OS
- bitmap.reset();
- hotSpotX = 0;
- hotSpotY = 0;
-#endif
- }
-
- inline bool isValid() const {
-#ifdef HAVE_ANDROID_OS
- return !bitmap.isNull() && !bitmap.empty();
-#else
- return false;
-#endif
- }
-};
-
-/*
- * A sprite is a simple graphical object that is displayed on-screen above other layers.
- * The basic sprite class is an interface.
- * The implementation is provided by the sprite controller.
- */
-class Sprite : public RefBase {
-protected:
- Sprite() { }
- virtual ~Sprite() { }
-
-public:
- enum {
- // The base layer for pointer sprites.
- BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
-
- // The base layer for spot sprites.
- BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
- };
-
- /* Sets the bitmap that is drawn by the sprite.
- * The sprite retains a copy of the bitmap for subsequent rendering. */
- virtual void setIcon(const SpriteIcon& icon) = 0;
-
- inline void clearIcon() {
- setIcon(SpriteIcon());
- }
-
- /* Sets whether the sprite is visible. */
- virtual void setVisible(bool visible) = 0;
-
- /* Sets the sprite position on screen, relative to the sprite's hot spot. */
- virtual void setPosition(float x, float y) = 0;
-
- /* Sets the layer of the sprite, relative to the system sprite overlay layer.
- * Layer 0 is the overlay layer, > 0 appear above this layer. */
- virtual void setLayer(int32_t layer) = 0;
-
- /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
- virtual void setAlpha(float alpha) = 0;
-
- /* Sets the sprite transformation matrix. */
- virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
-};
-
-/*
- * Displays sprites on the screen.
- *
- * This interface is used by PointerController and SpotController to draw pointers or
- * spot representations of fingers. It is not intended for general purpose use
- * by other components.
- *
- * All sprite position updates and rendering is performed asynchronously.
- *
- * Clients are responsible for animating sprites by periodically updating their properties.
- */
-class SpriteController : public MessageHandler {
-protected:
- virtual ~SpriteController();
-
-public:
- SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
-
- /* Creates a new sprite, initially invisible. */
- sp<Sprite> createSprite();
-
- /* Opens or closes a transaction to perform a batch of sprite updates as part of
- * a single operation such as setPosition and setAlpha. It is not necessary to
- * open a transaction when updating a single property.
- * Calls to openTransaction() nest and must be matched by an equal number
- * of calls to closeTransaction(). */
- void openTransaction();
- void closeTransaction();
-
-private:
- enum {
- MSG_UPDATE_SPRITES,
- MSG_DISPOSE_SURFACES,
- };
-
- enum {
- DIRTY_BITMAP = 1 << 0,
- DIRTY_ALPHA = 1 << 1,
- DIRTY_POSITION = 1 << 2,
- DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
- DIRTY_LAYER = 1 << 4,
- DIRTY_VISIBILITY = 1 << 5,
- DIRTY_HOTSPOT = 1 << 6,
- };
-
- /* Describes the state of a sprite.
- * This structure is designed so that it can be copied during updates so that
- * surfaces can be resized and redrawn without blocking the client by holding a lock
- * on the sprites for a long time.
- * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
- struct SpriteState {
- inline SpriteState() :
- dirty(0), visible(false),
- positionX(0), positionY(0), layer(0), alpha(1.0f),
- surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
- }
-
- uint32_t dirty;
-
- SpriteIcon icon;
- bool visible;
- float positionX;
- float positionY;
- int32_t layer;
- float alpha;
- SpriteTransformationMatrix transformationMatrix;
-
-#ifdef HAVE_ANDROID_OS
- sp<SurfaceControl> surfaceControl;
-#endif
- int32_t surfaceWidth;
- int32_t surfaceHeight;
- bool surfaceDrawn;
- bool surfaceVisible;
-
- inline bool wantSurfaceVisible() const {
- return visible && alpha > 0.0f && icon.isValid();
- }
- };
-
- /* Client interface for a sprite.
- * Requests acquire a lock on the controller, update local state and request the
- * controller to invalidate the sprite.
- * The real heavy lifting of creating, resizing and redrawing surfaces happens
- * asynchronously with no locks held except in short critical section to copy
- * the sprite state before the work and update the sprite surface control afterwards.
- */
- class SpriteImpl : public Sprite {
- protected:
- virtual ~SpriteImpl();
-
- public:
- SpriteImpl(const sp<SpriteController> controller);
-
- virtual void setIcon(const SpriteIcon& icon);
- virtual void setVisible(bool visible);
- virtual void setPosition(float x, float y);
- virtual void setLayer(int32_t layer);
- virtual void setAlpha(float alpha);
- virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
-
- inline const SpriteState& getStateLocked() const {
- return mLocked.state;
- }
-
- inline void resetDirtyLocked() {
- mLocked.state.dirty = 0;
- }
-
-#ifdef HAVE_ANDROID_OS
- inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
- int32_t width, int32_t height, bool drawn, bool visible) {
- mLocked.state.surfaceControl = surfaceControl;
- mLocked.state.surfaceWidth = width;
- mLocked.state.surfaceHeight = height;
- mLocked.state.surfaceDrawn = drawn;
- mLocked.state.surfaceVisible = visible;
- }
-#endif
-
- private:
- sp<SpriteController> mController;
-
- struct Locked {
- SpriteState state;
- } mLocked; // guarded by mController->mLock
-
- void invalidateLocked(uint32_t dirty);
- };
-
- /* Stores temporary information collected during the sprite update cycle. */
- struct SpriteUpdate {
- inline SpriteUpdate() : surfaceChanged(false) { }
- inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
- sprite(sprite), state(state), surfaceChanged(false) {
- }
-
- sp<SpriteImpl> sprite;
- SpriteState state;
- bool surfaceChanged;
- };
-
- mutable Mutex mLock;
-
- sp<Looper> mLooper;
- const int32_t mOverlayLayer;
-#ifdef HAVE_ANDROID_OS
- sp<WeakMessageHandler> mHandler;
-
- sp<SurfaceComposerClient> mSurfaceComposerClient;
-#endif
-
- struct Locked {
- Vector<sp<SpriteImpl> > invalidatedSprites;
-#ifdef HAVE_ANDROID_OS
- Vector<sp<SurfaceControl> > disposedSurfaces;
-#endif
- uint32_t transactionNestingCount;
- bool deferredSpriteUpdate;
- } mLocked; // guarded by mLock
-
- void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
-#ifdef HAVE_ANDROID_OS
- void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
-
- void handleMessage(const Message& message);
-#endif
- void doUpdateSprites();
- void doDisposeSurfaces();
-
- void ensureSurfaceComposerClient();
-#ifdef HAVE_ANDROID_OS
- sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
-#endif
-};
-
-} // namespace android
-
-#endif // _UI_SPRITES_H
diff --git a/widget/gonk/libui/Tokenizer.cpp b/widget/gonk/libui/Tokenizer.cpp
deleted file mode 100644
index 2f585cb4e..000000000
--- a/widget/gonk/libui/Tokenizer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Tokenizer"
-#include "cutils_log.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "Tokenizer.h"
-
-// Enables debug output for the tokenizer.
-#define DEBUG_TOKENIZER 0
-
-
-namespace android {
-
-static inline bool isDelimiter(char ch, const char* delimiters) {
- return strchr(delimiters, ch) != NULL;
-}
-
-Tokenizer::Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,
- bool ownBuffer, size_t length) :
- mFilename(filename), mFileMap(fileMap),
- mBuffer(buffer), mOwnBuffer(ownBuffer), mLength(length),
- mCurrent(buffer), mLineNumber(1) {
-}
-
-Tokenizer::~Tokenizer() {
- if (mFileMap) {
- mFileMap->release();
- }
- if (mOwnBuffer) {
- delete[] mBuffer;
- }
-}
-
-status_t Tokenizer::open(const String8& filename, Tokenizer** outTokenizer) {
- *outTokenizer = NULL;
-
- int result = NO_ERROR;
- int fd = ::open(filename.string(), O_RDONLY);
- if (fd < 0) {
- result = -errno;
- ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
- } else {
- struct stat stat;
- if (fstat(fd, &stat)) {
- result = -errno;
- ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
- } else {
- size_t length = size_t(stat.st_size);
-
- FileMap* fileMap = new FileMap();
- bool ownBuffer = false;
- char* buffer;
- if (fileMap->create(NULL, fd, 0, length, true)) {
- fileMap->advise(FileMap::SEQUENTIAL);
- buffer = static_cast<char*>(fileMap->getDataPtr());
- } else {
- fileMap->release();
- fileMap = NULL;
-
- // Fall back to reading into a buffer since we can't mmap files in sysfs.
- // The length we obtained from stat is wrong too (it will always be 4096)
- // so we must trust that read will read the entire file.
- buffer = new char[length];
- ownBuffer = true;
- ssize_t nrd = read(fd, buffer, length);
- if (nrd < 0) {
- result = -errno;
- ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
- delete[] buffer;
- buffer = NULL;
- } else {
- length = size_t(nrd);
- }
- }
-
- if (!result) {
- *outTokenizer = new Tokenizer(filename, fileMap, buffer, ownBuffer, length);
- }
- }
- close(fd);
- }
- return result;
-}
-
-status_t Tokenizer::fromContents(const String8& filename,
- const char* contents, Tokenizer** outTokenizer) {
- *outTokenizer = new Tokenizer(filename, NULL,
- const_cast<char*>(contents), false, strlen(contents));
- return OK;
-}
-
-String8 Tokenizer::getLocation() const {
- String8 result;
- result.appendFormat("%s:%d", mFilename.string(), mLineNumber);
- return result;
-}
-
-String8 Tokenizer::peekRemainderOfLine() const {
- const char* end = getEnd();
- const char* eol = mCurrent;
- while (eol != end) {
- char ch = *eol;
- if (ch == '\n') {
- break;
- }
- eol += 1;
- }
- return String8(mCurrent, eol - mCurrent);
-}
-
-String8 Tokenizer::nextToken(const char* delimiters) {
-#if DEBUG_TOKENIZER
- ALOGD("nextToken");
-#endif
- const char* end = getEnd();
- const char* tokenStart = mCurrent;
- while (mCurrent != end) {
- char ch = *mCurrent;
- if (ch == '\n' || isDelimiter(ch, delimiters)) {
- break;
- }
- mCurrent += 1;
- }
- return String8(tokenStart, mCurrent - tokenStart);
-}
-
-void Tokenizer::nextLine() {
-#if DEBUG_TOKENIZER
- ALOGD("nextLine");
-#endif
- const char* end = getEnd();
- while (mCurrent != end) {
- char ch = *(mCurrent++);
- if (ch == '\n') {
- mLineNumber += 1;
- break;
- }
- }
-}
-
-void Tokenizer::skipDelimiters(const char* delimiters) {
-#if DEBUG_TOKENIZER
- ALOGD("skipDelimiters");
-#endif
- const char* end = getEnd();
- while (mCurrent != end) {
- char ch = *mCurrent;
- if (ch == '\n' || !isDelimiter(ch, delimiters)) {
- break;
- }
- mCurrent += 1;
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/Tokenizer.h b/widget/gonk/libui/Tokenizer.h
deleted file mode 100644
index bb25f374c..000000000
--- a/widget/gonk/libui/Tokenizer.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UTILS_TOKENIZER_H
-#define _UTILS_TOKENIZER_H
-
-#include <assert.h>
-#include <utils/Errors.h>
-#include <utils/FileMap.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/**
- * A simple tokenizer for loading and parsing ASCII text files line by line.
- */
-class Tokenizer {
- Tokenizer(const String8& filename, FileMap* fileMap, char* buffer,
- bool ownBuffer, size_t length);
-
-public:
- ~Tokenizer();
-
- /**
- * Opens a file and maps it into memory.
- *
- * Returns NO_ERROR and a tokenizer for the file, if successful.
- * Otherwise returns an error and sets outTokenizer to NULL.
- */
- static status_t open(const String8& filename, Tokenizer** outTokenizer);
-
- /**
- * Prepares to tokenize the contents of a string.
- *
- * Returns NO_ERROR and a tokenizer for the string, if successful.
- * Otherwise returns an error and sets outTokenizer to NULL.
- */
- static status_t fromContents(const String8& filename,
- const char* contents, Tokenizer** outTokenizer);
-
- /**
- * Returns true if at the end of the file.
- */
- inline bool isEof() const { return mCurrent == getEnd(); }
-
- /**
- * Returns true if at the end of the line or end of the file.
- */
- inline bool isEol() const { return isEof() || *mCurrent == '\n'; }
-
- /**
- * Gets the name of the file.
- */
- inline String8 getFilename() const { return mFilename; }
-
- /**
- * Gets a 1-based line number index for the current position.
- */
- inline int32_t getLineNumber() const { return mLineNumber; }
-
- /**
- * Formats a location string consisting of the filename and current line number.
- * Returns a string like "MyFile.txt:33".
- */
- String8 getLocation() const;
-
- /**
- * Gets the character at the current position.
- * Returns null at end of file.
- */
- inline char peekChar() const { return isEof() ? '\0' : *mCurrent; }
-
- /**
- * Gets the remainder of the current line as a string, excluding the newline character.
- */
- String8 peekRemainderOfLine() const;
-
- /**
- * Gets the character at the current position and advances past it.
- * Returns null at end of file.
- */
- inline char nextChar() { return isEof() ? '\0' : *(mCurrent++); }
-
- /**
- * Gets the next token on this line stopping at the specified delimiters
- * or the end of the line whichever comes first and advances past it.
- * Also stops at embedded nulls.
- * Returns the token or an empty string if the current character is a delimiter
- * or is at the end of the line.
- */
- String8 nextToken(const char* delimiters);
-
- /**
- * Advances to the next line.
- * Does nothing if already at the end of the file.
- */
- void nextLine();
-
- /**
- * Skips over the specified delimiters in the line.
- * Also skips embedded nulls.
- */
- void skipDelimiters(const char* delimiters);
-
-private:
- Tokenizer(const Tokenizer& other); // not copyable
-
- String8 mFilename;
- FileMap* mFileMap;
- char* mBuffer;
- bool mOwnBuffer;
- size_t mLength;
-
- const char* mCurrent;
- int32_t mLineNumber;
-
- inline const char* getEnd() const { return mBuffer + mLength; }
-
-};
-
-} // namespace android
-
-#endif // _UTILS_TOKENIZER_H
diff --git a/widget/gonk/libui/Trace.h b/widget/gonk/libui/Trace.h
deleted file mode 100644
index 24fbfb602..000000000
--- a/widget/gonk/libui/Trace.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_TRACE_H
-#define ANDROID_TRACE_H
-
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <cutils/compiler.h>
-#include <utils/threads.h>
-#include "cutils_trace.h"
-
-// See <cutils/trace.h> for more ATRACE_* macros.
-
-// ATRACE_NAME traces the beginning and end of the current scope. To trace
-// the correct start and end times this macro should be declared first in the
-// scope body.
-#define ATRACE_NAME(name) android::ScopedTrace ___tracer(ATRACE_TAG, name)
-// ATRACE_CALL is an ATRACE_NAME that uses the current function name.
-#define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
-
-namespace android {
-
-class ScopedTrace {
-public:
-inline ScopedTrace(uint64_t tag, const char* name)
- : mTag(tag) {
-#ifdef HAVE_ANDROID_OS
- atrace_begin(mTag,name);
-#endif
-}
-
-inline ~ScopedTrace() {
-#ifdef HAVE_ANDROID_OS
- atrace_end(mTag);
-#endif
-}
-
-private:
- uint64_t mTag;
-};
-
-}; // namespace android
-
-#endif // ANDROID_TRACE_H
diff --git a/widget/gonk/libui/VelocityControl.cpp b/widget/gonk/libui/VelocityControl.cpp
deleted file mode 100644
index 31365a220..000000000
--- a/widget/gonk/libui/VelocityControl.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VelocityControl"
-//#define LOG_NDEBUG 0
-
-// Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
-
-#include <math.h>
-#include <limits.h>
-
-#include "VelocityControl.h"
-#include <utils/BitSet.h>
-#include <utils/Timers.h>
-
-namespace android {
-
-// --- VelocityControl ---
-
-const nsecs_t VelocityControl::STOP_TIME;
-
-VelocityControl::VelocityControl() {
- reset();
-}
-
-void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
- mParameters = parameters;
- reset();
-}
-
-void VelocityControl::reset() {
- mLastMovementTime = LLONG_MIN;
- mRawPosition.x = 0;
- mRawPosition.y = 0;
- mVelocityTracker.clear();
-}
-
-void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
- if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
- if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
- ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
- (eventTime - mLastMovementTime) * 0.000001f);
-#endif
- reset();
- }
-
- mLastMovementTime = eventTime;
- if (deltaX) {
- mRawPosition.x += *deltaX;
- }
- if (deltaY) {
- mRawPosition.y += *deltaY;
- }
- mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition);
-
- float vx, vy;
- float scale = mParameters.scale;
- if (mVelocityTracker.getVelocity(0, &vx, &vy)) {
- float speed = hypotf(vx, vy) * scale;
- if (speed >= mParameters.highThreshold) {
- // Apply full acceleration above the high speed threshold.
- scale *= mParameters.acceleration;
- } else if (speed > mParameters.lowThreshold) {
- // Linearly interpolate the acceleration to apply between the low and high
- // speed thresholds.
- scale *= 1 + (speed - mParameters.lowThreshold)
- / (mParameters.highThreshold - mParameters.lowThreshold)
- * (mParameters.acceleration - 1);
- }
-
-#if DEBUG_ACCELERATION
- ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
- "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
- mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
- mParameters.acceleration,
- vx, vy, speed, scale / mParameters.scale);
-#endif
- } else {
-#if DEBUG_ACCELERATION
- ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
- mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
- mParameters.acceleration);
-#endif
- }
-
- if (deltaX) {
- *deltaX *= scale;
- }
- if (deltaY) {
- *deltaY *= scale;
- }
- }
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/VelocityControl.h b/widget/gonk/libui/VelocityControl.h
deleted file mode 100644
index 8a2c695d6..000000000
--- a/widget/gonk/libui/VelocityControl.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_VELOCITY_CONTROL_H
-#define _ANDROIDFW_VELOCITY_CONTROL_H
-
-#include "Input.h"
-#include "VelocityTracker.h"
-#include <utils/Timers.h>
-
-namespace android {
-
-/*
- * Specifies parameters that govern pointer or wheel acceleration.
- */
-struct VelocityControlParameters {
- // A scale factor that is multiplied with the raw velocity deltas
- // prior to applying any other velocity control factors. The scale
- // factor should be used to adapt the input device resolution
- // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
- //
- // Must be a positive value.
- // Default is 1.0 (no scaling).
- float scale;
-
- // The scaled speed at which acceleration begins to be applied.
- // This value establishes the upper bound of a low speed regime for
- // small precise motions that are performed without any acceleration.
- //
- // Must be a non-negative value.
- // Default is 0.0 (no low threshold).
- float lowThreshold;
-
- // The scaled speed at which maximum acceleration is applied.
- // The difference between highThreshold and lowThreshold controls
- // the range of speeds over which the acceleration factor is interpolated.
- // The wider the range, the smoother the acceleration.
- //
- // Must be a non-negative value greater than or equal to lowThreshold.
- // Default is 0.0 (no high threshold).
- float highThreshold;
-
- // The acceleration factor.
- // When the speed is above the low speed threshold, the velocity will scaled
- // by an interpolated value between 1.0 and this amount.
- //
- // Must be a positive greater than or equal to 1.0.
- // Default is 1.0 (no acceleration).
- float acceleration;
-
- VelocityControlParameters() :
- scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
- }
-
- VelocityControlParameters(float scale, float lowThreshold,
- float highThreshold, float acceleration) :
- scale(scale), lowThreshold(lowThreshold),
- highThreshold(highThreshold), acceleration(acceleration) {
- }
-};
-
-/*
- * Implements mouse pointer and wheel speed control and acceleration.
- */
-class VelocityControl {
-public:
- VelocityControl();
-
- /* Sets the various parameters. */
- void setParameters(const VelocityControlParameters& parameters);
-
- /* Resets the current movement counters to zero.
- * This has the effect of nullifying any acceleration. */
- void reset();
-
- /* Translates a raw movement delta into an appropriately
- * scaled / accelerated delta based on the current velocity. */
- void move(nsecs_t eventTime, float* deltaX, float* deltaY);
-
-private:
- // If no movements are received within this amount of time,
- // we assume the movement has stopped and reset the movement counters.
- static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms
-
- VelocityControlParameters mParameters;
-
- nsecs_t mLastMovementTime;
- VelocityTracker::Position mRawPosition;
- VelocityTracker mVelocityTracker;
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_CONTROL_H
diff --git a/widget/gonk/libui/VelocityTracker.cpp b/widget/gonk/libui/VelocityTracker.cpp
deleted file mode 100644
index 11a8bf7fc..000000000
--- a/widget/gonk/libui/VelocityTracker.cpp
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VelocityTracker"
-//#define LOG_NDEBUG 0
-#include "cutils_log.h"
-
-// Log debug messages about velocity tracking.
-#define DEBUG_VELOCITY 0
-
-// Log debug messages about the progress of the algorithm itself.
-#define DEBUG_STRATEGY 0
-
-#include <math.h>
-#include <limits.h>
-
-#include "VelocityTracker.h"
-#include <utils/BitSet.h>
-#include <utils/String8.h>
-#include <utils/Timers.h>
-
-#include <cutils/properties.h>
-
-namespace android {
-
-// Nanoseconds per milliseconds.
-static const nsecs_t NANOS_PER_MS = 1000000;
-
-// Threshold for determining that a pointer has stopped moving.
-// Some input devices do not send ACTION_MOVE events in the case where a pointer has
-// stopped. We need to detect this case so that we can accurately predict the
-// velocity after the pointer starts moving again.
-static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;
-
-
-static float vectorDot(const float* a, const float* b, uint32_t m) {
- float r = 0;
- while (m--) {
- r += *(a++) * *(b++);
- }
- return r;
-}
-
-static float vectorNorm(const float* a, uint32_t m) {
- float r = 0;
- while (m--) {
- float t = *(a++);
- r += t * t;
- }
- return sqrtf(r);
-}
-
-#if DEBUG_STRATEGY || DEBUG_VELOCITY
-static String8 vectorToString(const float* a, uint32_t m) {
- String8 str;
- str.append("[");
- while (m--) {
- str.appendFormat(" %f", *(a++));
- if (m) {
- str.append(",");
- }
- }
- str.append(" ]");
- return str;
-}
-
-static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) {
- String8 str;
- str.append("[");
- for (size_t i = 0; i < m; i++) {
- if (i) {
- str.append(",");
- }
- str.append(" [");
- for (size_t j = 0; j < n; j++) {
- if (j) {
- str.append(",");
- }
- str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]);
- }
- str.append(" ]");
- }
- str.append(" ]");
- return str;
-}
-#endif
-
-
-// --- VelocityTracker ---
-
-// The default velocity tracker strategy.
-// Although other strategies are available for testing and comparison purposes,
-// this is the strategy that applications will actually use. Be very careful
-// when adjusting the default strategy because it can dramatically affect
-// (often in a bad way) the user experience.
-const char* VelocityTracker::DEFAULT_STRATEGY = "lsq2";
-
-VelocityTracker::VelocityTracker(const char* strategy) :
- mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1) {
- char value[PROPERTY_VALUE_MAX];
-
- // Allow the default strategy to be overridden using a system property for debugging.
- if (!strategy) {
- int length = property_get("debug.velocitytracker.strategy", value, NULL);
- if (length > 0) {
- strategy = value;
- } else {
- strategy = DEFAULT_STRATEGY;
- }
- }
-
- // Configure the strategy.
- if (!configureStrategy(strategy)) {
- ALOGD("Unrecognized velocity tracker strategy name '%s'.", strategy);
- if (!configureStrategy(DEFAULT_STRATEGY)) {
- LOG_ALWAYS_FATAL("Could not create the default velocity tracker strategy '%s'!",
- strategy);
- }
- }
-}
-
-VelocityTracker::~VelocityTracker() {
- delete mStrategy;
-}
-
-bool VelocityTracker::configureStrategy(const char* strategy) {
- mStrategy = createStrategy(strategy);
- return mStrategy != NULL;
-}
-
-VelocityTrackerStrategy* VelocityTracker::createStrategy(const char* strategy) {
- if (!strcmp("lsq1", strategy)) {
- // 1st order least squares. Quality: POOR.
- // Frequently underfits the touch data especially when the finger accelerates
- // or changes direction. Often underestimates velocity. The direction
- // is overly influenced by historical touch points.
- return new LeastSquaresVelocityTrackerStrategy(1);
- }
- if (!strcmp("lsq2", strategy)) {
- // 2nd order least squares. Quality: VERY GOOD.
- // Pretty much ideal, but can be confused by certain kinds of touch data,
- // particularly if the panel has a tendency to generate delayed,
- // duplicate or jittery touch coordinates when the finger is released.
- return new LeastSquaresVelocityTrackerStrategy(2);
- }
- if (!strcmp("lsq3", strategy)) {
- // 3rd order least squares. Quality: UNUSABLE.
- // Frequently overfits the touch data yielding wildly divergent estimates
- // of the velocity when the finger is released.
- return new LeastSquaresVelocityTrackerStrategy(3);
- }
- if (!strcmp("wlsq2-delta", strategy)) {
- // 2nd order weighted least squares, delta weighting. Quality: EXPERIMENTAL
- return new LeastSquaresVelocityTrackerStrategy(2,
- LeastSquaresVelocityTrackerStrategy::WEIGHTING_DELTA);
- }
- if (!strcmp("wlsq2-central", strategy)) {
- // 2nd order weighted least squares, central weighting. Quality: EXPERIMENTAL
- return new LeastSquaresVelocityTrackerStrategy(2,
- LeastSquaresVelocityTrackerStrategy::WEIGHTING_CENTRAL);
- }
- if (!strcmp("wlsq2-recent", strategy)) {
- // 2nd order weighted least squares, recent weighting. Quality: EXPERIMENTAL
- return new LeastSquaresVelocityTrackerStrategy(2,
- LeastSquaresVelocityTrackerStrategy::WEIGHTING_RECENT);
- }
- if (!strcmp("int1", strategy)) {
- // 1st order integrating filter. Quality: GOOD.
- // Not as good as 'lsq2' because it cannot estimate acceleration but it is
- // more tolerant of errors. Like 'lsq1', this strategy tends to underestimate
- // the velocity of a fling but this strategy tends to respond to changes in
- // direction more quickly and accurately.
- return new IntegratingVelocityTrackerStrategy(1);
- }
- if (!strcmp("int2", strategy)) {
- // 2nd order integrating filter. Quality: EXPERIMENTAL.
- // For comparison purposes only. Unlike 'int1' this strategy can compensate
- // for acceleration but it typically overestimates the effect.
- return new IntegratingVelocityTrackerStrategy(2);
- }
- if (!strcmp("legacy", strategy)) {
- // Legacy velocity tracker algorithm. Quality: POOR.
- // For comparison purposes only. This algorithm is strongly influenced by
- // old data points, consistently underestimates velocity and takes a very long
- // time to adjust to changes in direction.
- return new LegacyVelocityTrackerStrategy();
- }
- return NULL;
-}
-
-void VelocityTracker::clear() {
- mCurrentPointerIdBits.clear();
- mActivePointerId = -1;
-
- mStrategy->clear();
-}
-
-void VelocityTracker::clearPointers(BitSet32 idBits) {
- BitSet32 remainingIdBits(mCurrentPointerIdBits.value & ~idBits.value);
- mCurrentPointerIdBits = remainingIdBits;
-
- if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
- mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
- }
-
- mStrategy->clearPointers(idBits);
-}
-
-void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
- while (idBits.count() > MAX_POINTERS) {
- idBits.clearLastMarkedBit();
- }
-
- if ((mCurrentPointerIdBits.value & idBits.value)
- && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
-#if DEBUG_VELOCITY
- ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
- (eventTime - mLastEventTime) * 0.000001f);
-#endif
- // We have not received any movements for too long. Assume that all pointers
- // have stopped.
- mStrategy->clear();
- }
- mLastEventTime = eventTime;
-
- mCurrentPointerIdBits = idBits;
- if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
- mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
- }
-
- mStrategy->addMovement(eventTime, idBits, positions);
-
-#if DEBUG_VELOCITY
- ALOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
- eventTime, idBits.value, mActivePointerId);
- for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
- uint32_t id = iterBits.firstMarkedBit();
- uint32_t index = idBits.getIndexOfBit(id);
- iterBits.clearBit(id);
- Estimator estimator;
- getEstimator(id, &estimator);
- ALOGD(" %d: position (%0.3f, %0.3f), "
- "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)",
- id, positions[index].x, positions[index].y,
- int(estimator.degree),
- vectorToString(estimator.xCoeff, estimator.degree + 1).string(),
- vectorToString(estimator.yCoeff, estimator.degree + 1).string(),
- estimator.confidence);
- }
-#endif
-}
-
-void VelocityTracker::addMovement(const MotionEvent* event) {
- int32_t actionMasked = event->getActionMasked();
-
- switch (actionMasked) {
- case AMOTION_EVENT_ACTION_DOWN:
- case AMOTION_EVENT_ACTION_HOVER_ENTER:
- // Clear all pointers on down before adding the new movement.
- clear();
- break;
- case AMOTION_EVENT_ACTION_POINTER_DOWN: {
- // Start a new movement trace for a pointer that just went down.
- // We do this on down instead of on up because the client may want to query the
- // final velocity for a pointer that just went up.
- BitSet32 downIdBits;
- downIdBits.markBit(event->getPointerId(event->getActionIndex()));
- clearPointers(downIdBits);
- break;
- }
- case AMOTION_EVENT_ACTION_MOVE:
- case AMOTION_EVENT_ACTION_HOVER_MOVE:
- break;
- default:
- // Ignore all other actions because they do not convey any new information about
- // pointer movement. We also want to preserve the last known velocity of the pointers.
- // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
- // of the pointers that went up. ACTION_POINTER_UP does include the new position of
- // pointers that remained down but we will also receive an ACTION_MOVE with this
- // information if any of them actually moved. Since we don't know how many pointers
- // will be going up at once it makes sense to just wait for the following ACTION_MOVE
- // before adding the movement.
- return;
- }
-
- size_t pointerCount = event->getPointerCount();
- if (pointerCount > MAX_POINTERS) {
- pointerCount = MAX_POINTERS;
- }
-
- BitSet32 idBits;
- for (size_t i = 0; i < pointerCount; i++) {
- idBits.markBit(event->getPointerId(i));
- }
-
- uint32_t pointerIndex[MAX_POINTERS];
- for (size_t i = 0; i < pointerCount; i++) {
- pointerIndex[i] = idBits.getIndexOfBit(event->getPointerId(i));
- }
-
- nsecs_t eventTime;
- Position positions[pointerCount];
-
- size_t historySize = event->getHistorySize();
- for (size_t h = 0; h < historySize; h++) {
- eventTime = event->getHistoricalEventTime(h);
- for (size_t i = 0; i < pointerCount; i++) {
- uint32_t index = pointerIndex[i];
- positions[index].x = event->getHistoricalX(i, h);
- positions[index].y = event->getHistoricalY(i, h);
- }
- addMovement(eventTime, idBits, positions);
- }
-
- eventTime = event->getEventTime();
- for (size_t i = 0; i < pointerCount; i++) {
- uint32_t index = pointerIndex[i];
- positions[index].x = event->getX(i);
- positions[index].y = event->getY(i);
- }
- addMovement(eventTime, idBits, positions);
-}
-
-bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
- Estimator estimator;
- if (getEstimator(id, &estimator) && estimator.degree >= 1) {
- *outVx = estimator.xCoeff[1];
- *outVy = estimator.yCoeff[1];
- return true;
- }
- *outVx = 0;
- *outVy = 0;
- return false;
-}
-
-bool VelocityTracker::getEstimator(uint32_t id, Estimator* outEstimator) const {
- return mStrategy->getEstimator(id, outEstimator);
-}
-
-
-// --- LeastSquaresVelocityTrackerStrategy ---
-
-const nsecs_t LeastSquaresVelocityTrackerStrategy::HORIZON;
-const uint32_t LeastSquaresVelocityTrackerStrategy::HISTORY_SIZE;
-
-LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
- uint32_t degree, Weighting weighting) :
- mDegree(degree), mWeighting(weighting) {
- clear();
-}
-
-LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {
-}
-
-void LeastSquaresVelocityTrackerStrategy::clear() {
- mIndex = 0;
- mMovements[0].idBits.clear();
-}
-
-void LeastSquaresVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
- mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions) {
- if (++mIndex == HISTORY_SIZE) {
- mIndex = 0;
- }
-
- Movement& movement = mMovements[mIndex];
- movement.eventTime = eventTime;
- movement.idBits = idBits;
- uint32_t count = idBits.count();
- for (uint32_t i = 0; i < count; i++) {
- movement.positions[i] = positions[i];
- }
-}
-
-/**
- * Solves a linear least squares problem to obtain a N degree polynomial that fits
- * the specified input data as nearly as possible.
- *
- * Returns true if a solution is found, false otherwise.
- *
- * The input consists of two vectors of data points X and Y with indices 0..m-1
- * along with a weight vector W of the same size.
- *
- * The output is a vector B with indices 0..n that describes a polynomial
- * that fits the data, such the sum of W[i] * W[i] * abs(Y[i] - (B[0] + B[1] X[i]
- * + B[2] X[i]^2 ... B[n] X[i]^n)) for all i between 0 and m-1 is minimized.
- *
- * Accordingly, the weight vector W should be initialized by the caller with the
- * reciprocal square root of the variance of the error in each input data point.
- * In other words, an ideal choice for W would be W[i] = 1 / var(Y[i]) = 1 / stddev(Y[i]).
- * The weights express the relative importance of each data point. If the weights are
- * all 1, then the data points are considered to be of equal importance when fitting
- * the polynomial. It is a good idea to choose weights that diminish the importance
- * of data points that may have higher than usual error margins.
- *
- * Errors among data points are assumed to be independent. W is represented here
- * as a vector although in the literature it is typically taken to be a diagonal matrix.
- *
- * That is to say, the function that generated the input data can be approximated
- * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n.
- *
- * The coefficient of determination (R^2) is also returned to describe the goodness
- * of fit of the model for the given data. It is a value between 0 and 1, where 1
- * indicates perfect correspondence.
- *
- * This function first expands the X vector to a m by n matrix A such that
- * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n, then
- * multiplies it by w[i]./
- *
- * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q
- * and an m by n upper triangular matrix R. Because R is upper triangular (lower
- * part is all zeroes), we can simplify the decomposition into an m by n matrix
- * Q1 and a n by n matrix R1 such that A = Q1 R1.
- *
- * Finally we solve the system of linear equations given by R1 B = (Qtranspose W Y)
- * to find B.
- *
- * For efficiency, we lay out A and Q column-wise in memory because we frequently
- * operate on the column vectors. Conversely, we lay out R row-wise.
- *
- * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares
- * http://en.wikipedia.org/wiki/Gram-Schmidt
- */
-static bool solveLeastSquares(const float* x, const float* y,
- const float* w, uint32_t m, uint32_t n, float* outB, float* outDet) {
-#if DEBUG_STRATEGY
- ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
- vectorToString(x, m).string(), vectorToString(y, m).string(),
- vectorToString(w, m).string());
-#endif
-
- // Expand the X vector to a matrix A, pre-multiplied by the weights.
- float a[n][m]; // column-major order
- for (uint32_t h = 0; h < m; h++) {
- a[0][h] = w[h];
- for (uint32_t i = 1; i < n; i++) {
- a[i][h] = a[i - 1][h] * x[h];
- }
- }
-#if DEBUG_STRATEGY
- ALOGD(" - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
- // Apply the Gram-Schmidt process to A to obtain its QR decomposition.
- float q[n][m]; // orthonormal basis, column-major order
- float r[n][n]; // upper triangular matrix, row-major order
- for (uint32_t j = 0; j < n; j++) {
- for (uint32_t h = 0; h < m; h++) {
- q[j][h] = a[j][h];
- }
- for (uint32_t i = 0; i < j; i++) {
- float dot = vectorDot(&q[j][0], &q[i][0], m);
- for (uint32_t h = 0; h < m; h++) {
- q[j][h] -= dot * q[i][h];
- }
- }
-
- float norm = vectorNorm(&q[j][0], m);
- if (norm < 0.000001f) {
- // vectors are linearly dependent or zero so no solution
-#if DEBUG_STRATEGY
- ALOGD(" - no solution, norm=%f", norm);
-#endif
- return false;
- }
-
- float invNorm = 1.0f / norm;
- for (uint32_t h = 0; h < m; h++) {
- q[j][h] *= invNorm;
- }
- for (uint32_t i = 0; i < n; i++) {
- r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m);
- }
- }
-#if DEBUG_STRATEGY
- ALOGD(" - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string());
- ALOGD(" - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string());
-
- // calculate QR, if we factored A correctly then QR should equal A
- float qr[n][m];
- for (uint32_t h = 0; h < m; h++) {
- for (uint32_t i = 0; i < n; i++) {
- qr[i][h] = 0;
- for (uint32_t j = 0; j < n; j++) {
- qr[i][h] += q[j][h] * r[j][i];
- }
- }
- }
- ALOGD(" - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string());
-#endif
-
- // Solve R B = Qt W Y to find B. This is easy because R is upper triangular.
- // We just work from bottom-right to top-left calculating B's coefficients.
- float wy[m];
- for (uint32_t h = 0; h < m; h++) {
- wy[h] = y[h] * w[h];
- }
- for (uint32_t i = n; i-- != 0; ) {
- outB[i] = vectorDot(&q[i][0], wy, m);
- for (uint32_t j = n - 1; j > i; j--) {
- outB[i] -= r[i][j] * outB[j];
- }
- outB[i] /= r[i][i];
- }
-#if DEBUG_STRATEGY
- ALOGD(" - b=%s", vectorToString(outB, n).string());
-#endif
-
- // Calculate the coefficient of determination as 1 - (SSerr / SStot) where
- // SSerr is the residual sum of squares (variance of the error),
- // and SStot is the total sum of squares (variance of the data) where each
- // has been weighted.
- float ymean = 0;
- for (uint32_t h = 0; h < m; h++) {
- ymean += y[h];
- }
- ymean /= m;
-
- float sserr = 0;
- float sstot = 0;
- for (uint32_t h = 0; h < m; h++) {
- float err = y[h] - outB[0];
- float term = 1;
- for (uint32_t i = 1; i < n; i++) {
- term *= x[h];
- err -= term * outB[i];
- }
- sserr += w[h] * w[h] * err * err;
- float var = y[h] - ymean;
- sstot += w[h] * w[h] * var * var;
- }
- *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
-#if DEBUG_STRATEGY
- ALOGD(" - sserr=%f", sserr);
- ALOGD(" - sstot=%f", sstot);
- ALOGD(" - det=%f", *outDet);
-#endif
- return true;
-}
-
-bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
- VelocityTracker::Estimator* outEstimator) const {
- outEstimator->clear();
-
- // Iterate over movement samples in reverse time order and collect samples.
- float x[HISTORY_SIZE];
- float y[HISTORY_SIZE];
- float w[HISTORY_SIZE];
- float time[HISTORY_SIZE];
- uint32_t m = 0;
- uint32_t index = mIndex;
- const Movement& newestMovement = mMovements[mIndex];
- do {
- const Movement& movement = mMovements[index];
- if (!movement.idBits.hasBit(id)) {
- break;
- }
-
- nsecs_t age = newestMovement.eventTime - movement.eventTime;
- if (age > HORIZON) {
- break;
- }
-
- const VelocityTracker::Position& position = movement.getPosition(id);
- x[m] = position.x;
- y[m] = position.y;
- w[m] = chooseWeight(index);
- time[m] = -age * 0.000000001f;
- index = (index == 0 ? HISTORY_SIZE : index) - 1;
- } while (++m < HISTORY_SIZE);
-
- if (m == 0) {
- return false; // no data
- }
-
- // Calculate a least squares polynomial fit.
- uint32_t degree = mDegree;
- if (degree > m - 1) {
- degree = m - 1;
- }
- if (degree >= 1) {
- float xdet, ydet;
- uint32_t n = degree + 1;
- if (solveLeastSquares(time, x, w, m, n, outEstimator->xCoeff, &xdet)
- && solveLeastSquares(time, y, w, m, n, outEstimator->yCoeff, &ydet)) {
- outEstimator->time = newestMovement.eventTime;
- outEstimator->degree = degree;
- outEstimator->confidence = xdet * ydet;
-#if DEBUG_STRATEGY
- ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
- int(outEstimator->degree),
- vectorToString(outEstimator->xCoeff, n).string(),
- vectorToString(outEstimator->yCoeff, n).string(),
- outEstimator->confidence);
-#endif
- return true;
- }
- }
-
- // No velocity data available for this pointer, but we do have its current position.
- outEstimator->xCoeff[0] = x[0];
- outEstimator->yCoeff[0] = y[0];
- outEstimator->time = newestMovement.eventTime;
- outEstimator->degree = 0;
- outEstimator->confidence = 1;
- return true;
-}
-
-float LeastSquaresVelocityTrackerStrategy::chooseWeight(uint32_t index) const {
- switch (mWeighting) {
- case WEIGHTING_DELTA: {
- // Weight points based on how much time elapsed between them and the next
- // point so that points that "cover" a shorter time span are weighed less.
- // delta 0ms: 0.5
- // delta 10ms: 1.0
- if (index == mIndex) {
- return 1.0f;
- }
- uint32_t nextIndex = (index + 1) % HISTORY_SIZE;
- float deltaMillis = (mMovements[nextIndex].eventTime- mMovements[index].eventTime)
- * 0.000001f;
- if (deltaMillis < 0) {
- return 0.5f;
- }
- if (deltaMillis < 10) {
- return 0.5f + deltaMillis * 0.05;
- }
- return 1.0f;
- }
-
- case WEIGHTING_CENTRAL: {
- // Weight points based on their age, weighing very recent and very old points less.
- // age 0ms: 0.5
- // age 10ms: 1.0
- // age 50ms: 1.0
- // age 60ms: 0.5
- float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
- * 0.000001f;
- if (ageMillis < 0) {
- return 0.5f;
- }
- if (ageMillis < 10) {
- return 0.5f + ageMillis * 0.05;
- }
- if (ageMillis < 50) {
- return 1.0f;
- }
- if (ageMillis < 60) {
- return 0.5f + (60 - ageMillis) * 0.05;
- }
- return 0.5f;
- }
-
- case WEIGHTING_RECENT: {
- // Weight points based on their age, weighing older points less.
- // age 0ms: 1.0
- // age 50ms: 1.0
- // age 100ms: 0.5
- float ageMillis = (mMovements[mIndex].eventTime - mMovements[index].eventTime)
- * 0.000001f;
- if (ageMillis < 50) {
- return 1.0f;
- }
- if (ageMillis < 100) {
- return 0.5f + (100 - ageMillis) * 0.01f;
- }
- return 0.5f;
- }
-
- case WEIGHTING_NONE:
- default:
- return 1.0f;
- }
-}
-
-
-// --- IntegratingVelocityTrackerStrategy ---
-
-IntegratingVelocityTrackerStrategy::IntegratingVelocityTrackerStrategy(uint32_t degree) :
- mDegree(degree) {
-}
-
-IntegratingVelocityTrackerStrategy::~IntegratingVelocityTrackerStrategy() {
-}
-
-void IntegratingVelocityTrackerStrategy::clear() {
- mPointerIdBits.clear();
-}
-
-void IntegratingVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
- mPointerIdBits.value &= ~idBits.value;
-}
-
-void IntegratingVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions) {
- uint32_t index = 0;
- for (BitSet32 iterIdBits(idBits); !iterIdBits.isEmpty();) {
- uint32_t id = iterIdBits.clearFirstMarkedBit();
- State& state = mPointerState[id];
- const VelocityTracker::Position& position = positions[index++];
- if (mPointerIdBits.hasBit(id)) {
- updateState(state, eventTime, position.x, position.y);
- } else {
- initState(state, eventTime, position.x, position.y);
- }
- }
-
- mPointerIdBits = idBits;
-}
-
-bool IntegratingVelocityTrackerStrategy::getEstimator(uint32_t id,
- VelocityTracker::Estimator* outEstimator) const {
- outEstimator->clear();
-
- if (mPointerIdBits.hasBit(id)) {
- const State& state = mPointerState[id];
- populateEstimator(state, outEstimator);
- return true;
- }
-
- return false;
-}
-
-void IntegratingVelocityTrackerStrategy::initState(State& state,
- nsecs_t eventTime, float xpos, float ypos) const {
- state.updateTime = eventTime;
- state.degree = 0;
-
- state.xpos = xpos;
- state.xvel = 0;
- state.xaccel = 0;
- state.ypos = ypos;
- state.yvel = 0;
- state.yaccel = 0;
-}
-
-void IntegratingVelocityTrackerStrategy::updateState(State& state,
- nsecs_t eventTime, float xpos, float ypos) const {
- const nsecs_t MIN_TIME_DELTA = 2 * NANOS_PER_MS;
- const float FILTER_TIME_CONSTANT = 0.010f; // 10 milliseconds
-
- if (eventTime <= state.updateTime + MIN_TIME_DELTA) {
- return;
- }
-
- float dt = (eventTime - state.updateTime) * 0.000000001f;
- state.updateTime = eventTime;
-
- float xvel = (xpos - state.xpos) / dt;
- float yvel = (ypos - state.ypos) / dt;
- if (state.degree == 0) {
- state.xvel = xvel;
- state.yvel = yvel;
- state.degree = 1;
- } else {
- float alpha = dt / (FILTER_TIME_CONSTANT + dt);
- if (mDegree == 1) {
- state.xvel += (xvel - state.xvel) * alpha;
- state.yvel += (yvel - state.yvel) * alpha;
- } else {
- float xaccel = (xvel - state.xvel) / dt;
- float yaccel = (yvel - state.yvel) / dt;
- if (state.degree == 1) {
- state.xaccel = xaccel;
- state.yaccel = yaccel;
- state.degree = 2;
- } else {
- state.xaccel += (xaccel - state.xaccel) * alpha;
- state.yaccel += (yaccel - state.yaccel) * alpha;
- }
- state.xvel += (state.xaccel * dt) * alpha;
- state.yvel += (state.yaccel * dt) * alpha;
- }
- }
- state.xpos = xpos;
- state.ypos = ypos;
-}
-
-void IntegratingVelocityTrackerStrategy::populateEstimator(const State& state,
- VelocityTracker::Estimator* outEstimator) const {
- outEstimator->time = state.updateTime;
- outEstimator->confidence = 1.0f;
- outEstimator->degree = state.degree;
- outEstimator->xCoeff[0] = state.xpos;
- outEstimator->xCoeff[1] = state.xvel;
- outEstimator->xCoeff[2] = state.xaccel / 2;
- outEstimator->yCoeff[0] = state.ypos;
- outEstimator->yCoeff[1] = state.yvel;
- outEstimator->yCoeff[2] = state.yaccel / 2;
-}
-
-
-// --- LegacyVelocityTrackerStrategy ---
-
-const nsecs_t LegacyVelocityTrackerStrategy::HORIZON;
-const uint32_t LegacyVelocityTrackerStrategy::HISTORY_SIZE;
-const nsecs_t LegacyVelocityTrackerStrategy::MIN_DURATION;
-
-LegacyVelocityTrackerStrategy::LegacyVelocityTrackerStrategy() {
- clear();
-}
-
-LegacyVelocityTrackerStrategy::~LegacyVelocityTrackerStrategy() {
-}
-
-void LegacyVelocityTrackerStrategy::clear() {
- mIndex = 0;
- mMovements[0].idBits.clear();
-}
-
-void LegacyVelocityTrackerStrategy::clearPointers(BitSet32 idBits) {
- BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
- mMovements[mIndex].idBits = remainingIdBits;
-}
-
-void LegacyVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions) {
- if (++mIndex == HISTORY_SIZE) {
- mIndex = 0;
- }
-
- Movement& movement = mMovements[mIndex];
- movement.eventTime = eventTime;
- movement.idBits = idBits;
- uint32_t count = idBits.count();
- for (uint32_t i = 0; i < count; i++) {
- movement.positions[i] = positions[i];
- }
-}
-
-bool LegacyVelocityTrackerStrategy::getEstimator(uint32_t id,
- VelocityTracker::Estimator* outEstimator) const {
- outEstimator->clear();
-
- const Movement& newestMovement = mMovements[mIndex];
- if (!newestMovement.idBits.hasBit(id)) {
- return false; // no data
- }
-
- // Find the oldest sample that contains the pointer and that is not older than HORIZON.
- nsecs_t minTime = newestMovement.eventTime - HORIZON;
- uint32_t oldestIndex = mIndex;
- uint32_t numTouches = 1;
- do {
- uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
- const Movement& nextOldestMovement = mMovements[nextOldestIndex];
- if (!nextOldestMovement.idBits.hasBit(id)
- || nextOldestMovement.eventTime < minTime) {
- break;
- }
- oldestIndex = nextOldestIndex;
- } while (++numTouches < HISTORY_SIZE);
-
- // Calculate an exponentially weighted moving average of the velocity estimate
- // at different points in time measured relative to the oldest sample.
- // This is essentially an IIR filter. Newer samples are weighted more heavily
- // than older samples. Samples at equal time points are weighted more or less
- // equally.
- //
- // One tricky problem is that the sample data may be poorly conditioned.
- // Sometimes samples arrive very close together in time which can cause us to
- // overestimate the velocity at that time point. Most samples might be measured
- // 16ms apart but some consecutive samples could be only 0.5sm apart because
- // the hardware or driver reports them irregularly or in bursts.
- float accumVx = 0;
- float accumVy = 0;
- uint32_t index = oldestIndex;
- uint32_t samplesUsed = 0;
- const Movement& oldestMovement = mMovements[oldestIndex];
- const VelocityTracker::Position& oldestPosition = oldestMovement.getPosition(id);
- nsecs_t lastDuration = 0;
-
- while (numTouches-- > 1) {
- if (++index == HISTORY_SIZE) {
- index = 0;
- }
- const Movement& movement = mMovements[index];
- nsecs_t duration = movement.eventTime - oldestMovement.eventTime;
-
- // If the duration between samples is small, we may significantly overestimate
- // the velocity. Consequently, we impose a minimum duration constraint on the
- // samples that we include in the calculation.
- if (duration >= MIN_DURATION) {
- const VelocityTracker::Position& position = movement.getPosition(id);
- float scale = 1000000000.0f / duration; // one over time delta in seconds
- float vx = (position.x - oldestPosition.x) * scale;
- float vy = (position.y - oldestPosition.y) * scale;
- accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration);
- accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration);
- lastDuration = duration;
- samplesUsed += 1;
- }
- }
-
- // Report velocity.
- const VelocityTracker::Position& newestPosition = newestMovement.getPosition(id);
- outEstimator->time = newestMovement.eventTime;
- outEstimator->confidence = 1;
- outEstimator->xCoeff[0] = newestPosition.x;
- outEstimator->yCoeff[0] = newestPosition.y;
- if (samplesUsed) {
- outEstimator->xCoeff[1] = accumVx;
- outEstimator->yCoeff[1] = accumVy;
- outEstimator->degree = 1;
- } else {
- outEstimator->degree = 0;
- }
- return true;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/VelocityTracker.h b/widget/gonk/libui/VelocityTracker.h
deleted file mode 100644
index fd077d438..000000000
--- a/widget/gonk/libui/VelocityTracker.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_VELOCITY_TRACKER_H
-#define _ANDROIDFW_VELOCITY_TRACKER_H
-
-#include "Input.h"
-#include <utils/Timers.h>
-#include <utils/BitSet.h>
-
-namespace android {
-
-class VelocityTrackerStrategy;
-
-/*
- * Calculates the velocity of pointer movements over time.
- */
-class VelocityTracker {
-public:
- struct Position {
- float x, y;
- };
-
- struct Estimator {
- static const size_t MAX_DEGREE = 4;
-
- // Estimator time base.
- nsecs_t time;
-
- // Polynomial coefficients describing motion in X and Y.
- float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
-
- // Polynomial degree (number of coefficients), or zero if no information is
- // available.
- uint32_t degree;
-
- // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
- float confidence;
-
- inline void clear() {
- time = 0;
- degree = 0;
- confidence = 0;
- for (size_t i = 0; i <= MAX_DEGREE; i++) {
- xCoeff[i] = 0;
- yCoeff[i] = 0;
- }
- }
- };
-
- // Creates a velocity tracker using the specified strategy.
- // If strategy is NULL, uses the default strategy for the platform.
- VelocityTracker(const char* strategy = NULL);
-
- ~VelocityTracker();
-
- // Resets the velocity tracker state.
- void clear();
-
- // Resets the velocity tracker state for specific pointers.
- // Call this method when some pointers have changed and may be reusing
- // an id that was assigned to a different pointer earlier.
- void clearPointers(BitSet32 idBits);
-
- // Adds movement information for a set of pointers.
- // The idBits bitfield specifies the pointer ids of the pointers whose positions
- // are included in the movement.
- // The positions array contains position information for each pointer in order by
- // increasing id. Its size should be equal to the number of one bits in idBits.
- void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
-
- // Adds movement information for all pointers in a MotionEvent, including historical samples.
- void addMovement(const MotionEvent* event);
-
- // Gets the velocity of the specified pointer id in position units per second.
- // Returns false and sets the velocity components to zero if there is
- // insufficient movement information for the pointer.
- bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
-
- // Gets an estimator for the recent movements of the specified pointer id.
- // Returns false and clears the estimator if there is no information available
- // about the pointer.
- bool getEstimator(uint32_t id, Estimator* outEstimator) const;
-
- // Gets the active pointer id, or -1 if none.
- inline int32_t getActivePointerId() const { return mActivePointerId; }
-
- // Gets a bitset containing all pointer ids from the most recent movement.
- inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
-
-private:
- static const char* DEFAULT_STRATEGY;
-
- nsecs_t mLastEventTime;
- BitSet32 mCurrentPointerIdBits;
- int32_t mActivePointerId;
- VelocityTrackerStrategy* mStrategy;
-
- bool configureStrategy(const char* strategy);
-
- static VelocityTrackerStrategy* createStrategy(const char* strategy);
-};
-
-
-/*
- * Implements a particular velocity tracker algorithm.
- */
-class VelocityTrackerStrategy {
-protected:
- VelocityTrackerStrategy() { }
-
-public:
- virtual ~VelocityTrackerStrategy() { }
-
- virtual void clear() = 0;
- virtual void clearPointers(BitSet32 idBits) = 0;
- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions) = 0;
- virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
-};
-
-
-/*
- * Velocity tracker algorithm based on least-squares linear regression.
- */
-class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
- enum Weighting {
- // No weights applied. All data points are equally reliable.
- WEIGHTING_NONE,
-
- // Weight by time delta. Data points clustered together are weighted less.
- WEIGHTING_DELTA,
-
- // Weight such that points within a certain horizon are weighed more than those
- // outside of that horizon.
- WEIGHTING_CENTRAL,
-
- // Weight such that points older than a certain amount are weighed less.
- WEIGHTING_RECENT,
- };
-
- // Degree must be no greater than Estimator::MAX_DEGREE.
- LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
- virtual ~LeastSquaresVelocityTrackerStrategy();
-
- virtual void clear();
- virtual void clearPointers(BitSet32 idBits);
- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions);
- virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
- // Sample horizon.
- // We don't use too much history by default since we want to react to quick
- // changes in direction.
- static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
-
- // Number of samples to keep.
- static const uint32_t HISTORY_SIZE = 20;
-
- struct Movement {
- nsecs_t eventTime;
- BitSet32 idBits;
- VelocityTracker::Position positions[MAX_POINTERS];
-
- inline const VelocityTracker::Position& getPosition(uint32_t id) const {
- return positions[idBits.getIndexOfBit(id)];
- }
- };
-
- float chooseWeight(uint32_t index) const;
-
- const uint32_t mDegree;
- const Weighting mWeighting;
- uint32_t mIndex;
- Movement mMovements[HISTORY_SIZE];
-};
-
-
-/*
- * Velocity tracker algorithm that uses an IIR filter.
- */
-class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
- // Degree must be 1 or 2.
- IntegratingVelocityTrackerStrategy(uint32_t degree);
- ~IntegratingVelocityTrackerStrategy();
-
- virtual void clear();
- virtual void clearPointers(BitSet32 idBits);
- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions);
- virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
- // Current state estimate for a particular pointer.
- struct State {
- nsecs_t updateTime;
- uint32_t degree;
-
- float xpos, xvel, xaccel;
- float ypos, yvel, yaccel;
- };
-
- const uint32_t mDegree;
- BitSet32 mPointerIdBits;
- State mPointerState[MAX_POINTER_ID + 1];
-
- void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
- void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
- void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
-};
-
-
-/*
- * Velocity tracker strategy used prior to ICS.
- */
-class LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
-public:
- LegacyVelocityTrackerStrategy();
- virtual ~LegacyVelocityTrackerStrategy();
-
- virtual void clear();
- virtual void clearPointers(BitSet32 idBits);
- virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
- const VelocityTracker::Position* positions);
- virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
-
-private:
- // Oldest sample to consider when calculating the velocity.
- static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
-
- // Number of samples to keep.
- static const uint32_t HISTORY_SIZE = 20;
-
- // The minimum duration between samples when estimating velocity.
- static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
-
- struct Movement {
- nsecs_t eventTime;
- BitSet32 idBits;
- VelocityTracker::Position positions[MAX_POINTERS];
-
- inline const VelocityTracker::Position& getPosition(uint32_t id) const {
- return positions[idBits.getIndexOfBit(id)];
- }
- };
-
- uint32_t mIndex;
- Movement mMovements[HISTORY_SIZE];
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_VELOCITY_TRACKER_H
diff --git a/widget/gonk/libui/VirtualKeyMap.cpp b/widget/gonk/libui/VirtualKeyMap.cpp
deleted file mode 100644
index 444ab3718..000000000
--- a/widget/gonk/libui/VirtualKeyMap.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VirtualKeyMap"
-#include "cutils_log.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include "VirtualKeyMap.h"
-#include <utils/Errors.h>
-#include "Tokenizer.h"
-#include <utils/Timers.h>
-
-// Enables debug output for the parser.
-#define DEBUG_PARSER 0
-
-// Enables debug output for parser performance.
-#define DEBUG_PARSER_PERFORMANCE 0
-
-
-namespace android {
-
-static const char* WHITESPACE = " \t\r";
-static const char* WHITESPACE_OR_FIELD_DELIMITER = " \t\r:";
-
-
-// --- VirtualKeyMap ---
-
-VirtualKeyMap::VirtualKeyMap() {
-}
-
-VirtualKeyMap::~VirtualKeyMap() {
-}
-
-status_t VirtualKeyMap::load(const String8& filename, VirtualKeyMap** outMap) {
- *outMap = NULL;
-
- Tokenizer* tokenizer;
- status_t status = Tokenizer::open(filename, &tokenizer);
- if (status) {
- ALOGE("Error %d opening virtual key map file %s.", status, filename.string());
- } else {
- VirtualKeyMap* map = new VirtualKeyMap();
- if (!map) {
- ALOGE("Error allocating virtual key map.");
- status = NO_MEMORY;
- } else {
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t startTime = systemTime(SYSTEM_TIME_MONOTONIC);
-#endif
- Parser parser(map, tokenizer);
- status = parser.parse();
-#if DEBUG_PARSER_PERFORMANCE
- nsecs_t elapsedTime = systemTime(SYSTEM_TIME_MONOTONIC) - startTime;
- ALOGD("Parsed key character map file '%s' %d lines in %0.3fms.",
- tokenizer->getFilename().string(), tokenizer->getLineNumber(),
- elapsedTime / 1000000.0);
-#endif
- if (status) {
- delete map;
- } else {
- *outMap = map;
- }
- }
- delete tokenizer;
- }
- return status;
-}
-
-
-// --- VirtualKeyMap::Parser ---
-
-VirtualKeyMap::Parser::Parser(VirtualKeyMap* map, Tokenizer* tokenizer) :
- mMap(map), mTokenizer(tokenizer) {
-}
-
-VirtualKeyMap::Parser::~Parser() {
-}
-
-status_t VirtualKeyMap::Parser::parse() {
- while (!mTokenizer->isEof()) {
-#if DEBUG_PARSER
- ALOGD("Parsing %s: '%s'.", mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
-#endif
-
- mTokenizer->skipDelimiters(WHITESPACE);
-
- if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
- // Multiple keys can appear on one line or they can be broken up across multiple lines.
- do {
- String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
- if (token != "0x01") {
- ALOGE("%s: Unknown virtual key type, expected 0x01.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
- VirtualKeyDefinition defn;
- bool success = parseNextIntField(&defn.scanCode)
- && parseNextIntField(&defn.centerX)
- && parseNextIntField(&defn.centerY)
- && parseNextIntField(&defn.width)
- && parseNextIntField(&defn.height);
- if (!success) {
- ALOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
-
-#if DEBUG_PARSER
- ALOGD("Parsed virtual key: scanCode=%d, centerX=%d, centerY=%d, "
- "width=%d, height=%d",
- defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height);
-#endif
- mMap->mVirtualKeys.push(defn);
- } while (consumeFieldDelimiterAndSkipWhitespace());
-
- if (!mTokenizer->isEol()) {
- ALOGE("%s: Expected end of line, got '%s'.",
- mTokenizer->getLocation().string(),
- mTokenizer->peekRemainderOfLine().string());
- return BAD_VALUE;
- }
- }
-
- mTokenizer->nextLine();
- }
-
- return NO_ERROR;
-}
-
-bool VirtualKeyMap::Parser::consumeFieldDelimiterAndSkipWhitespace() {
- mTokenizer->skipDelimiters(WHITESPACE);
- if (mTokenizer->peekChar() == ':') {
- mTokenizer->nextChar();
- mTokenizer->skipDelimiters(WHITESPACE);
- return true;
- }
- return false;
-}
-
-bool VirtualKeyMap::Parser::parseNextIntField(int32_t* outValue) {
- if (!consumeFieldDelimiterAndSkipWhitespace()) {
- return false;
- }
-
- String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
- char* end;
- *outValue = strtol(token.string(), &end, 0);
- if (token.isEmpty() || *end != '\0') {
- ALOGE("Expected an integer, got '%s'.", token.string());
- return false;
- }
- return true;
-}
-
-} // namespace android
diff --git a/widget/gonk/libui/VirtualKeyMap.h b/widget/gonk/libui/VirtualKeyMap.h
deleted file mode 100644
index 79d61a536..000000000
--- a/widget/gonk/libui/VirtualKeyMap.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROIDFW_VIRTUAL_KEY_MAP_H
-#define _ANDROIDFW_VIRTUAL_KEY_MAP_H
-
-#include <stdint.h>
-
-#include "Input.h"
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
-#include "Tokenizer.h"
-#include <utils/String8.h>
-#include <utils/Unicode.h>
-
-namespace android {
-
-/* Describes a virtual key. */
-struct VirtualKeyDefinition {
- int32_t scanCode;
-
- // configured position data, specified in display coords
- int32_t centerX;
- int32_t centerY;
- int32_t width;
- int32_t height;
-};
-
-
-/**
- * Describes a collection of virtual keys on a touch screen in terms of
- * virtual scan codes and hit rectangles.
- *
- * This object is immutable after it has been loaded.
- */
-class VirtualKeyMap {
-public:
- ~VirtualKeyMap();
-
- static status_t load(const String8& filename, VirtualKeyMap** outMap);
-
- inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const {
- return mVirtualKeys;
- }
-
-private:
- class Parser {
- VirtualKeyMap* mMap;
- Tokenizer* mTokenizer;
-
- public:
- Parser(VirtualKeyMap* map, Tokenizer* tokenizer);
- ~Parser();
- status_t parse();
-
- private:
- bool consumeFieldDelimiterAndSkipWhitespace();
- bool parseNextIntField(int32_t* outValue);
- };
-
- Vector<VirtualKeyDefinition> mVirtualKeys;
-
- VirtualKeyMap();
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/widget/gonk/libui/android_input.h b/widget/gonk/libui/android_input.h
deleted file mode 100644
index 00e81b28d..000000000
--- a/widget/gonk/libui/android_input.h
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_INPUT_H
-#define _ANDROID_INPUT_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit).
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-/*
- * Structures and functions to receive and process input events in
- * native code.
- *
- * NOTE: These functions MUST be implemented by /system/lib/libui.so
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-#include "android_keycodes.h"
-#include <android/looper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key states (may be returned by queries about the current state of a
- * particular key code, scan code or switch).
- */
-enum {
- /* The key state is unknown or the requested key itself is not supported. */
- AKEY_STATE_UNKNOWN = -1,
-
- /* The key is up. */
- AKEY_STATE_UP = 0,
-
- /* The key is down. */
- AKEY_STATE_DOWN = 1,
-
- /* The key is down but is a virtual key press that is being emulated by the system. */
- AKEY_STATE_VIRTUAL = 2
-};
-
-/*
- * Meta key / modifer state.
- */
-enum {
- /* No meta keys are pressed. */
- AMETA_NONE = 0,
-
- /* This mask is used to check whether one of the ALT meta keys is pressed. */
- AMETA_ALT_ON = 0x02,
-
- /* This mask is used to check whether the left ALT meta key is pressed. */
- AMETA_ALT_LEFT_ON = 0x10,
-
- /* This mask is used to check whether the right ALT meta key is pressed. */
- AMETA_ALT_RIGHT_ON = 0x20,
-
- /* This mask is used to check whether one of the SHIFT meta keys is pressed. */
- AMETA_SHIFT_ON = 0x01,
-
- /* This mask is used to check whether the left SHIFT meta key is pressed. */
- AMETA_SHIFT_LEFT_ON = 0x40,
-
- /* This mask is used to check whether the right SHIFT meta key is pressed. */
- AMETA_SHIFT_RIGHT_ON = 0x80,
-
- /* This mask is used to check whether the SYM meta key is pressed. */
- AMETA_SYM_ON = 0x04,
-
- /* This mask is used to check whether the FUNCTION meta key is pressed. */
- AMETA_FUNCTION_ON = 0x08,
-
- /* This mask is used to check whether one of the CTRL meta keys is pressed. */
- AMETA_CTRL_ON = 0x1000,
-
- /* This mask is used to check whether the left CTRL meta key is pressed. */
- AMETA_CTRL_LEFT_ON = 0x2000,
-
- /* This mask is used to check whether the right CTRL meta key is pressed. */
- AMETA_CTRL_RIGHT_ON = 0x4000,
-
- /* This mask is used to check whether one of the META meta keys is pressed. */
- AMETA_META_ON = 0x10000,
-
- /* This mask is used to check whether the left META meta key is pressed. */
- AMETA_META_LEFT_ON = 0x20000,
-
- /* This mask is used to check whether the right META meta key is pressed. */
- AMETA_META_RIGHT_ON = 0x40000,
-
- /* This mask is used to check whether the CAPS LOCK meta key is on. */
- AMETA_CAPS_LOCK_ON = 0x100000,
-
- /* This mask is used to check whether the NUM LOCK meta key is on. */
- AMETA_NUM_LOCK_ON = 0x200000,
-
- /* This mask is used to check whether the SCROLL LOCK meta key is on. */
- AMETA_SCROLL_LOCK_ON = 0x400000,
-};
-
-/*
- * Input events.
- *
- * Input events are opaque structures. Use the provided accessors functions to
- * read their properties.
- */
-struct AInputEvent;
-typedef struct AInputEvent AInputEvent;
-
-/*
- * Input event types.
- */
-enum {
- /* Indicates that the input event is a key event. */
- AINPUT_EVENT_TYPE_KEY = 1,
-
- /* Indicates that the input event is a motion event. */
- AINPUT_EVENT_TYPE_MOTION = 2
-};
-
-/*
- * Key event actions.
- */
-enum {
- /* The key has been pressed down. */
- AKEY_EVENT_ACTION_DOWN = 0,
-
- /* The key has been released. */
- AKEY_EVENT_ACTION_UP = 1,
-
- /* Multiple duplicate key events have occurred in a row, or a complex string is
- * being delivered. The repeat_count property of the key event contains the number
- * of times the given key code should be executed.
- */
- AKEY_EVENT_ACTION_MULTIPLE = 2
-};
-
-/*
- * Key event flags.
- */
-enum {
- /* This mask is set if the device woke because of this key event. */
- AKEY_EVENT_FLAG_WOKE_HERE = 0x1,
-
- /* This mask is set if the key event was generated by a software keyboard. */
- AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
-
- /* This mask is set if we don't want the key event to cause us to leave touch mode. */
- AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
-
- /* This mask is set if an event was known to come from a trusted part
- * of the system. That is, the event is known to come from the user,
- * and could not have been spoofed by a third party component. */
- AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
-
- /* This mask is used for compatibility, to identify enter keys that are
- * coming from an IME whose enter key has been auto-labelled "next" or
- * "done". This allows TextView to dispatch these as normal enter keys
- * for old applications, but still do the appropriate action when
- * receiving them. */
- AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
-
- /* When associated with up key events, this indicates that the key press
- * has been canceled. Typically this is used with virtual touch screen
- * keys, where the user can slide from the virtual key area on to the
- * display: in that case, the application will receive a canceled up
- * event and should not perform the action normally associated with the
- * key. Note that for this to work, the application can not perform an
- * action for a key until it receives an up or the long press timeout has
- * expired. */
- AKEY_EVENT_FLAG_CANCELED = 0x20,
-
- /* This key event was generated by a virtual (on-screen) hard key area.
- * Typically this is an area of the touchscreen, outside of the regular
- * display, dedicated to "hardware" buttons. */
- AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
-
- /* This flag is set for the first key repeat that occurs after the
- * long press timeout. */
- AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
-
- /* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long
- * press action was executed while it was down. */
- AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
-
- /* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
- * tracked from its initial down. That is, somebody requested that tracking
- * started on the key down and a long press has not caused
- * the tracking to be canceled. */
- AKEY_EVENT_FLAG_TRACKING = 0x200,
-
- /* Set when a key event has been synthesized to implement default behavior
- * for an event that the application did not handle.
- * Fallback key events are generated by unhandled trackball motions
- * (to emulate a directional keypad) and by certain unhandled key presses
- * that are declared in the key map (such as special function numeric keypad
- * keys when numlock is off). */
- AKEY_EVENT_FLAG_FALLBACK = 0x400,
-};
-
-/*
- * Motion event actions.
- */
-
-/* Bit shift for the action bits holding the pointer index as
- * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.
- */
-#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
-
-enum {
- /* Bit mask of the parts of the action code that are the action itself.
- */
- AMOTION_EVENT_ACTION_MASK = 0xff,
-
- /* Bits in the action code that represent a pointer index, used with
- * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP. Shifting
- * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
- * index where the data for the pointer going up or down can be found.
- */
- AMOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00,
-
- /* A pressed gesture has started, the motion contains the initial starting location.
- */
- AMOTION_EVENT_ACTION_DOWN = 0,
-
- /* A pressed gesture has finished, the motion contains the final release location
- * as well as any intermediate points since the last down or move event.
- */
- AMOTION_EVENT_ACTION_UP = 1,
-
- /* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
- * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as
- * any intermediate points since the last down or move event.
- */
- AMOTION_EVENT_ACTION_MOVE = 2,
-
- /* The current gesture has been aborted.
- * You will not receive any more points in it. You should treat this as
- * an up event, but not perform any action that you normally would.
- */
- AMOTION_EVENT_ACTION_CANCEL = 3,
-
- /* A movement has happened outside of the normal bounds of the UI element.
- * This does not provide a full gesture, but only the initial location of the movement/touch.
- */
- AMOTION_EVENT_ACTION_OUTSIDE = 4,
-
- /* A non-primary pointer has gone down.
- * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
- */
- AMOTION_EVENT_ACTION_POINTER_DOWN = 5,
-
- /* A non-primary pointer has gone up.
- * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
- */
- AMOTION_EVENT_ACTION_POINTER_UP = 6,
-
- /* A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
- * The motion contains the most recent point, as well as any intermediate points since
- * the last hover move event.
- */
- AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
-
- /* The motion event contains relative vertical and/or horizontal scroll offsets.
- * Use getAxisValue to retrieve the information from AMOTION_EVENT_AXIS_VSCROLL
- * and AMOTION_EVENT_AXIS_HSCROLL.
- * The pointer may or may not be down when this event is dispatched.
- * This action is always delivered to the winder under the pointer, which
- * may not be the window currently touched.
- */
- AMOTION_EVENT_ACTION_SCROLL = 8,
-
- /* The pointer is not down but has entered the boundaries of a window or view.
- */
- AMOTION_EVENT_ACTION_HOVER_ENTER = 9,
-
- /* The pointer is not down but has exited the boundaries of a window or view.
- */
- AMOTION_EVENT_ACTION_HOVER_EXIT = 10,
-};
-
-/*
- * Motion event flags.
- */
-enum {
- /* This flag indicates that the window that received this motion event is partly
- * or wholly obscured by another visible window above it. This flag is set to true
- * even if the event did not directly pass through the obscured area.
- * A security sensitive application can check this flag to identify situations in which
- * a malicious application may have covered up part of its content for the purpose
- * of misleading the user or hijacking touches. An appropriate response might be
- * to drop the suspect touches or to take additional precautions to confirm the user's
- * actual intent.
- */
- AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,
-};
-
-/*
- * Motion event edge touch flags.
- */
-enum {
- /* No edges intersected */
- AMOTION_EVENT_EDGE_FLAG_NONE = 0,
-
- /* Flag indicating the motion event intersected the top edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,
-
- /* Flag indicating the motion event intersected the bottom edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
-
- /* Flag indicating the motion event intersected the left edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
-
- /* Flag indicating the motion event intersected the right edge of the screen. */
- AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
-};
-
-/*
- * Constants that identify each individual axis of a motion event.
- * Refer to the documentation on the MotionEvent class for descriptions of each axis.
- */
-enum {
- AMOTION_EVENT_AXIS_X = 0,
- AMOTION_EVENT_AXIS_Y = 1,
- AMOTION_EVENT_AXIS_PRESSURE = 2,
- AMOTION_EVENT_AXIS_SIZE = 3,
- AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,
- AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,
- AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,
- AMOTION_EVENT_AXIS_TOOL_MINOR = 7,
- AMOTION_EVENT_AXIS_ORIENTATION = 8,
- AMOTION_EVENT_AXIS_VSCROLL = 9,
- AMOTION_EVENT_AXIS_HSCROLL = 10,
- AMOTION_EVENT_AXIS_Z = 11,
- AMOTION_EVENT_AXIS_RX = 12,
- AMOTION_EVENT_AXIS_RY = 13,
- AMOTION_EVENT_AXIS_RZ = 14,
- AMOTION_EVENT_AXIS_HAT_X = 15,
- AMOTION_EVENT_AXIS_HAT_Y = 16,
- AMOTION_EVENT_AXIS_LTRIGGER = 17,
- AMOTION_EVENT_AXIS_RTRIGGER = 18,
- AMOTION_EVENT_AXIS_THROTTLE = 19,
- AMOTION_EVENT_AXIS_RUDDER = 20,
- AMOTION_EVENT_AXIS_WHEEL = 21,
- AMOTION_EVENT_AXIS_GAS = 22,
- AMOTION_EVENT_AXIS_BRAKE = 23,
- AMOTION_EVENT_AXIS_DISTANCE = 24,
- AMOTION_EVENT_AXIS_TILT = 25,
- AMOTION_EVENT_AXIS_GENERIC_1 = 32,
- AMOTION_EVENT_AXIS_GENERIC_2 = 33,
- AMOTION_EVENT_AXIS_GENERIC_3 = 34,
- AMOTION_EVENT_AXIS_GENERIC_4 = 35,
- AMOTION_EVENT_AXIS_GENERIC_5 = 36,
- AMOTION_EVENT_AXIS_GENERIC_6 = 37,
- AMOTION_EVENT_AXIS_GENERIC_7 = 38,
- AMOTION_EVENT_AXIS_GENERIC_8 = 39,
- AMOTION_EVENT_AXIS_GENERIC_9 = 40,
- AMOTION_EVENT_AXIS_GENERIC_10 = 41,
- AMOTION_EVENT_AXIS_GENERIC_11 = 42,
- AMOTION_EVENT_AXIS_GENERIC_12 = 43,
- AMOTION_EVENT_AXIS_GENERIC_13 = 44,
- AMOTION_EVENT_AXIS_GENERIC_14 = 45,
- AMOTION_EVENT_AXIS_GENERIC_15 = 46,
- AMOTION_EVENT_AXIS_GENERIC_16 = 47,
-
- // NOTE: If you add a new axis here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
-};
-
-/*
- * Constants that identify buttons that are associated with motion events.
- * Refer to the documentation on the MotionEvent class for descriptions of each button.
- */
-enum {
- AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0,
- AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1,
- AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2,
- AMOTION_EVENT_BUTTON_BACK = 1 << 3,
- AMOTION_EVENT_BUTTON_FORWARD = 1 << 4,
-};
-
-/*
- * Constants that identify tool types.
- * Refer to the documentation on the MotionEvent class for descriptions of each tool type.
- */
-enum {
- AMOTION_EVENT_TOOL_TYPE_UNKNOWN = 0,
- AMOTION_EVENT_TOOL_TYPE_FINGER = 1,
- AMOTION_EVENT_TOOL_TYPE_STYLUS = 2,
- AMOTION_EVENT_TOOL_TYPE_MOUSE = 3,
- AMOTION_EVENT_TOOL_TYPE_ERASER = 4,
-};
-
-/*
- * Input sources.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- */
-enum {
- AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
-
- AINPUT_SOURCE_CLASS_NONE = 0x00000000,
- AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
- AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
- AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
- AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
- AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010,
-};
-
-enum {
- AINPUT_SOURCE_UNKNOWN = 0x00000000,
-
- AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
- AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
- AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
- AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
- AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
- AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
-
- AINPUT_SOURCE_ANY = 0xffffff00,
-};
-
-/*
- * Keyboard types.
- *
- * Refer to the documentation on android.view.InputDevice for more details.
- */
-enum {
- AINPUT_KEYBOARD_TYPE_NONE = 0,
- AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
- AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
-};
-
-/*
- * Constants used to retrieve information about the range of motion for a particular
- * coordinate of a motion event.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- *
- * DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
- */
-enum {
- AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
- AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
- AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
- AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
- AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
- AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
- AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
- AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
- AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,
-} __attribute__ ((deprecated));
-
-
-/*
- * Input event accessors.
- *
- * Note that most functions can only be used on input events that are of a given type.
- * Calling these functions on input events of other types will yield undefined behavior.
- */
-
-/*** Accessors for all input events. ***/
-
-/* Get the input event type. */
-int32_t AInputEvent_getType(const AInputEvent* event);
-
-/* Get the id for the device that an input event came from.
- *
- * Input events can be generated by multiple different input devices.
- * Use the input device id to obtain information about the input
- * device that was responsible for generating a particular event.
- *
- * An input device id of 0 indicates that the event didn't come from a physical device;
- * other numbers are arbitrary and you shouldn't depend on the values.
- * Use the provided input device query API to obtain information about input devices.
- */
-int32_t AInputEvent_getDeviceId(const AInputEvent* event);
-
-/* Get the input event source. */
-int32_t AInputEvent_getSource(const AInputEvent* event);
-
-/*** Accessors for key events only. ***/
-
-/* Get the key event action. */
-int32_t AKeyEvent_getAction(const AInputEvent* key_event);
-
-/* Get the key event flags. */
-int32_t AKeyEvent_getFlags(const AInputEvent* key_event);
-
-/* Get the key code of the key event.
- * This is the physical key that was pressed, not the Unicode character. */
-int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);
-
-/* Get the hardware key id of this key event.
- * These values are not reliable and vary from device to device. */
-int32_t AKeyEvent_getScanCode(const AInputEvent* key_event);
-
-/* Get the meta key state. */
-int32_t AKeyEvent_getMetaState(const AInputEvent* key_event);
-
-/* Get the repeat count of the event.
- * For both key up an key down events, this is the number of times the key has
- * repeated with the first down starting at 0 and counting up from there. For
- * multiple key events, this is the number of down/up pairs that have occurred. */
-int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);
-
-/* Get the time of the most recent key down event, in the
- * java.lang.System.nanoTime() time base. If this is a down event,
- * this will be the same as eventTime.
- * Note that when chording keys, this value is the down time of the most recently
- * pressed key, which may not be the same physical key of this event. */
-int64_t AKeyEvent_getDownTime(const AInputEvent* key_event);
-
-/* Get the time this event occurred, in the
- * java.lang.System.nanoTime() time base. */
-int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
-
-/*** Accessors for motion events only. ***/
-
-/* Get the combined motion event action code and pointer index. */
-int32_t AMotionEvent_getAction(const AInputEvent* motion_event);
-
-/* Get the motion event flags. */
-int32_t AMotionEvent_getFlags(const AInputEvent* motion_event);
-
-/* Get the state of any meta / modifier keys that were in effect when the
- * event was generated. */
-int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);
-
-/* Get the button state of all buttons that are pressed. */
-int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event);
-
-/* Get a bitfield indicating which edges, if any, were touched by this motion event.
- * For touch events, clients can use this to determine if the user's finger was
- * touching the edge of the display. */
-int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);
-
-/* Get the time when the user originally pressed down to start a stream of
- * position events, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);
-
-/* Get the time when this specific event was generated,
- * in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);
-
-/* Get the X coordinate offset.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getXOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getYOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the X coordinates being reported.
- * You can multiply this number with an X coordinate sample to find the
- * actual hardware value of the X coordinate. */
-float AMotionEvent_getXPrecision(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * You can multiply this number with a Y coordinate sample to find the
- * actual hardware value of the Y coordinate. */
-float AMotionEvent_getYPrecision(const AInputEvent* motion_event);
-
-/* Get the number of pointers of data contained in this event.
- * Always >= 1. */
-size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);
-
-/* Get the pointer identifier associated with a particular pointer
- * data index in this event. The identifier tells you the actual pointer
- * number associated with the data, accounting for individual pointers
- * going up and down since the start of the current gesture. */
-int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the tool type of a pointer for the given pointer index.
- * The tool type indicates the type of tool used to make contact such as a
- * finger or stylus, if known. */
-int32_t AMotionEvent_getToolType(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current X coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current Y coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current pressure of this event for the given pointer index.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * although values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation. A positive angle
- * indicates that the major axis of contact is oriented to the right. A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the value of the request axis for the given pointer index. */
-float AMotionEvent_getAxisValue(const AInputEvent* motion_event,
- int32_t axis, size_t pointer_index);
-
-/* Get the number of historical points in this event. These are movements that
- * have occurred between this event and the previous event. This only applies
- * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
- * Historical samples are indexed from oldest to newest. */
-size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);
-
-/* Get the time that a historical movement occurred between this event and
- * the previous event, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
- size_t history_index);
-
-/* Get the historical raw X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical raw Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical pressure of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * although values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index that
- * occurred between this event and the previous motion event.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index that
- * occurred between this event and the previous motion event.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation. A positive angle
- * indicates that the major axis of contact is oriented to the right. A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
- size_t history_index);
-
-/* Get the historical value of the request axis for the given pointer index
- * that occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
- int32_t axis, size_t pointer_index, size_t history_index);
-
-
-/*
- * Input queue
- *
- * An input queue is the facility through which you retrieve input
- * events.
- */
-struct AInputQueue;
-typedef struct AInputQueue AInputQueue;
-
-/*
- * Add this input queue to a looper for processing. See
- * ALooper_addFd() for information on the ident, callback, and data params.
- */
-void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
- int ident, ALooper_callbackFunc callback, void* data);
-
-/*
- * Remove the input queue from the looper it is currently attached to.
- */
-void AInputQueue_detachLooper(AInputQueue* queue);
-
-/*
- * Returns true if there are one or more events available in the
- * input queue. Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
- */
-int32_t AInputQueue_hasEvents(AInputQueue* queue);
-
-/*
- * Returns the next available event from the queue. Returns a negative
- * value if no events are available or an error has occurred.
- */
-int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);
-
-/*
- * Sends the key for standard pre-dispatching -- that is, possibly deliver
- * it to the current IME to be consumed before the app. Returns 0 if it
- * was not pre-dispatched, meaning you can process it right now. If non-zero
- * is returned, you must abandon the current event processing and allow the
- * event to appear again in the event queue (if it does not get consumed during
- * pre-dispatching).
- */
-int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
-
-/*
- * Report that dispatching has finished with the given event.
- * This must be called after receiving an event with AInputQueue_get_event().
- */
-void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_INPUT_H
diff --git a/widget/gonk/libui/android_keycodes.h b/widget/gonk/libui/android_keycodes.h
deleted file mode 100644
index 9e63d1d01..000000000
--- a/widget/gonk/libui/android_keycodes.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_KEYCODES_H
-#define _ANDROID_KEYCODES_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit).
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key codes.
- */
-enum {
- AKEYCODE_UNKNOWN = 0,
- AKEYCODE_SOFT_LEFT = 1,
- AKEYCODE_SOFT_RIGHT = 2,
- AKEYCODE_HOME = 3,
- AKEYCODE_BACK = 4,
- AKEYCODE_CALL = 5,
- AKEYCODE_ENDCALL = 6,
- AKEYCODE_0 = 7,
- AKEYCODE_1 = 8,
- AKEYCODE_2 = 9,
- AKEYCODE_3 = 10,
- AKEYCODE_4 = 11,
- AKEYCODE_5 = 12,
- AKEYCODE_6 = 13,
- AKEYCODE_7 = 14,
- AKEYCODE_8 = 15,
- AKEYCODE_9 = 16,
- AKEYCODE_STAR = 17,
- AKEYCODE_POUND = 18,
- AKEYCODE_DPAD_UP = 19,
- AKEYCODE_DPAD_DOWN = 20,
- AKEYCODE_DPAD_LEFT = 21,
- AKEYCODE_DPAD_RIGHT = 22,
- AKEYCODE_DPAD_CENTER = 23,
- AKEYCODE_VOLUME_UP = 24,
- AKEYCODE_VOLUME_DOWN = 25,
- AKEYCODE_POWER = 26,
- AKEYCODE_CAMERA = 27,
- AKEYCODE_CLEAR = 28,
- AKEYCODE_A = 29,
- AKEYCODE_B = 30,
- AKEYCODE_C = 31,
- AKEYCODE_D = 32,
- AKEYCODE_E = 33,
- AKEYCODE_F = 34,
- AKEYCODE_G = 35,
- AKEYCODE_H = 36,
- AKEYCODE_I = 37,
- AKEYCODE_J = 38,
- AKEYCODE_K = 39,
- AKEYCODE_L = 40,
- AKEYCODE_M = 41,
- AKEYCODE_N = 42,
- AKEYCODE_O = 43,
- AKEYCODE_P = 44,
- AKEYCODE_Q = 45,
- AKEYCODE_R = 46,
- AKEYCODE_S = 47,
- AKEYCODE_T = 48,
- AKEYCODE_U = 49,
- AKEYCODE_V = 50,
- AKEYCODE_W = 51,
- AKEYCODE_X = 52,
- AKEYCODE_Y = 53,
- AKEYCODE_Z = 54,
- AKEYCODE_COMMA = 55,
- AKEYCODE_PERIOD = 56,
- AKEYCODE_ALT_LEFT = 57,
- AKEYCODE_ALT_RIGHT = 58,
- AKEYCODE_SHIFT_LEFT = 59,
- AKEYCODE_SHIFT_RIGHT = 60,
- AKEYCODE_TAB = 61,
- AKEYCODE_SPACE = 62,
- AKEYCODE_SYM = 63,
- AKEYCODE_EXPLORER = 64,
- AKEYCODE_ENVELOPE = 65,
- AKEYCODE_ENTER = 66,
- AKEYCODE_DEL = 67,
- AKEYCODE_GRAVE = 68,
- AKEYCODE_MINUS = 69,
- AKEYCODE_EQUALS = 70,
- AKEYCODE_LEFT_BRACKET = 71,
- AKEYCODE_RIGHT_BRACKET = 72,
- AKEYCODE_BACKSLASH = 73,
- AKEYCODE_SEMICOLON = 74,
- AKEYCODE_APOSTROPHE = 75,
- AKEYCODE_SLASH = 76,
- AKEYCODE_AT = 77,
- AKEYCODE_NUM = 78,
- AKEYCODE_HEADSETHOOK = 79,
- AKEYCODE_FOCUS = 80, // *Camera* focus
- AKEYCODE_PLUS = 81,
- AKEYCODE_MENU = 82,
- AKEYCODE_NOTIFICATION = 83,
- AKEYCODE_SEARCH = 84,
- AKEYCODE_MEDIA_PLAY_PAUSE= 85,
- AKEYCODE_MEDIA_STOP = 86,
- AKEYCODE_MEDIA_NEXT = 87,
- AKEYCODE_MEDIA_PREVIOUS = 88,
- AKEYCODE_MEDIA_REWIND = 89,
- AKEYCODE_MEDIA_FAST_FORWARD = 90,
- AKEYCODE_MUTE = 91,
- AKEYCODE_PAGE_UP = 92,
- AKEYCODE_PAGE_DOWN = 93,
- AKEYCODE_PICTSYMBOLS = 94,
- AKEYCODE_SWITCH_CHARSET = 95,
- AKEYCODE_BUTTON_A = 96,
- AKEYCODE_BUTTON_B = 97,
- AKEYCODE_BUTTON_C = 98,
- AKEYCODE_BUTTON_X = 99,
- AKEYCODE_BUTTON_Y = 100,
- AKEYCODE_BUTTON_Z = 101,
- AKEYCODE_BUTTON_L1 = 102,
- AKEYCODE_BUTTON_R1 = 103,
- AKEYCODE_BUTTON_L2 = 104,
- AKEYCODE_BUTTON_R2 = 105,
- AKEYCODE_BUTTON_THUMBL = 106,
- AKEYCODE_BUTTON_THUMBR = 107,
- AKEYCODE_BUTTON_START = 108,
- AKEYCODE_BUTTON_SELECT = 109,
- AKEYCODE_BUTTON_MODE = 110,
- AKEYCODE_ESCAPE = 111,
- AKEYCODE_FORWARD_DEL = 112,
- AKEYCODE_CTRL_LEFT = 113,
- AKEYCODE_CTRL_RIGHT = 114,
- AKEYCODE_CAPS_LOCK = 115,
- AKEYCODE_SCROLL_LOCK = 116,
- AKEYCODE_META_LEFT = 117,
- AKEYCODE_META_RIGHT = 118,
- AKEYCODE_FUNCTION = 119,
- AKEYCODE_SYSRQ = 120,
- AKEYCODE_BREAK = 121,
- AKEYCODE_MOVE_HOME = 122,
- AKEYCODE_MOVE_END = 123,
- AKEYCODE_INSERT = 124,
- AKEYCODE_FORWARD = 125,
- AKEYCODE_MEDIA_PLAY = 126,
- AKEYCODE_MEDIA_PAUSE = 127,
- AKEYCODE_MEDIA_CLOSE = 128,
- AKEYCODE_MEDIA_EJECT = 129,
- AKEYCODE_MEDIA_RECORD = 130,
- AKEYCODE_F1 = 131,
- AKEYCODE_F2 = 132,
- AKEYCODE_F3 = 133,
- AKEYCODE_F4 = 134,
- AKEYCODE_F5 = 135,
- AKEYCODE_F6 = 136,
- AKEYCODE_F7 = 137,
- AKEYCODE_F8 = 138,
- AKEYCODE_F9 = 139,
- AKEYCODE_F10 = 140,
- AKEYCODE_F11 = 141,
- AKEYCODE_F12 = 142,
- AKEYCODE_NUM_LOCK = 143,
- AKEYCODE_NUMPAD_0 = 144,
- AKEYCODE_NUMPAD_1 = 145,
- AKEYCODE_NUMPAD_2 = 146,
- AKEYCODE_NUMPAD_3 = 147,
- AKEYCODE_NUMPAD_4 = 148,
- AKEYCODE_NUMPAD_5 = 149,
- AKEYCODE_NUMPAD_6 = 150,
- AKEYCODE_NUMPAD_7 = 151,
- AKEYCODE_NUMPAD_8 = 152,
- AKEYCODE_NUMPAD_9 = 153,
- AKEYCODE_NUMPAD_DIVIDE = 154,
- AKEYCODE_NUMPAD_MULTIPLY = 155,
- AKEYCODE_NUMPAD_SUBTRACT = 156,
- AKEYCODE_NUMPAD_ADD = 157,
- AKEYCODE_NUMPAD_DOT = 158,
- AKEYCODE_NUMPAD_COMMA = 159,
- AKEYCODE_NUMPAD_ENTER = 160,
- AKEYCODE_NUMPAD_EQUALS = 161,
- AKEYCODE_NUMPAD_LEFT_PAREN = 162,
- AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
- AKEYCODE_VOLUME_MUTE = 164,
- AKEYCODE_INFO = 165,
- AKEYCODE_CHANNEL_UP = 166,
- AKEYCODE_CHANNEL_DOWN = 167,
- AKEYCODE_ZOOM_IN = 168,
- AKEYCODE_ZOOM_OUT = 169,
- AKEYCODE_TV = 170,
- AKEYCODE_WINDOW = 171,
- AKEYCODE_GUIDE = 172,
- AKEYCODE_DVR = 173,
- AKEYCODE_BOOKMARK = 174,
- AKEYCODE_CAPTIONS = 175,
- AKEYCODE_SETTINGS = 176,
- AKEYCODE_TV_POWER = 177,
- AKEYCODE_TV_INPUT = 178,
- AKEYCODE_STB_POWER = 179,
- AKEYCODE_STB_INPUT = 180,
- AKEYCODE_AVR_POWER = 181,
- AKEYCODE_AVR_INPUT = 182,
- AKEYCODE_PROG_RED = 183,
- AKEYCODE_PROG_GREEN = 184,
- AKEYCODE_PROG_YELLOW = 185,
- AKEYCODE_PROG_BLUE = 186,
- AKEYCODE_APP_SWITCH = 187,
- AKEYCODE_BUTTON_1 = 188,
- AKEYCODE_BUTTON_2 = 189,
- AKEYCODE_BUTTON_3 = 190,
- AKEYCODE_BUTTON_4 = 191,
- AKEYCODE_BUTTON_5 = 192,
- AKEYCODE_BUTTON_6 = 193,
- AKEYCODE_BUTTON_7 = 194,
- AKEYCODE_BUTTON_8 = 195,
- AKEYCODE_BUTTON_9 = 196,
- AKEYCODE_BUTTON_10 = 197,
- AKEYCODE_BUTTON_11 = 198,
- AKEYCODE_BUTTON_12 = 199,
- AKEYCODE_BUTTON_13 = 200,
- AKEYCODE_BUTTON_14 = 201,
- AKEYCODE_BUTTON_15 = 202,
- AKEYCODE_BUTTON_16 = 203,
- AKEYCODE_LANGUAGE_SWITCH = 204,
- AKEYCODE_MANNER_MODE = 205,
- AKEYCODE_3D_MODE = 206,
- AKEYCODE_CONTACTS = 207,
- AKEYCODE_CALENDAR = 208,
- AKEYCODE_MUSIC = 209,
- AKEYCODE_CALCULATOR = 210,
- AKEYCODE_ZENKAKU_HANKAKU = 211,
- AKEYCODE_EISU = 212,
- AKEYCODE_MUHENKAN = 213,
- AKEYCODE_HENKAN = 214,
- AKEYCODE_KATAKANA_HIRAGANA = 215,
- AKEYCODE_YEN = 216,
- AKEYCODE_RO = 217,
- AKEYCODE_KANA = 218,
- AKEYCODE_ASSIST = 219,
- AKEYCODE_BRIGHTNESS_DOWN = 220,
- AKEYCODE_BRIGHTNESS_UP = 221,
- AKEYCODE_MEDIA_AUDIO_TRACK = 222,
- AKEYCODE_SLEEP = 223,
- AKEYCODE_WAKEUP = 224,
- AKEYCODE_PAIRING = 225,
- AKEYCODE_MEDIA_TOP_MENU = 226,
- AKEYCODE_11 = 227,
- AKEYCODE_12 = 228,
- AKEYCODE_LAST_CHANNEL = 229,
- AKEYCODE_TV_DATA_SERVICE = 230,
- AKEYCODE_VOICE_ASSIST = 231,
- AKEYCODE_TV_RADIO_SERVICE = 232,
- AKEYCODE_TV_TELETEXT = 233,
- AKEYCODE_TV_NUMBER_ENTRY = 234,
- AKEYCODE_TV_TERRESTRIAL_ANALOG = 235,
- AKEYCODE_TV_TERRESTRIAL_DIGITAL = 236,
- AKEYCODE_TV_SATELLITE = 237,
- AKEYCODE_TV_SATELLITE_BS = 238,
- AKEYCODE_TV_SATELLITE_CS = 239,
- AKEYCODE_TV_SATELLITE_SERVICE = 240,
- AKEYCODE_TV_NETWORK = 241,
- AKEYCODE_TV_ANTENNA_CABLE = 242,
- AKEYCODE_TV_INPUT_HDMI_1 = 243,
- AKEYCODE_TV_INPUT_HDMI_2 = 244,
- AKEYCODE_TV_INPUT_HDMI_3 = 245,
- AKEYCODE_TV_INPUT_HDMI_4 = 246,
- AKEYCODE_TV_INPUT_COMPOSITE_1 = 247,
- AKEYCODE_TV_INPUT_COMPOSITE_2 = 248,
- AKEYCODE_TV_INPUT_COMPONENT_1 = 249,
- AKEYCODE_TV_INPUT_COMPONENT_2 = 250,
- AKEYCODE_TV_INPUT_VGA_1 = 251,
- AKEYCODE_TV_AUDIO_DESCRIPTION = 252,
- AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP = 253,
- AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN = 254,
- AKEYCODE_TV_ZOOM_MODE = 255,
- AKEYCODE_TV_CONTENTS_MENU = 256,
- AKEYCODE_TV_MEDIA_CONTEXT_MENU = 257,
- AKEYCODE_TV_TIMER_PROGRAMMING = 258,
- AKEYCODE_HELP = 259,
-
- // NOTE: If you add a new keycode here you must also add it to several other files.
- // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_KEYCODES_H
diff --git a/widget/gonk/libui/cutils_log.h b/widget/gonk/libui/cutils_log.h
deleted file mode 100644
index f4252c867..000000000
--- a/widget/gonk/libui/cutils_log.h
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2005 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// C/C++ logging functions. See the logging documentation for API details.
-//
-// We'd like these to be available from C code (in case we import some from
-// somewhere), so this has a C interface.
-//
-// The output will be correct when the log file is shared between multiple
-// threads and/or multiple processes so long as the operating system
-// supports O_APPEND. These calls have mutex-protected data structures
-// and so are NOT reentrant. Do not use LOG in a signal handler.
-//
-#if !defined(_LIBS_CUTILS_LOG_H) && !defined(_LIBS_LOG_LOG_H)
-#define _LIBS_LOG_LOG_H
-#define _LIBS_CUTILS_LOG_H
-
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#ifdef HAVE_PTHREADS
-#include <pthread.h>
-#endif
-#include <stdarg.h>
-
-#if ANDROID_VERSION >= 19
-#include <log/uio.h>
-#include <log/logd.h>
-#else
-#include <cutils/uio.h>
-#include <cutils/logd.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Normally we strip ALOGV (VERBOSE messages) from release builds.
- * You can modify this (for example with "#define LOG_NDEBUG 0"
- * at the top of your source file) to change that behavior.
- */
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/*
- * This is the local tag used for the following simplified
- * logging macros. You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Simplified macro to send a verbose log message using the current LOG_TAG.
- */
-#ifndef ALOGV
-#if LOG_NDEBUG
-#define ALOGV(...) ((void)0)
-#else
-#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#endif
-#endif
-
-#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
-
-#ifndef ALOGV_IF
-#if LOG_NDEBUG
-#define ALOGV_IF(cond, ...) ((void)0)
-#else
-#define ALOGV_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug log message using the current LOG_TAG.
- */
-#ifndef ALOGD
-#define ALOGD(...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGD_IF
-#define ALOGD_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an info log message using the current LOG_TAG.
- */
-#ifndef ALOGI
-#define ALOGI(...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGI_IF
-#define ALOGI_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send a warning log message using the current LOG_TAG.
- */
-#ifndef ALOGW
-#define ALOGW(...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGW_IF
-#define ALOGW_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an error log message using the current LOG_TAG.
- */
-#ifndef ALOGE
-#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef ALOGE_IF
-#define ALOGE_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * verbose priority.
- */
-#ifndef IF_ALOGV
-#if LOG_NDEBUG
-#define IF_ALOGV() if (false)
-#else
-#define IF_ALOGV() IF_ALOG(LOG_VERBOSE, LOG_TAG)
-#endif
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * debug priority.
- */
-#ifndef IF_ALOGD
-#define IF_ALOGD() IF_ALOG(LOG_DEBUG, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * info priority.
- */
-#ifndef IF_ALOGI
-#define IF_ALOGI() IF_ALOG(LOG_INFO, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * warn priority.
- */
-#ifndef IF_ALOGW
-#define IF_ALOGW() IF_ALOG(LOG_WARN, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * error priority.
- */
-#ifndef IF_ALOGE
-#define IF_ALOGE() IF_ALOG(LOG_ERROR, LOG_TAG)
-#endif
-
-
-// ---------------------------------------------------------------------
-
-/*
- * Simplified macro to send a verbose system log message using the current LOG_TAG.
- */
-#ifndef SLOGV
-#if LOG_NDEBUG
-#define SLOGV(...) ((void)0)
-#else
-#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#endif
-#endif
-
-#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
-
-#ifndef SLOGV_IF
-#if LOG_NDEBUG
-#define SLOGV_IF(cond, ...) ((void)0)
-#else
-#define SLOGV_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug system log message using the current LOG_TAG.
- */
-#ifndef SLOGD
-#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef SLOGD_IF
-#define SLOGD_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an info system log message using the current LOG_TAG.
- */
-#ifndef SLOGI
-#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef SLOGI_IF
-#define SLOGI_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send a warning system log message using the current LOG_TAG.
- */
-#ifndef SLOGW
-#define SLOGW(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef SLOGW_IF
-#define SLOGW_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an error system log message using the current LOG_TAG.
- */
-#ifndef SLOGE
-#define SLOGE(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef SLOGE_IF
-#define SLOGE_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Simplified macro to send a verbose radio log message using the current LOG_TAG.
- */
-#ifndef RLOGV
-#if LOG_NDEBUG
-#define RLOGV(...) ((void)0)
-#else
-#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#endif
-#endif
-
-#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
-
-#ifndef RLOGV_IF
-#if LOG_NDEBUG
-#define RLOGV_IF(cond, ...) ((void)0)
-#else
-#define RLOGV_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-#endif
-
-/*
- * Simplified macro to send a debug radio log message using the current LOG_TAG.
- */
-#ifndef RLOGD
-#define RLOGD(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef RLOGD_IF
-#define RLOGD_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an info radio log message using the current LOG_TAG.
- */
-#ifndef RLOGI
-#define RLOGI(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef RLOGI_IF
-#define RLOGI_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send a warning radio log message using the current LOG_TAG.
- */
-#ifndef RLOGW
-#define RLOGW(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef RLOGW_IF
-#define RLOGW_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an error radio log message using the current LOG_TAG.
- */
-#ifndef RLOGE
-#define RLOGE(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef RLOGE_IF
-#define RLOGE_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-
-// ---------------------------------------------------------------------
-
-/*
- * Log a fatal error. If the given condition fails, this stops program
- * execution like a normal assertion, but also generating the given message.
- * It is NOT stripped from release builds. Note that the condition test
- * is -inverted- from the normal assert() semantics.
- */
-#ifndef LOG_ALWAYS_FATAL_IF
-#define LOG_ALWAYS_FATAL_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-#ifndef LOG_ALWAYS_FATAL
-#define LOG_ALWAYS_FATAL(...) \
- ( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
-#endif
-
-/*
- * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
- * are stripped out of release builds.
- */
-#if LOG_NDEBUG
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) ((void)0)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) ((void)0)
-#endif
-
-#else
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
-#endif
-
-#endif
-
-/*
- * Assertion that generates a log message when the assertion fails.
- * Stripped out of release builds. Uses the current LOG_TAG.
- */
-#ifndef ALOG_ASSERT
-#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
-//#define ALOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond)
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Basic log message macro.
- *
- * Example:
- * ALOG(LOG_WARN, NULL, "Failed with error %d", errno);
- *
- * The second argument may be NULL or "" to indicate the "global" tag.
- */
-#ifndef ALOG
-#define ALOG(priority, tag, ...) \
- LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Log macro that allows you to specify a number for the priority.
- */
-#ifndef LOG_PRI
-#define LOG_PRI(priority, tag, ...) \
- android_printLog(priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Log macro that allows you to pass in a varargs ("args" is a va_list).
- */
-#ifndef LOG_PRI_VA
-#define LOG_PRI_VA(priority, tag, fmt, args) \
- android_vprintLog(priority, NULL, tag, fmt, args)
-#endif
-
-/*
- * Conditional given a desired logging priority and tag.
- */
-#ifndef IF_ALOG
-#define IF_ALOG(priority, tag) \
- if (android_testLog(ANDROID_##priority, tag))
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Event logging.
- */
-
-/*
- * Event log entry types. These must match up with the declarations in
- * java/android/android/util/EventLog.java.
- */
-typedef enum {
- EVENT_TYPE_INT = 0,
- EVENT_TYPE_LONG = 1,
- EVENT_TYPE_STRING = 2,
- EVENT_TYPE_LIST = 3,
-} AndroidEventLogType;
-
-
-#ifndef LOG_EVENT_INT
-#define LOG_EVENT_INT(_tag, _value) { \
- int intBuf = _value; \
- (void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \
- sizeof(intBuf)); \
- }
-#endif
-#ifndef LOG_EVENT_LONG
-#define LOG_EVENT_LONG(_tag, _value) { \
- long long longBuf = _value; \
- (void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \
- sizeof(longBuf)); \
- }
-#endif
-#ifndef LOG_EVENT_STRING
-#define LOG_EVENT_STRING(_tag, _value) \
- ((void) 0) /* not implemented -- must combine len with string */
-#endif
-/* TODO: something for LIST */
-
-/*
- * ===========================================================================
- *
- * The stuff in the rest of this file should not be used directly.
- */
-
-#define android_printLog(prio, tag, fmt...) \
- __android_log_print(prio, tag, fmt)
-
-#define android_vprintLog(prio, cond, tag, fmt...) \
- __android_log_vprint(prio, tag, fmt)
-
-/* XXX Macros to work around syntax errors in places where format string
- * arg is not passed to ALOG_ASSERT, LOG_ALWAYS_FATAL or LOG_ALWAYS_FATAL_IF
- * (happens only in debug builds).
- */
-
-/* Returns 2nd arg. Used to substitute default value if caller's vararg list
- * is empty.
- */
-#define __android_second(dummy, second, ...) second
-
-/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
- * returns nothing.
- */
-#define __android_rest(first, ...) , ## __VA_ARGS__
-
-#define android_printAssert(cond, tag, fmt...) \
- __android_log_assert(cond, tag, \
- __android_second(0, ## fmt, NULL) __android_rest(fmt))
-
-#define android_writeLog(prio, tag, text) \
- __android_log_write(prio, tag, text)
-
-#define android_bWriteLog(tag, payload, len) \
- __android_log_bwrite(tag, payload, len)
-#define android_btWriteLog(tag, type, payload, len) \
- __android_log_btwrite(tag, type, payload, len)
-
-// TODO: remove these prototypes and their users
-#define android_testLog(prio, tag) (1)
-#define android_writevLog(vec,num) do{}while(0)
-#define android_write1Log(str,len) do{}while (0)
-#define android_setMinPriority(tag, prio) do{}while(0)
-//#define android_logToCallback(func) do{}while(0)
-#define android_logToFile(tag, file) (0)
-#define android_logToFd(tag, fd) (0)
-
-typedef enum {
- LOG_ID_MAIN = 0,
- LOG_ID_RADIO = 1,
- LOG_ID_EVENTS = 2,
- LOG_ID_SYSTEM = 3,
-
- LOG_ID_MAX
-} log_id_t;
-
-/*
- * Send a simple string to the log.
- */
-int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
-int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _LIBS_CUTILS_LOG_H
diff --git a/widget/gonk/libui/cutils_trace.h b/widget/gonk/libui/cutils_trace.h
deleted file mode 100644
index 29034cab5..000000000
--- a/widget/gonk/libui/cutils_trace.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _LIBS_CUTILS_TRACE_H
-#define _LIBS_CUTILS_TRACE_H
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <cutils/compiler.h>
-
-#ifdef ANDROID_SMP
-#include <cutils/atomic-inline.h>
-#else
-#include <cutils/atomic.h>
-#endif
-
-__BEGIN_DECLS
-
-/**
- * The ATRACE_TAG macro can be defined before including this header to trace
- * using one of the tags defined below. It must be defined to one of the
- * following ATRACE_TAG_* macros. The trace tag is used to filter tracing in
- * userland to avoid some of the runtime cost of tracing when it is not desired.
- *
- * Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always
- * being enabled - this should ONLY be done for debug code, as userland tracing
- * has a performance cost even when the trace is not being recorded. Defining
- * ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result
- * in the tracing always being disabled.
- *
- * ATRACE_TAG_HAL should be bitwise ORed with the relevant tags for tracing
- * within a hardware module. For example a camera hardware module would set:
- * #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
- *
- * Keep these in sync with frameworks/base/core/java/android/os/Trace.java.
- */
-#define ATRACE_TAG_NEVER 0 // This tag is never enabled.
-#define ATRACE_TAG_ALWAYS (1<<0) // This tag is always enabled.
-#define ATRACE_TAG_GRAPHICS (1<<1)
-#define ATRACE_TAG_INPUT (1<<2)
-#define ATRACE_TAG_VIEW (1<<3)
-#define ATRACE_TAG_WEBVIEW (1<<4)
-#define ATRACE_TAG_WINDOW_MANAGER (1<<5)
-#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6)
-#define ATRACE_TAG_SYNC_MANAGER (1<<7)
-#define ATRACE_TAG_AUDIO (1<<8)
-#define ATRACE_TAG_VIDEO (1<<9)
-#define ATRACE_TAG_CAMERA (1<<10)
-#define ATRACE_TAG_HAL (1<<11)
-#define ATRACE_TAG_APP (1<<12)
-#define ATRACE_TAG_RESOURCES (1<<13)
-#define ATRACE_TAG_DALVIK (1<<14)
-#define ATRACE_TAG_LAST ATRACE_TAG_DALVIK
-
-// Reserved for initialization.
-#define ATRACE_TAG_NOT_READY (1LL<<63)
-
-#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
-
-#ifndef ATRACE_TAG
-#define ATRACE_TAG ATRACE_TAG_NEVER
-#elif ATRACE_TAG > ATRACE_TAG_VALID_MASK
-#error ATRACE_TAG must be defined to be one of the tags defined in cutils/trace.h
-#endif
-
-#ifdef HAVE_ANDROID_OS
-/**
- * Maximum size of a message that can be logged to the trace buffer.
- * Note this message includes a tag, the pid, and the string given as the name.
- * Names should be kept short to get the most use of the trace buffer.
- */
-#define ATRACE_MESSAGE_LENGTH 1024
-
-/**
- * Opens the trace file for writing and reads the property for initial tags.
- * The atrace.tags.enableflags property sets the tags to trace.
- * This function should not be explicitly called, the first call to any normal
- * trace function will cause it to be run safely.
- */
-void atrace_setup();
-
-/**
- * If tracing is ready, set atrace_enabled_tags to the system property
- * debug.atrace.tags.enableflags. Can be used as a sysprop change callback.
- */
-void atrace_update_tags();
-
-/**
- * Set whether the process is debuggable. By default the process is not
- * considered debuggable. If the process is not debuggable then application-
- * level tracing is not allowed unless the ro.debuggable system property is
- * set to '1'.
- */
-void atrace_set_debuggable(bool debuggable);
-
-/**
- * Set whether tracing is enabled for the current process. This is used to
- * prevent tracing within the Zygote process.
- */
-void atrace_set_tracing_enabled(bool enabled);
-
-/**
- * Flag indicating whether setup has been completed, initialized to 0.
- * Nonzero indicates setup has completed.
- * Note: This does NOT indicate whether or not setup was successful.
- */
-extern volatile int32_t atrace_is_ready;
-
-/**
- * Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY.
- * A value of zero indicates setup has failed.
- * Any other nonzero value indicates setup has succeeded, and tracing is on.
- */
-extern uint64_t atrace_enabled_tags;
-
-/**
- * Handle to the kernel's trace buffer, initialized to -1.
- * Any other value indicates setup has succeeded, and is a valid fd for tracing.
- */
-extern int atrace_marker_fd;
-
-/**
- * atrace_init readies the process for tracing by opening the trace_marker file.
- * Calling any trace function causes this to be run, so calling it is optional.
- * This can be explicitly run to avoid setup delay on first trace function.
- */
-#define ATRACE_INIT() atrace_init()
-static inline void atrace_init()
-{
- if (CC_UNLIKELY(!android_atomic_acquire_load(&atrace_is_ready))) {
- atrace_setup();
- }
-}
-
-/**
- * Get the mask of all tags currently enabled.
- * It can be used as a guard condition around more expensive trace calculations.
- * Every trace function calls this, which ensures atrace_init is run.
- */
-#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags()
-static inline uint64_t atrace_get_enabled_tags()
-{
- atrace_init();
- return atrace_enabled_tags;
-}
-
-/**
- * Test if a given tag is currently enabled.
- * Returns nonzero if the tag is enabled, otherwise zero.
- * It can be used as a guard condition around more expensive trace calculations.
- */
-#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG)
-static inline uint64_t atrace_is_tag_enabled(uint64_t tag)
-{
- return atrace_get_enabled_tags() & tag;
-}
-
-/**
- * Trace the beginning of a context. name is used to identify the context.
- * This is often used to time function execution.
- */
-#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name)
-static inline void atrace_begin(uint64_t tag, const char* name)
-{
- if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "B|%d|%s", getpid(), name);
- write(atrace_marker_fd, buf, len);
- }
-}
-
-/**
- * Trace the end of a context.
- * This should match up (and occur after) a corresponding ATRACE_BEGIN.
- */
-#define ATRACE_END() atrace_end(ATRACE_TAG)
-static inline void atrace_end(uint64_t tag)
-{
- if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
- char c = 'E';
- write(atrace_marker_fd, &c, 1);
- }
-}
-
-/**
- * Trace the beginning of an asynchronous event. Unlike ATRACE_BEGIN/ATRACE_END
- * contexts, asynchronous events do not need to be nested. The name describes
- * the event, and the cookie provides a unique identifier for distinguishing
- * simultaneous events. The name and cookie used to begin an event must be
- * used to end it.
- */
-#define ATRACE_ASYNC_BEGIN(name, cookie) \
- atrace_async_begin(ATRACE_TAG, name, cookie)
-static inline void atrace_async_begin(uint64_t tag, const char* name,
- int32_t cookie)
-{
- if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%d", getpid(),
- name, cookie);
- write(atrace_marker_fd, buf, len);
- }
-}
-
-/**
- * Trace the end of an asynchronous event.
- * This should have a corresponding ATRACE_ASYNC_BEGIN.
- */
-#define ATRACE_ASYNC_END(name, cookie) atrace_async_end(ATRACE_TAG, name, cookie)
-static inline void atrace_async_end(uint64_t tag, const char* name,
- int32_t cookie)
-{
- if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%d", getpid(),
- name, cookie);
- write(atrace_marker_fd, buf, len);
- }
-}
-
-
-/**
- * Traces an integer counter value. name is used to identify the counter.
- * This can be used to track how a value changes over time.
- */
-#define ATRACE_INT(name, value) atrace_int(ATRACE_TAG, name, value)
-static inline void atrace_int(uint64_t tag, const char* name, int32_t value)
-{
- if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
- char buf[ATRACE_MESSAGE_LENGTH];
- size_t len;
-
- len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%d",
- getpid(), name, value);
- write(atrace_marker_fd, buf, len);
- }
-}
-
-#else // not HAVE_ANDROID_OS
-
-#define ATRACE_INIT()
-#define ATRACE_GET_ENABLED_TAGS()
-#define ATRACE_ENABLED()
-#define ATRACE_BEGIN(name)
-#define ATRACE_END()
-#define ATRACE_ASYNC_BEGIN(name, cookie)
-#define ATRACE_ASYNC_END(name, cookie)
-#define ATRACE_INT(name, value)
-
-#endif // not HAVE_ANDROID_OS
-
-__END_DECLS
-
-#endif // _LIBS_CUTILS_TRACE_H
diff --git a/widget/gonk/libui/linux_input.h b/widget/gonk/libui/linux_input.h
deleted file mode 100644
index 2ba14973f..000000000
--- a/widget/gonk/libui/linux_input.h
+++ /dev/null
@@ -1,1029 +0,0 @@
-/****************************************************************************
- ****************************************************************************
- ***
- *** This header was automatically generated from a Linux kernel header
- *** of the same name, to make information necessary for userspace to
- *** call into the kernel available to libc. It contains only constants,
- *** structures, and macros generated from the original header, and thus,
- *** contains no copyrightable information.
- ***
- *** To edit the content of this header, modify the corresponding
- *** source file (e.g. under external/kernel-headers/original/) then
- *** run bionic/libc/kernel/tools/update_all.py
- ***
- *** Any manual change here will be lost the next time this script will
- *** be run. You've been warned!
- ***
- ****************************************************************************
- ****************************************************************************/
-#ifndef _INPUT_H
-#define _INPUT_H
-#include <sys/time.h>
-#include <sys/ioctl.h>
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#include <sys/types.h>
-#include <linux/types.h>
-struct input_event {
- struct timeval time;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 type;
- __u16 code;
- __s32 value;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_VERSION 0x010001
-struct input_id {
- __u16 bustype;
- __u16 vendor;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 product;
- __u16 version;
-};
-struct input_absinfo {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __s32 value;
- __s32 minimum;
- __s32 maximum;
- __s32 fuzz;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __s32 flat;
- __s32 resolution;
-};
-struct input_keymap_entry {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define INPUT_KEYMAP_BY_INDEX (1 << 0)
- __u8 flags;
- __u8 len;
- __u16 index;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u32 keycode;
- __u8 scancode[32];
-};
-#define EVIOCGVERSION _IOR('E', 0x01, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCGID _IOR('E', 0x02, struct input_id)
-#define EVIOCGREP _IOR('E', 0x03, unsigned int[2])
-#define EVIOCSREP _IOW('E', 0x03, unsigned int[2])
-#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2])
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry)
-#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2])
-#define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry)
-#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len)
-#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len)
-#define EVIOCGPROP(len) _IOC(_IOC_READ, 'E', 0x09, len)
-#define EVIOCGMTSLOTS(len) _IOC(_IOC_READ, 'E', 0x0a, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len)
-#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len)
-#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len)
-#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + (ev), len)
-#define EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo)
-#define EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo)
-#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect))
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCRMFF _IOW('E', 0x81, int)
-#define EVIOCGEFFECTS _IOR('E', 0x84, int)
-#define EVIOCGRAB _IOW('E', 0x90, int)
-#define EVIOCGSUSPENDBLOCK _IOR('E', 0x91, int)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
-#define EVIOCSCLOCKID _IOW('E', 0xa0, int)
-#define INPUT_PROP_POINTER 0x00
-#define INPUT_PROP_DIRECT 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define INPUT_PROP_BUTTONPAD 0x02
-#define INPUT_PROP_SEMI_MT 0x03
-#define INPUT_PROP_MAX 0x1f
-#define INPUT_PROP_CNT (INPUT_PROP_MAX + 1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_SYN 0x00
-#define EV_KEY 0x01
-#define EV_REL 0x02
-#define EV_ABS 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_MSC 0x04
-#define EV_SW 0x05
-#define EV_LED 0x11
-#define EV_SND 0x12
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_REP 0x14
-#define EV_FF 0x15
-#define EV_PWR 0x16
-#define EV_FF_STATUS 0x17
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define EV_MAX 0x1f
-#define EV_CNT (EV_MAX+1)
-#define SYN_REPORT 0
-#define SYN_CONFIG 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SYN_MT_REPORT 2
-#define SYN_DROPPED 3
-#define SYN_TIME_SEC 4
-#define SYN_TIME_NSEC 5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RESERVED 0
-#define KEY_ESC 1
-#define KEY_1 2
-#define KEY_2 3
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_3 4
-#define KEY_4 5
-#define KEY_5 6
-#define KEY_6 7
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_7 8
-#define KEY_8 9
-#define KEY_9 10
-#define KEY_0 11
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MINUS 12
-#define KEY_EQUAL 13
-#define KEY_BACKSPACE 14
-#define KEY_TAB 15
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_Q 16
-#define KEY_W 17
-#define KEY_E 18
-#define KEY_R 19
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_T 20
-#define KEY_Y 21
-#define KEY_U 22
-#define KEY_I 23
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_O 24
-#define KEY_P 25
-#define KEY_LEFTBRACE 26
-#define KEY_RIGHTBRACE 27
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ENTER 28
-#define KEY_LEFTCTRL 29
-#define KEY_A 30
-#define KEY_S 31
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_D 32
-#define KEY_F 33
-#define KEY_G 34
-#define KEY_H 35
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_J 36
-#define KEY_K 37
-#define KEY_L 38
-#define KEY_SEMICOLON 39
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_APOSTROPHE 40
-#define KEY_GRAVE 41
-#define KEY_LEFTSHIFT 42
-#define KEY_BACKSLASH 43
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_Z 44
-#define KEY_X 45
-#define KEY_C 46
-#define KEY_V 47
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_B 48
-#define KEY_N 49
-#define KEY_M 50
-#define KEY_COMMA 51
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DOT 52
-#define KEY_SLASH 53
-#define KEY_RIGHTSHIFT 54
-#define KEY_KPASTERISK 55
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_LEFTALT 56
-#define KEY_SPACE 57
-#define KEY_CAPSLOCK 58
-#define KEY_F1 59
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F2 60
-#define KEY_F3 61
-#define KEY_F4 62
-#define KEY_F5 63
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F6 64
-#define KEY_F7 65
-#define KEY_F8 66
-#define KEY_F9 67
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F10 68
-#define KEY_NUMLOCK 69
-#define KEY_SCROLLLOCK 70
-#define KEY_KP7 71
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP8 72
-#define KEY_KP9 73
-#define KEY_KPMINUS 74
-#define KEY_KP4 75
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP5 76
-#define KEY_KP6 77
-#define KEY_KPPLUS 78
-#define KEY_KP1 79
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KP2 80
-#define KEY_KP3 81
-#define KEY_KP0 82
-#define KEY_KPDOT 83
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ZENKAKUHANKAKU 85
-#define KEY_102ND 86
-#define KEY_F11 87
-#define KEY_F12 88
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RO 89
-#define KEY_KATAKANA 90
-#define KEY_HIRAGANA 91
-#define KEY_HENKAN 92
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KATAKANAHIRAGANA 93
-#define KEY_MUHENKAN 94
-#define KEY_KPJPCOMMA 95
-#define KEY_KPENTER 96
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RIGHTCTRL 97
-#define KEY_KPSLASH 98
-#define KEY_SYSRQ 99
-#define KEY_RIGHTALT 100
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_LINEFEED 101
-#define KEY_HOME 102
-#define KEY_UP 103
-#define KEY_PAGEUP 104
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_LEFT 105
-#define KEY_RIGHT 106
-#define KEY_END 107
-#define KEY_DOWN 108
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PAGEDOWN 109
-#define KEY_INSERT 110
-#define KEY_DELETE 111
-#define KEY_MACRO 112
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MUTE 113
-#define KEY_VOLUMEDOWN 114
-#define KEY_VOLUMEUP 115
-#define KEY_POWER 116
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPEQUAL 117
-#define KEY_KPPLUSMINUS 118
-#define KEY_PAUSE 119
-#define KEY_SCALE 120
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPCOMMA 121
-#define KEY_HANGEUL 122
-#define KEY_HANGUEL KEY_HANGEUL
-#define KEY_HANJA 123
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_YEN 124
-#define KEY_LEFTMETA 125
-#define KEY_RIGHTMETA 126
-#define KEY_COMPOSE 127
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_STOP 128
-#define KEY_AGAIN 129
-#define KEY_PROPS 130
-#define KEY_UNDO 131
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FRONT 132
-#define KEY_COPY 133
-#define KEY_OPEN 134
-#define KEY_PASTE 135
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FIND 136
-#define KEY_CUT 137
-#define KEY_HELP 138
-#define KEY_MENU 139
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CALC 140
-#define KEY_SETUP 141
-#define KEY_SLEEP 142
-#define KEY_WAKEUP 143
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FILE 144
-#define KEY_SENDFILE 145
-#define KEY_DELETEFILE 146
-#define KEY_XFER 147
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PROG1 148
-#define KEY_PROG2 149
-#define KEY_WWW 150
-#define KEY_MSDOS 151
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_COFFEE 152
-#define KEY_SCREENLOCK KEY_COFFEE
-#define KEY_DIRECTION 153
-#define KEY_CYCLEWINDOWS 154
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MAIL 155
-#define KEY_BOOKMARKS 156
-#define KEY_COMPUTER 157
-#define KEY_BACK 158
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FORWARD 159
-#define KEY_CLOSECD 160
-#define KEY_EJECTCD 161
-#define KEY_EJECTCLOSECD 162
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NEXTSONG 163
-#define KEY_PLAYPAUSE 164
-#define KEY_PREVIOUSSONG 165
-#define KEY_STOPCD 166
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RECORD 167
-#define KEY_REWIND 168
-#define KEY_PHONE 169
-#define KEY_ISO 170
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CONFIG 171
-#define KEY_HOMEPAGE 172
-#define KEY_REFRESH 173
-#define KEY_EXIT 174
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MOVE 175
-#define KEY_EDIT 176
-#define KEY_SCROLLUP 177
-#define KEY_SCROLLDOWN 178
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KPLEFTPAREN 179
-#define KEY_KPRIGHTPAREN 180
-#define KEY_NEW 181
-#define KEY_REDO 182
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F13 183
-#define KEY_F14 184
-#define KEY_F15 185
-#define KEY_F16 186
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F17 187
-#define KEY_F18 188
-#define KEY_F19 189
-#define KEY_F20 190
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_F21 191
-#define KEY_F22 192
-#define KEY_F23 193
-#define KEY_F24 194
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PLAYCD 200
-#define KEY_PAUSECD 201
-#define KEY_PROG3 202
-#define KEY_PROG4 203
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DASHBOARD 204
-#define KEY_SUSPEND 205
-#define KEY_CLOSE 206
-#define KEY_PLAY 207
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FASTFORWARD 208
-#define KEY_BASSBOOST 209
-#define KEY_PRINT 210
-#define KEY_HP 211
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CAMERA 212
-#define KEY_SOUND 213
-#define KEY_QUESTION 214
-#define KEY_EMAIL 215
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CHAT 216
-#define KEY_SEARCH 217
-#define KEY_CONNECT 218
-#define KEY_FINANCE 219
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SPORT 220
-#define KEY_SHOP 221
-#define KEY_ALTERASE 222
-#define KEY_CANCEL 223
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRIGHTNESSDOWN 224
-#define KEY_BRIGHTNESSUP 225
-#define KEY_MEDIA 226
-#define KEY_SWITCHVIDEOMODE 227
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KBDILLUMTOGGLE 228
-#define KEY_KBDILLUMDOWN 229
-#define KEY_KBDILLUMUP 230
-#define KEY_SEND 231
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_REPLY 232
-#define KEY_FORWARDMAIL 233
-#define KEY_SAVE 234
-#define KEY_DOCUMENTS 235
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BATTERY 236
-#define KEY_BLUETOOTH 237
-#define KEY_WLAN 238
-#define KEY_UWB 239
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_UNKNOWN 240
-#define KEY_VIDEO_NEXT 241
-#define KEY_VIDEO_PREV 242
-#define KEY_BRIGHTNESS_CYCLE 243
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRIGHTNESS_ZERO 244
-#define KEY_DISPLAY_OFF 245
-#define KEY_WIMAX 246
-#define KEY_RFKILL 247
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MICMUTE 248
-#define BTN_MISC 0x100
-#define BTN_0 0x100
-#define BTN_1 0x101
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_2 0x102
-#define BTN_3 0x103
-#define BTN_4 0x104
-#define BTN_5 0x105
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_6 0x106
-#define BTN_7 0x107
-#define BTN_8 0x108
-#define BTN_9 0x109
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_MOUSE 0x110
-#define BTN_LEFT 0x110
-#define BTN_RIGHT 0x111
-#define BTN_MIDDLE 0x112
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_SIDE 0x113
-#define BTN_EXTRA 0x114
-#define BTN_FORWARD 0x115
-#define BTN_BACK 0x116
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TASK 0x117
-#define BTN_JOYSTICK 0x120
-#define BTN_TRIGGER 0x120
-#define BTN_THUMB 0x121
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_THUMB2 0x122
-#define BTN_TOP 0x123
-#define BTN_TOP2 0x124
-#define BTN_PINKIE 0x125
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_BASE 0x126
-#define BTN_BASE2 0x127
-#define BTN_BASE3 0x128
-#define BTN_BASE4 0x129
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_BASE5 0x12a
-#define BTN_BASE6 0x12b
-#define BTN_DEAD 0x12f
-#define BTN_GAMEPAD 0x130
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_A 0x130
-#define BTN_B 0x131
-#define BTN_C 0x132
-#define BTN_X 0x133
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_Y 0x134
-#define BTN_Z 0x135
-#define BTN_TL 0x136
-#define BTN_TR 0x137
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TL2 0x138
-#define BTN_TR2 0x139
-#define BTN_SELECT 0x13a
-#define BTN_START 0x13b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_MODE 0x13c
-#define BTN_THUMBL 0x13d
-#define BTN_THUMBR 0x13e
-#define BTN_DIGI 0x140
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_PEN 0x140
-#define BTN_TOOL_RUBBER 0x141
-#define BTN_TOOL_BRUSH 0x142
-#define BTN_TOOL_PENCIL 0x143
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_AIRBRUSH 0x144
-#define BTN_TOOL_FINGER 0x145
-#define BTN_TOOL_MOUSE 0x146
-#define BTN_TOOL_LENS 0x147
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_QUINTTAP 0x148
-#define BTN_TOUCH 0x14a
-#define BTN_STYLUS 0x14b
-#define BTN_STYLUS2 0x14c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TOOL_DOUBLETAP 0x14d
-#define BTN_TOOL_TRIPLETAP 0x14e
-#define BTN_TOOL_QUADTAP 0x14f
-#define BTN_WHEEL 0x150
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_GEAR_DOWN 0x150
-#define BTN_GEAR_UP 0x151
-#define KEY_OK 0x160
-#define KEY_SELECT 0x161
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_GOTO 0x162
-#define KEY_CLEAR 0x163
-#define KEY_POWER2 0x164
-#define KEY_OPTION 0x165
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_INFO 0x166
-#define KEY_TIME 0x167
-#define KEY_VENDOR 0x168
-#define KEY_ARCHIVE 0x169
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PROGRAM 0x16a
-#define KEY_CHANNEL 0x16b
-#define KEY_FAVORITES 0x16c
-#define KEY_EPG 0x16d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_PVR 0x16e
-#define KEY_MHP 0x16f
-#define KEY_LANGUAGE 0x170
-#define KEY_TITLE 0x171
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SUBTITLE 0x172
-#define KEY_ANGLE 0x173
-#define KEY_ZOOM 0x174
-#define KEY_MODE 0x175
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_KEYBOARD 0x176
-#define KEY_SCREEN 0x177
-#define KEY_PC 0x178
-#define KEY_TV 0x179
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TV2 0x17a
-#define KEY_VCR 0x17b
-#define KEY_VCR2 0x17c
-#define KEY_SAT 0x17d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SAT2 0x17e
-#define KEY_CD 0x17f
-#define KEY_TAPE 0x180
-#define KEY_RADIO 0x181
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TUNER 0x182
-#define KEY_PLAYER 0x183
-#define KEY_TEXT 0x184
-#define KEY_DVD 0x185
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_AUX 0x186
-#define KEY_MP3 0x187
-#define KEY_AUDIO 0x188
-#define KEY_VIDEO 0x189
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DIRECTORY 0x18a
-#define KEY_LIST 0x18b
-#define KEY_MEMO 0x18c
-#define KEY_CALENDAR 0x18d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_RED 0x18e
-#define KEY_GREEN 0x18f
-#define KEY_YELLOW 0x190
-#define KEY_BLUE 0x191
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CHANNELUP 0x192
-#define KEY_CHANNELDOWN 0x193
-#define KEY_FIRST 0x194
-#define KEY_LAST 0x195
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_AB 0x196
-#define KEY_NEXT 0x197
-#define KEY_RESTART 0x198
-#define KEY_SLOW 0x199
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_SHUFFLE 0x19a
-#define KEY_BREAK 0x19b
-#define KEY_PREVIOUS 0x19c
-#define KEY_DIGITS 0x19d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TEEN 0x19e
-#define KEY_TWEN 0x19f
-#define KEY_VIDEOPHONE 0x1a0
-#define KEY_GAMES 0x1a1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_ZOOMIN 0x1a2
-#define KEY_ZOOMOUT 0x1a3
-#define KEY_ZOOMRESET 0x1a4
-#define KEY_WORDPROCESSOR 0x1a5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_EDITOR 0x1a6
-#define KEY_SPREADSHEET 0x1a7
-#define KEY_GRAPHICSEDITOR 0x1a8
-#define KEY_PRESENTATION 0x1a9
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DATABASE 0x1aa
-#define KEY_NEWS 0x1ab
-#define KEY_VOICEMAIL 0x1ac
-#define KEY_ADDRESSBOOK 0x1ad
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_MESSENGER 0x1ae
-#define KEY_DISPLAYTOGGLE 0x1af
-#define KEY_SPELLCHECK 0x1b0
-#define KEY_LOGOFF 0x1b1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DOLLAR 0x1b2
-#define KEY_EURO 0x1b3
-#define KEY_FRAMEBACK 0x1b4
-#define KEY_FRAMEFORWARD 0x1b5
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CONTEXT_MENU 0x1b6
-#define KEY_MEDIA_REPEAT 0x1b7
-#define KEY_10CHANNELSUP 0x1b8
-#define KEY_10CHANNELSDOWN 0x1b9
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_IMAGES 0x1ba
-#define KEY_DEL_EOL 0x1c0
-#define KEY_DEL_EOS 0x1c1
-#define KEY_INS_LINE 0x1c2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_DEL_LINE 0x1c3
-#define KEY_FN 0x1d0
-#define KEY_FN_ESC 0x1d1
-#define KEY_FN_F1 0x1d2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F2 0x1d3
-#define KEY_FN_F3 0x1d4
-#define KEY_FN_F4 0x1d5
-#define KEY_FN_F5 0x1d6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F6 0x1d7
-#define KEY_FN_F7 0x1d8
-#define KEY_FN_F8 0x1d9
-#define KEY_FN_F9 0x1da
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_F10 0x1db
-#define KEY_FN_F11 0x1dc
-#define KEY_FN_F12 0x1dd
-#define KEY_FN_1 0x1de
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_2 0x1df
-#define KEY_FN_D 0x1e0
-#define KEY_FN_E 0x1e1
-#define KEY_FN_F 0x1e2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_FN_S 0x1e3
-#define KEY_FN_B 0x1e4
-#define KEY_BRL_DOT1 0x1f1
-#define KEY_BRL_DOT2 0x1f2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRL_DOT3 0x1f3
-#define KEY_BRL_DOT4 0x1f4
-#define KEY_BRL_DOT5 0x1f5
-#define KEY_BRL_DOT6 0x1f6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_BRL_DOT7 0x1f7
-#define KEY_BRL_DOT8 0x1f8
-#define KEY_BRL_DOT9 0x1f9
-#define KEY_BRL_DOT10 0x1fa
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_0 0x200
-#define KEY_NUMERIC_1 0x201
-#define KEY_NUMERIC_2 0x202
-#define KEY_NUMERIC_3 0x203
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_4 0x204
-#define KEY_NUMERIC_5 0x205
-#define KEY_NUMERIC_6 0x206
-#define KEY_NUMERIC_7 0x207
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_NUMERIC_8 0x208
-#define KEY_NUMERIC_9 0x209
-#define KEY_NUMERIC_STAR 0x20a
-#define KEY_NUMERIC_POUND 0x20b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CAMERA_SNAPSHOT 0x2fe
-#define KEY_CAMERA_FOCUS 0x210
-#define KEY_WPS_BUTTON 0x211
-#define KEY_TOUCHPAD_TOGGLE 0x212
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_TOUCHPAD_ON 0x213
-#define KEY_TOUCHPAD_OFF 0x214
-#define KEY_CAMERA_ZOOMIN 0x215
-#define KEY_CAMERA_ZOOMOUT 0x216
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define KEY_CAMERA_UP 0x217
-#define KEY_CAMERA_DOWN 0x218
-#define KEY_CAMERA_LEFT 0x219
-#define KEY_CAMERA_RIGHT 0x21a
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY 0x2c0
-#define BTN_TRIGGER_HAPPY1 0x2c0
-#define BTN_TRIGGER_HAPPY2 0x2c1
-#define BTN_TRIGGER_HAPPY3 0x2c2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY4 0x2c3
-#define BTN_TRIGGER_HAPPY5 0x2c4
-#define BTN_TRIGGER_HAPPY6 0x2c5
-#define BTN_TRIGGER_HAPPY7 0x2c6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY8 0x2c7
-#define BTN_TRIGGER_HAPPY9 0x2c8
-#define BTN_TRIGGER_HAPPY10 0x2c9
-#define BTN_TRIGGER_HAPPY11 0x2ca
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY12 0x2cb
-#define BTN_TRIGGER_HAPPY13 0x2cc
-#define BTN_TRIGGER_HAPPY14 0x2cd
-#define BTN_TRIGGER_HAPPY15 0x2ce
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY16 0x2cf
-#define BTN_TRIGGER_HAPPY17 0x2d0
-#define BTN_TRIGGER_HAPPY18 0x2d1
-#define BTN_TRIGGER_HAPPY19 0x2d2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY20 0x2d3
-#define BTN_TRIGGER_HAPPY21 0x2d4
-#define BTN_TRIGGER_HAPPY22 0x2d5
-#define BTN_TRIGGER_HAPPY23 0x2d6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY24 0x2d7
-#define BTN_TRIGGER_HAPPY25 0x2d8
-#define BTN_TRIGGER_HAPPY26 0x2d9
-#define BTN_TRIGGER_HAPPY27 0x2da
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY28 0x2db
-#define BTN_TRIGGER_HAPPY29 0x2dc
-#define BTN_TRIGGER_HAPPY30 0x2dd
-#define BTN_TRIGGER_HAPPY31 0x2de
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY32 0x2df
-#define BTN_TRIGGER_HAPPY33 0x2e0
-#define BTN_TRIGGER_HAPPY34 0x2e1
-#define BTN_TRIGGER_HAPPY35 0x2e2
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY36 0x2e3
-#define BTN_TRIGGER_HAPPY37 0x2e4
-#define BTN_TRIGGER_HAPPY38 0x2e5
-#define BTN_TRIGGER_HAPPY39 0x2e6
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BTN_TRIGGER_HAPPY40 0x2e7
-#define KEY_MIN_INTERESTING KEY_MUTE
-#define KEY_MAX 0x2ff
-#define KEY_CNT (KEY_MAX+1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_X 0x00
-#define REL_Y 0x01
-#define REL_Z 0x02
-#define REL_RX 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_RY 0x04
-#define REL_RZ 0x05
-#define REL_HWHEEL 0x06
-#define REL_DIAL 0x07
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REL_WHEEL 0x08
-#define REL_MISC 0x09
-#define REL_MAX 0x0f
-#define REL_CNT (REL_MAX+1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_X 0x00
-#define ABS_Y 0x01
-#define ABS_Z 0x02
-#define ABS_RX 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_RY 0x04
-#define ABS_RZ 0x05
-#define ABS_THROTTLE 0x06
-#define ABS_RUDDER 0x07
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_WHEEL 0x08
-#define ABS_GAS 0x09
-#define ABS_BRAKE 0x0a
-#define ABS_HAT0X 0x10
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_HAT0Y 0x11
-#define ABS_HAT1X 0x12
-#define ABS_HAT1Y 0x13
-#define ABS_HAT2X 0x14
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_HAT2Y 0x15
-#define ABS_HAT3X 0x16
-#define ABS_HAT3Y 0x17
-#define ABS_PRESSURE 0x18
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_DISTANCE 0x19
-#define ABS_TILT_X 0x1a
-#define ABS_TILT_Y 0x1b
-#define ABS_TOOL_WIDTH 0x1c
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_VOLUME 0x20
-#define ABS_MISC 0x28
-#define ABS_MT_SLOT 0x2f
-#define ABS_MT_TOUCH_MAJOR 0x30
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_TOUCH_MINOR 0x31
-#define ABS_MT_WIDTH_MAJOR 0x32
-#define ABS_MT_WIDTH_MINOR 0x33
-#define ABS_MT_ORIENTATION 0x34
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_POSITION_X 0x35
-#define ABS_MT_POSITION_Y 0x36
-#define ABS_MT_TOOL_TYPE 0x37
-#define ABS_MT_BLOB_ID 0x38
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_MT_TRACKING_ID 0x39
-#define ABS_MT_PRESSURE 0x3a
-#define ABS_MT_DISTANCE 0x3b
-#define ABS_MAX 0x3f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ABS_CNT (ABS_MAX+1)
-#define SW_LID 0x00
-#define SW_TABLET_MODE 0x01
-#define SW_HEADPHONE_INSERT 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_RFKILL_ALL 0x03
-#define SW_RADIO SW_RFKILL_ALL
-#define SW_MICROPHONE_INSERT 0x04
-#define SW_DOCK 0x05
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_LINEOUT_INSERT 0x06
-#define SW_JACK_PHYSICAL_INSERT 0x07
-#define SW_VIDEOOUT_INSERT 0x08
-#define SW_CAMERA_LENS_COVER 0x09
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_KEYPAD_SLIDE 0x0a
-#define SW_FRONT_PROXIMITY 0x0b
-#define SW_ROTATE_LOCK 0x0c
-#define SW_LINEIN_INSERT 0x0d
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_HPHL_OVERCURRENT 0x0e
-#define SW_HPHR_OVERCURRENT 0x0f
-#define SW_UNSUPPORT_INSERT 0x10
-#define SW_MAX 0x20
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SW_CNT (SW_MAX+1)
-#define MSC_SERIAL 0x00
-#define MSC_PULSELED 0x01
-#define MSC_GESTURE 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define MSC_RAW 0x03
-#define MSC_SCAN 0x04
-#define MSC_MAX 0x07
-#define MSC_CNT (MSC_MAX+1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_NUML 0x00
-#define LED_CAPSL 0x01
-#define LED_SCROLLL 0x02
-#define LED_COMPOSE 0x03
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_KANA 0x04
-#define LED_SLEEP 0x05
-#define LED_SUSPEND 0x06
-#define LED_MUTE 0x07
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_MISC 0x08
-#define LED_MAIL 0x09
-#define LED_CHARGING 0x0a
-#define LED_MAX 0x0f
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define LED_CNT (LED_MAX+1)
-#define REP_DELAY 0x00
-#define REP_PERIOD 0x01
-#define REP_MAX 0x01
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define REP_CNT (REP_MAX+1)
-#define SND_CLICK 0x00
-#define SND_BELL 0x01
-#define SND_TONE 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define SND_MAX 0x07
-#define SND_CNT (SND_MAX+1)
-#define ID_BUS 0
-#define ID_VENDOR 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define ID_PRODUCT 2
-#define ID_VERSION 3
-#define BUS_PCI 0x01
-#define BUS_ISAPNP 0x02
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BUS_USB 0x03
-#define BUS_HIL 0x04
-#define BUS_BLUETOOTH 0x05
-#define BUS_VIRTUAL 0x06
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BUS_ISA 0x10
-#define BUS_I8042 0x11
-#define BUS_XTKBD 0x12
-#define BUS_RS232 0x13
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BUS_GAMEPORT 0x14
-#define BUS_PARPORT 0x15
-#define BUS_AMIGA 0x16
-#define BUS_ADB 0x17
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BUS_I2C 0x18
-#define BUS_HOST 0x19
-#define BUS_GSC 0x1A
-#define BUS_ATARI 0x1B
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define BUS_SPI 0x1C
-#define MT_TOOL_FINGER 0
-#define MT_TOOL_PEN 1
-#define MT_TOOL_MAX 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_STATUS_STOPPED 0x00
-#define FF_STATUS_PLAYING 0x01
-#define FF_STATUS_MAX 0x01
-struct ff_replay {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 length;
- __u16 delay;
-};
-struct ff_trigger {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 button;
- __u16 interval;
-};
-struct ff_envelope {
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 attack_length;
- __u16 attack_level;
- __u16 fade_length;
- __u16 fade_level;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
-struct ff_constant_effect {
- __s16 level;
- struct ff_envelope envelope;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-};
-struct ff_ramp_effect {
- __s16 start_level;
- __s16 end_level;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- struct ff_envelope envelope;
-};
-struct ff_condition_effect {
- __u16 right_saturation;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 left_saturation;
- __s16 right_coeff;
- __s16 left_coeff;
- __u16 deadband;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __s16 center;
-};
-struct ff_periodic_effect {
- __u16 waveform;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 period;
- __s16 magnitude;
- __s16 offset;
- __u16 phase;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- struct ff_envelope envelope;
- __u32 custom_len;
- __s16 __user *custom_data;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct ff_rumble_effect {
- __u16 strong_magnitude;
- __u16 weak_magnitude;
-};
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-struct ff_effect {
- __u16 type;
- __s16 id;
- __u16 direction;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- struct ff_trigger trigger;
- struct ff_replay replay;
- union {
- struct ff_constant_effect constant;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- struct ff_ramp_effect ramp;
- struct ff_periodic_effect periodic;
- struct ff_condition_effect condition[2];
- struct ff_rumble_effect rumble;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- } u;
-};
-#define FF_RUMBLE 0x50
-#define FF_PERIODIC 0x51
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_CONSTANT 0x52
-#define FF_SPRING 0x53
-#define FF_FRICTION 0x54
-#define FF_DAMPER 0x55
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_INERTIA 0x56
-#define FF_RAMP 0x57
-#define FF_EFFECT_MIN FF_RUMBLE
-#define FF_EFFECT_MAX FF_RAMP
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_SQUARE 0x58
-#define FF_TRIANGLE 0x59
-#define FF_SINE 0x5a
-#define FF_SAW_UP 0x5b
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_SAW_DOWN 0x5c
-#define FF_CUSTOM 0x5d
-#define FF_WAVEFORM_MIN FF_SQUARE
-#define FF_WAVEFORM_MAX FF_CUSTOM
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define FF_GAIN 0x60
-#define FF_AUTOCENTER 0x61
-#define FF_MAX 0x7f
-#define FF_CNT (FF_MAX+1)
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#endif
diff --git a/widget/gonk/libui/sha1.c b/widget/gonk/libui/sha1.c
deleted file mode 100644
index 40a4ecaa3..000000000
--- a/widget/gonk/libui/sha1.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ */
-/* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */
-
-/*
- * SHA-1 in C
- * By Steve Reid <steve@edmweb.com>
- * 100% Public Domain
- *
- * Test Vectors (from FIPS PUB 180-1)
- * "abc"
- * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
- * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
- * A million repetitions of "a"
- * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
- */
-
-#define SHA1HANDSOFF /* Copies data before messing with it. */
-
-#include <sys/cdefs.h>
-
-#if defined(_KERNEL) || defined(_STANDALONE)
-__KERNEL_RCSID(0, "$NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $");
-
-#include <lib/libkern/libkern.h>
-
-#else
-
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $");
-#endif /* LIBC_SCCS and not lint */
-
-#include <assert.h>
-#include <string.h>
-
-#endif
-
-#include <sys/types.h>
-#include "sha1.h"
-
-#define _DIAGASSERT assert
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#if !HAVE_SHA1_H
-
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/*
- * blk0() and blk() perform the initial expand.
- * I got the idea of expanding during the round function from SSLeay
- */
-#if BYTE_ORDER == LITTLE_ENDIAN
-# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
- |(rol(block->l[i],8)&0x00FF00FF))
-#else
-# define blk0(i) block->l[i]
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
- ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/*
- * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
- */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-#if !defined(_KERNEL) && !defined(_STANDALONE)
-#if defined(__weak_alias)
-__weak_alias(SHA1Transform,_SHA1Transform)
-__weak_alias(SHA1Init,_SHA1Init)
-__weak_alias(SHA1Update,_SHA1Update)
-__weak_alias(SHA1Final,_SHA1Final)
-#endif
-#endif
-
-typedef union {
- uint8_t c[64];
- uint32_t l[16];
-} CHAR64LONG16;
-
-/* old sparc64 gcc could not compile this */
-#undef SPARC64_GCC_WORKAROUND
-#if defined(__sparc64__) && defined(__GNUC__) && __GNUC__ < 3
-#define SPARC64_GCC_WORKAROUND
-#endif
-
-#ifdef SPARC64_GCC_WORKAROUND
-void do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
-void do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
-void do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
-void do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *);
-
-#define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i)
-#define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i)
-#define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i)
-#define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i)
-#define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i)
-
-void
-do_R01(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
-{
- nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2); nR0(c,d,e,a,b, 3);
- nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5); nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7);
- nR0(c,d,e,a,b, 8); nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11);
- nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14); nR0(a,b,c,d,e,15);
- nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17); nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19);
-}
-
-void
-do_R2(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
-{
- nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22); nR2(c,d,e,a,b,23);
- nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25); nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27);
- nR2(c,d,e,a,b,28); nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31);
- nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34); nR2(a,b,c,d,e,35);
- nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37); nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39);
-}
-
-void
-do_R3(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
-{
- nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42); nR3(c,d,e,a,b,43);
- nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45); nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47);
- nR3(c,d,e,a,b,48); nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51);
- nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54); nR3(a,b,c,d,e,55);
- nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57); nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59);
-}
-
-void
-do_R4(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint32_t *e, CHAR64LONG16 *block)
-{
- nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62); nR4(c,d,e,a,b,63);
- nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65); nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67);
- nR4(c,d,e,a,b,68); nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71);
- nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74); nR4(a,b,c,d,e,75);
- nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77); nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79);
-}
-#endif
-
-/*
- * Hash a single 512-bit block. This is the core of the algorithm.
- */
-void SHA1Transform(uint32_t state[5], const uint8_t buffer[64])
-{
- uint32_t a, b, c, d, e;
- CHAR64LONG16 *block;
-
-#ifdef SHA1HANDSOFF
- CHAR64LONG16 workspace;
-#endif
-
- _DIAGASSERT(buffer != 0);
- _DIAGASSERT(state != 0);
-
-#ifdef SHA1HANDSOFF
- block = &workspace;
- (void)memcpy(block, buffer, 64);
-#else
- block = (CHAR64LONG16 *)(void *)buffer;
-#endif
-
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
-
-#ifdef SPARC64_GCC_WORKAROUND
- do_R01(&a, &b, &c, &d, &e, block);
- do_R2(&a, &b, &c, &d, &e, block);
- do_R3(&a, &b, &c, &d, &e, block);
- do_R4(&a, &b, &c, &d, &e, block);
-#else
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-#endif
-
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
-
- /* Wipe variables */
- a = b = c = d = e = 0;
-}
-
-
-/*
- * SHA1Init - Initialize new context
- */
-void SHA1Init(SHA1_CTX *context)
-{
-
- _DIAGASSERT(context != 0);
-
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
-}
-
-
-/*
- * Run your data through this.
- */
-void SHA1Update(SHA1_CTX *context, const uint8_t *data, unsigned int len)
-{
- unsigned int i, j;
-
- _DIAGASSERT(context != 0);
- _DIAGASSERT(data != 0);
-
- j = context->count[0];
- if ((context->count[0] += len << 3) < j)
- context->count[1] += (len>>29)+1;
- j = (j >> 3) & 63;
- if ((j + len) > 63) {
- (void)memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64)
- SHA1Transform(context->state, &data[i]);
- j = 0;
- } else {
- i = 0;
- }
- (void)memcpy(&context->buffer[j], &data[i], len - i);
-}
-
-
-/*
- * Add padding and return the message digest.
- */
-void SHA1Final(uint8_t digest[20], SHA1_CTX *context)
-{
- unsigned int i;
- uint8_t finalcount[8];
-
- _DIAGASSERT(digest != 0);
- _DIAGASSERT(context != 0);
-
- for (i = 0; i < 8; i++) {
- finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
- SHA1Update(context, (const uint8_t *)"\200", 1);
- while ((context->count[0] & 504) != 448)
- SHA1Update(context, (const uint8_t *)"\0", 1);
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
-
- if (digest) {
- for (i = 0; i < 20; i++)
- digest[i] = (uint8_t)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
-}
-
-#endif /* HAVE_SHA1_H */
diff --git a/widget/gonk/libui/sha1.h b/widget/gonk/libui/sha1.h
deleted file mode 100644
index f7ada46a5..000000000
--- a/widget/gonk/libui/sha1.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* $NetBSD: sha1.h,v 1.13 2005/12/26 18:41:36 perry Exp $ */
-
-/*
- * SHA-1 in C
- * By Steve Reid <steve@edmweb.com>
- * 100% Public Domain
- */
-
-#ifndef _SYS_SHA1_H_
-#define _SYS_SHA1_H_
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-
-#define SHA1_DIGEST_LENGTH 20
-#define SHA1_DIGEST_STRING_LENGTH 41
-
-typedef struct {
- uint32_t state[5];
- uint32_t count[2];
- u_char buffer[64];
-} SHA1_CTX;
-
-__BEGIN_DECLS
-void SHA1Transform(uint32_t[5], const u_char[64]);
-void SHA1Init(SHA1_CTX *);
-void SHA1Update(SHA1_CTX *, const u_char *, u_int);
-void SHA1Final(u_char[SHA1_DIGEST_LENGTH], SHA1_CTX *);
-__END_DECLS
-
-#endif /* _SYS_SHA1_H_ */