diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index dc9757e28..16cd6cf67 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -340,13 +340,13 @@ public: inline void* data() { return mData; } }; -#ifndef DISABLE_ASHMEM_TRACKING private: - size_t mBlobAshmemSize; -#endif + size_t mOpenAshmemSize; public: + // TODO: Remove once ABI can be changed. size_t getBlobAshmemSize() const; + size_t getOpenAshmemSize() const; }; // --------------------------------------------------------------------------- diff --git a/include/input/Input.h b/include/input/Input.h index 4a67f47f9..617175bb3 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -28,6 +28,7 @@ #include #include #include +#include /* * Additional private constants not defined in ndk/ui/input.h. @@ -110,6 +111,11 @@ enum { */ #define MAX_POINTERS 16 +/* + * Maximum number of samples supported per motion event. + */ +#define MAX_SAMPLES UINT16_MAX + /* * Maximum pointer id value supported in a motion event. * Smallest pointer id is 0. diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index e70666ab2..3f0914b67 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -124,6 +124,11 @@ public: * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; + /* Tries to find a replacement key code for a given key code and meta state + * in character map. */ + void tryRemapKey(int32_t scanCode, int32_t metaState, + int32_t* outKeyCode, int32_t* outMetaState) const; + #if HAVE_ANDROID_OS /* Reads a key map from a parcel. */ static sp readFromParcel(Parcel* parcel); @@ -151,6 +156,9 @@ private: /* The fallback keycode if the key is not handled. */ int32_t fallbackKeyCode; + + /* The replacement keycode if the key has to be replaced outright. */ + int32_t replacementKeyCode; }; struct Key { diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h index 519bb22d2..d4903e98d 100644 --- a/include/input/Keyboard.h +++ b/include/input/Keyboard.h @@ -87,6 +87,13 @@ extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentif */ extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); +/** + * Normalizes the meta state such that if either the left or right modifier + * meta state bits are set then the result will also include the universal + * bit for that modifier. + */ +extern int32_t normalizeMetaState(int32_t oldMetaState); + /** * Returns true if a key is a meta key like ALT or CAPS_LOCK. */ diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index ba41f0fe8..22d7ef36c 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -96,7 +96,7 @@ enum { }; void acquire_object(const sp& proc, - const flat_binder_object& obj, const void* who) + const flat_binder_object& obj, const void* who, size_t* outAshmemSize) { switch (obj.type) { case BINDER_TYPE_BINDER: @@ -123,8 +123,15 @@ void acquire_object(const sp& proc, return; } case BINDER_TYPE_FD: { - // intentionally blank -- nothing to do to acquire this, but we do - // recognize it as a legitimate object type. + if (obj.cookie != 0) { + if (outAshmemSize != NULL) { + // If we own an ashmem fd, keep track of how much memory it refers to. + int size = ashmem_get_size_region(obj.handle); + if (size > 0) { + *outAshmemSize += size; + } + } + } return; } } @@ -132,8 +139,14 @@ void acquire_object(const sp& proc, ALOGD("Invalid object type 0x%08x", obj.type); } -void release_object(const sp& proc, +void acquire_object(const sp& proc, const flat_binder_object& obj, const void* who) +{ + acquire_object(proc, obj, who, NULL); +} + +static void release_object(const sp& proc, + const flat_binder_object& obj, const void* who, size_t* outAshmemSize) { switch (obj.type) { case BINDER_TYPE_BINDER: @@ -160,7 +173,16 @@ void release_object(const sp& proc, return; } case BINDER_TYPE_FD: { - if (obj.cookie != 0) close(obj.handle); + if (outAshmemSize != NULL) { + if (obj.cookie != 0) { + int size = ashmem_get_size_region(obj.handle); + if (size > 0) { + *outAshmemSize -= size; + } + + close(obj.handle); + } + } return; } } @@ -168,6 +190,12 @@ void release_object(const sp& proc, ALOGE("Invalid object type 0x%08x", obj.type); } +void release_object(const sp& proc, + const flat_binder_object& obj, const void* who) +{ + release_object(proc, obj, who, NULL); +} + inline static status_t finish_flatten_binder( const sp& /*binder*/, const flat_binder_object& flat, Parcel* out) { @@ -504,7 +532,7 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) flat_binder_object* flat = reinterpret_cast(mData + off); - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, &mOpenAshmemSize); if (flat->type == BINDER_TYPE_FD) { // If this is a file descriptor, we need to dup it so the @@ -922,9 +950,7 @@ status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) ALOGV("writeBlob: write to ashmem"); int fd = ashmem_create_region("Parcel Blob", len); if (fd < 0) return NO_MEMORY; -#ifndef DISABLE_ASHMEM_TRACKING - mBlobAshmemSize += len; -#endif + int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); if (result < 0) { status = result; @@ -1026,7 +1052,7 @@ restart_write: // Need to write meta-data? if (nullMetaData || val.binder != 0) { mObjects[mObjectsSize] = mDataPos; - acquire_object(ProcessState::self(), val, this); + acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize); mObjectsSize++; } @@ -1609,7 +1635,7 @@ void Parcel::releaseObjects() i--; const flat_binder_object* flat = reinterpret_cast(data+objects[i]); - release_object(proc, *flat, this); + release_object(proc, *flat, this, &mOpenAshmemSize); } } @@ -1623,7 +1649,7 @@ void Parcel::acquireObjects() i--; const flat_binder_object* flat = reinterpret_cast(data+objects[i]); - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, &mOpenAshmemSize); } } @@ -1805,7 +1831,7 @@ status_t Parcel::continueWrite(size_t desired) // will need to rescan because we may have lopped off the only FDs mFdsKnown = false; } - release_object(proc, *flat, this); + release_object(proc, *flat, this, &mOpenAshmemSize); } binder_size_t* objects = (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t)); @@ -1890,9 +1916,7 @@ void Parcel::initState() mFdsKnown = true; mAllowFds = true; mOwner = NULL; -#ifndef DISABLE_ASHMEM_TRACKING - mBlobAshmemSize = 0; -#endif + mOpenAshmemSize = 0; } void Parcel::scanForFds() const @@ -1912,11 +1936,15 @@ void Parcel::scanForFds() const size_t Parcel::getBlobAshmemSize() const { -#ifndef DISABLE_ASHMEM_TRACKING - return mBlobAshmemSize; -#else - return 0; -#endif + // This used to return the size of all blobs that were written to ashmem, now we're returning + // the ashmem currently referenced by this Parcel, which should be equivalent. + // TODO: Remove method once ABI can be changed. + return mOpenAshmemSize; +} + +size_t Parcel::getOpenAshmemSize() const +{ + return mOpenAshmemSize; } // --- Parcel::Blob --- diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp index 4b3603ee1..235cbbdd7 100644 --- a/libs/gui/Sensor.cpp +++ b/libs/gui/Sensor.cpp @@ -245,6 +245,11 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) break; } + // Set DATA_INJECTION flag here. Defined in HAL 1_4. + if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) { + mFlags |= (hwSensor->flags & DATA_INJECTION_MASK); + } + // For the newer HALs log errors if reporting mask flags are set incorrectly. if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { // Wake-up flag is set here. diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 2c1418e07..b64cb2ca9 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -424,7 +424,8 @@ void MotionEvent::transform(const float matrix[9]) { status_t MotionEvent::readFromParcel(Parcel* parcel) { size_t pointerCount = parcel->readInt32(); size_t sampleCount = parcel->readInt32(); - if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) { + if (pointerCount == 0 || pointerCount > MAX_POINTERS || + sampleCount == 0 || sampleCount > MAX_SAMPLES) { return BAD_VALUE; } diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index b03e01eff..df3f0dd1d 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -332,33 +332,75 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o 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); +#if DEBUG_MAPPING + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", + scanCode, usageCode, *outKeyCode); +#endif 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); +#if DEBUG_MAPPING + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", + scanCode, usageCode, *outKeyCode); +#endif return OK; } } #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); #endif *outKeyCode = AKEYCODE_UNKNOWN; return NAME_NOT_FOUND; } +void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, + int32_t *outKeyCode, int32_t *outMetaState) const { + *outKeyCode = keyCode; + *outMetaState = metaState; + + const Key* key; + const Behavior* behavior; + if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { + if (behavior->replacementKeyCode) { + *outKeyCode = behavior->replacementKeyCode; + int32_t newMetaState = metaState & ~behavior->metaState; + // Reset dependent meta states. + if (behavior->metaState & AMETA_ALT_ON) { + newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); + } + if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { + newMetaState &= ~AMETA_ALT_ON; + } + if (behavior->metaState & AMETA_CTRL_ON) { + newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); + } + if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { + newMetaState &= ~AMETA_CTRL_ON; + } + if (behavior->metaState & AMETA_SHIFT_ON) { + newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); + } + if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { + newMetaState &= ~AMETA_SHIFT_ON; + } + // ... and put universal bits back if needed + *outMetaState = normalizeMetaState(newMetaState); + } + } + +#if DEBUG_MAPPING + ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ " + "replacement keyCode=%d, replacement metaState=0x%08x.", + keyCode, metaState, *outKeyCode, *outMetaState); +#endif +} + bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { ssize_t index = mKeys.indexOfKey(keyCode); if (index >= 0) { @@ -584,6 +626,7 @@ sp KeyCharacterMap::readFromParcel(Parcel* parcel) { int32_t metaState = parcel->readInt32(); char16_t character = parcel->readInt32(); int32_t fallbackKeyCode = parcel->readInt32(); + int32_t replacementKeyCode = parcel->readInt32(); if (parcel->errorCheck()) { return NULL; } @@ -592,6 +635,7 @@ sp KeyCharacterMap::readFromParcel(Parcel* parcel) { behavior->metaState = metaState; behavior->character = character; behavior->fallbackKeyCode = fallbackKeyCode; + behavior->replacementKeyCode = replacementKeyCode; if (lastBehavior) { lastBehavior->next = behavior; } else { @@ -624,6 +668,7 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { parcel->writeInt32(behavior->metaState); parcel->writeInt32(behavior->character); parcel->writeInt32(behavior->fallbackKeyCode); + parcel->writeInt32(behavior->replacementKeyCode); } parcel->writeInt32(0); } @@ -655,13 +700,14 @@ KeyCharacterMap::Key::~Key() { // --- KeyCharacterMap::Behavior --- KeyCharacterMap::Behavior::Behavior() : - next(NULL), metaState(0), character(0), fallbackKeyCode(0) { + next(NULL), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) { } KeyCharacterMap::Behavior::Behavior(const Behavior& other) : next(other.next ? new Behavior(*other.next) : NULL), metaState(other.metaState), character(other.character), - fallbackKeyCode(other.fallbackKeyCode) { + fallbackKeyCode(other.fallbackKeyCode), + replacementKeyCode(other.replacementKeyCode) { } @@ -923,6 +969,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { Behavior behavior; bool haveCharacter = false; bool haveFallback = false; + bool haveReplacement = false; do { char ch = mTokenizer->peekChar(); @@ -939,6 +986,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } + if (haveReplacement) { + ALOGE("%s: Cannot combine character literal with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } behavior.character = character; haveCharacter = true; } else { @@ -949,6 +1001,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } + if (haveReplacement) { + ALOGE("%s: Cannot combine 'none' with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } haveCharacter = true; } else if (token == "fallback") { mTokenizer->skipDelimiters(WHITESPACE); @@ -960,13 +1017,36 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { token.string()); return BAD_VALUE; } - if (haveFallback) { - ALOGE("%s: Cannot combine multiple fallback key codes.", + if (haveFallback || haveReplacement) { + ALOGE("%s: Cannot combine multiple fallback/replacement key codes.", mTokenizer->getLocation().string()); return BAD_VALUE; } behavior.fallbackKeyCode = keyCode; haveFallback = true; + } else if (token == "replace") { + mTokenizer->skipDelimiters(WHITESPACE); + token = mTokenizer->nextToken(WHITESPACE); + int32_t keyCode = getKeyCodeByLabel(token.string()); + if (!keyCode) { + ALOGE("%s: Invalid key code label for replace, got '%s'.", + mTokenizer->getLocation().string(), + token.string()); + return BAD_VALUE; + } + if (haveCharacter) { + ALOGE("%s: Cannot combine character literal with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + if (haveFallback || haveReplacement) { + ALOGE("%s: Cannot combine multiple fallback/replacement key codes.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + behavior.replacementKeyCode = keyCode; + haveReplacement = true; + } else { ALOGE("%s: Expected a key behavior after ':'.", mTokenizer->getLocation().string()); @@ -1016,8 +1096,10 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { 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); + ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.", + mKeyCode, + newBehavior->metaState, newBehavior->character, + newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode); #endif break; } diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp index f4d95077d..9a01395da 100644 --- a/libs/input/Keyboard.cpp +++ b/libs/input/Keyboard.cpp @@ -176,6 +176,11 @@ static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaSta ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON); } + return normalizeMetaState(newMetaState); +} + +int32_t normalizeMetaState(int32_t oldMetaState) { + int32_t newMetaState = oldMetaState; if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { newMetaState |= AMETA_ALT_ON; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 0bc81b1de..4d9eaf5b3 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -604,15 +604,6 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) return setError(EGL_BAD_SURFACE, EGL_FALSE); egl_surface_t * const s = get_surface(surface); - ANativeWindow* window = s->win.get(); - if (window) { - int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); - if (result != OK) { - ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) " - "failed (%#x)", - window, result); - } - } EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface); if (result == EGL_TRUE) { _s.terminate(); diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp index 6b60c7cf7..585960628 100644 --- a/services/inputflinger/EventHub.cpp +++ b/services/inputflinger/EventHub.cpp @@ -438,10 +438,12 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, return false; } -status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const { +status_t EventHub::mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); + status_t status = NAME_NOT_FOUND; if (device) { // Check the key character map first. @@ -449,22 +451,34 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, if (kcm != NULL) { if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { *outFlags = 0; - return NO_ERROR; + status = NO_ERROR; } } // Check the key layout next. - if (device->keyMap.haveKeyLayout()) { + if (status != NO_ERROR && device->keyMap.haveKeyLayout()) { if (!device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags)) { - return NO_ERROR; + status = NO_ERROR; + } + } + + if (status == NO_ERROR) { + if (kcm != NULL) { + kcm->tryRemapKey(*outKeycode, metaState, outKeycode, outMetaState); + } else { + *outMetaState = metaState; } } } - *outKeycode = 0; - *outFlags = 0; - return NAME_NOT_FOUND; + if (status != NO_ERROR) { + *outKeycode = 0; + *outFlags = 0; + *outMetaState = metaState; + } + + return status; } status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h index 3ec49105c..0f94c770e 100644 --- a/services/inputflinger/EventHub.h +++ b/services/inputflinger/EventHub.h @@ -197,8 +197,9 @@ public: 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 mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const = 0; virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const = 0; @@ -285,8 +286,9 @@ public: 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 mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const; virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const; diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index 3813d9b59..53ff1557b 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -2193,13 +2193,7 @@ void KeyboardInputMapper::process(const RawEvent* rawEvent) { 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); + processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode); } break; } @@ -2224,8 +2218,18 @@ bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) { || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI); } -void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, - int32_t scanCode, uint32_t policyFlags) { +void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, + int32_t usageCode) { + int32_t keyCode; + int32_t keyMetaState; + uint32_t policyFlags; + + if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState, + &keyCode, &keyMetaState, &policyFlags)) { + keyCode = AKEYCODE_UNKNOWN; + keyMetaState = mMetaState; + policyFlags = 0; + } if (down) { // Rotate key codes according to orientation if needed. @@ -2278,6 +2282,12 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, if (metaStateChanged) { mMetaState = newMetaState; updateLedState(false); + + // If global meta state changed send it along with the key. + // If it has not changed then we'll use what keymap gave us, + // since key replacement logic might temporarily reset a few + // meta bits for given key. + keyMetaState = newMetaState; } nsecs_t downTime = mDownTime; @@ -2305,7 +2315,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, - AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); + AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime); getListener()->notifyKey(&args); } @@ -3568,8 +3578,10 @@ void TouchInputMapper::configureVirtualKeys() { virtualKey.scanCode = virtualKeyDefinition.scanCode; int32_t keyCode; + int32_t dummyKeyMetaState; uint32_t flags; - if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) { + if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, 0, + &keyCode, &dummyKeyMetaState, &flags)) { ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode); mVirtualKeys.pop(); // drop the key diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h index 9a46fb8ee..e480350c8 100644 --- a/services/inputflinger/InputReader.h +++ b/services/inputflinger/InputReader.h @@ -1175,8 +1175,7 @@ private: bool isKeyboardOrGamepadKey(int32_t scanCode); - void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode, - uint32_t policyFlags); + void processKey(nsecs_t when, bool down, int32_t scanCode, int32_t usageCode); ssize_t findKeyDown(int32_t scanCode); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index f34b810f1..42bc8656b 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -518,8 +518,9 @@ private: return false; } - virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const { + virtual status_t mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const { Device* device = getDevice(deviceId); if (device) { const KeyInfo* key = getKey(device, scanCode, usageCode); @@ -530,6 +531,9 @@ private: if (outFlags) { *outFlags = key->flags; } + if (outMetaState) { + *outMetaState = metaState; + } return OK; } } diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 9c67be2a9..28af943dd 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -913,11 +913,16 @@ status_t SensorService::enable(const sp& connection, status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, maxBatchReportLatencyNs); - // Call flush() before calling activate() on the sensor. Wait for a first flush complete - // event before sending events on this connection. Ignore one-shot sensors which don't - // support flush(). Also if this sensor isn't already active, don't call flush(). + // Call flush() before calling activate() on the sensor. Wait for a first + // flush complete event before sending events on this connection. Ignore + // one-shot sensors which don't support flush(). Ignore on-change sensors + // to maintain the on-change logic (any on-change events except the initial + // one should be trigger by a change in value). Also if this sensor isn't + // already active, don't call flush(). const SensorDevice& device(SensorDevice::getInstance()); - if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && + if (err == NO_ERROR && + sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && + sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE && rec->getNumConnections() > 1) { if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) { connection->setFirstFlushPending(handle, true);