diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/binder/Parcel.cpp | 62 | ||||
-rw-r--r-- | libs/gui/Sensor.cpp | 5 | ||||
-rw-r--r-- | libs/gui/SensorManager.cpp | 72 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 13 | ||||
-rw-r--r-- | libs/input/KeyCharacterMap.cpp | 108 | ||||
-rw-r--r-- | libs/input/Keyboard.cpp | 5 |
6 files changed, 233 insertions, 32 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 7a4ddc4..22d7ef3 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -96,7 +96,7 @@ enum { }; void acquire_object(const sp<ProcessState>& 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<ProcessState>& 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,9 +139,15 @@ void acquire_object(const sp<ProcessState>& proc, ALOGD("Invalid object type 0x%08x", obj.type); } -void release_object(const sp<ProcessState>& proc, +void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj, const void* who) { + acquire_object(proc, obj, who, NULL); +} + +static void release_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who, size_t* outAshmemSize) +{ switch (obj.type) { case BINDER_TYPE_BINDER: if (obj.binder) { @@ -160,7 +173,16 @@ void release_object(const sp<ProcessState>& 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<ProcessState>& proc, ALOGE("Invalid object type 0x%08x", obj.type); } +void release_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who) +{ + release_object(proc, obj, who, NULL); +} + inline static status_t finish_flatten_binder( const sp<IBinder>& /*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<flat_binder_object*>(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 @@ -923,8 +951,6 @@ status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob) int fd = ashmem_create_region("Parcel Blob", len); if (fd < 0) return NO_MEMORY; - mBlobAshmemSize += len; - 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<flat_binder_object*>(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<flat_binder_object*>(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,7 +1916,7 @@ void Parcel::initState() mFdsKnown = true; mAllowFds = true; mOwner = NULL; - mBlobAshmemSize = 0; + mOpenAshmemSize = 0; } void Parcel::scanForFds() const @@ -1910,7 +1936,15 @@ void Parcel::scanForFds() const size_t Parcel::getBlobAshmemSize() const { - return mBlobAshmemSize; + // 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 4b3603e..235cbbd 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/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index dd37781..33608b5 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -36,6 +36,58 @@ namespace android { // ---------------------------------------------------------------------------- +android::Mutex android::SensorManager::sLock; +std::map<String16, SensorManager*> android::SensorManager::sPackageInstances; + +SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) { + Mutex::Autolock _l(sLock); + SensorManager* sensorManager; + std::map<String16, SensorManager*>::iterator iterator = + sPackageInstances.find(packageName); + + if (iterator != sPackageInstances.end()) { + sensorManager = iterator->second; + } else { + String16 opPackageName = packageName; + + // It is possible that the calling code has no access to the package name. + // In this case we will get the packages for the calling UID and pick the + // first one for attributing the app op. This will work correctly for + // runtime permissions as for legacy apps we will toggle the app op for + // all packages in the UID. The caveat is that the operation may be attributed + // to the wrong package and stats based on app ops may be slightly off. + if (opPackageName.size() <= 0) { + sp<IBinder> binder = defaultServiceManager()->getService(String16("permission")); + if (binder != 0) { + const uid_t uid = IPCThreadState::self()->getCallingUid(); + Vector<String16> packages; + interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages); + if (!packages.isEmpty()) { + opPackageName = packages[0]; + } else { + ALOGE("No packages for calling UID"); + } + } else { + ALOGE("Cannot get permission service"); + } + } + + sensorManager = new SensorManager(opPackageName); + + // If we had no package name, we looked it up from the UID and the sensor + // manager instance we created should also be mapped to the empty package + // name, to avoid looking up the packages for a UID and get the same result. + if (packageName.size() <= 0) { + sPackageInstances.insert(std::make_pair(String16(), sensorManager)); + } + + // Stash the per package sensor manager. + sPackageInstances.insert(std::make_pair(opPackageName, sensorManager)); + } + + return *sensorManager; +} + SensorManager::SensorManager(const String16& opPackageName) : mSensorList(0), mOpPackageName(opPackageName) { @@ -58,13 +110,23 @@ void SensorManager::sensorManagerDied() } status_t SensorManager::assertStateLocked() const { + bool initSensorManager = false; if (mSensorServer == NULL) { - // try for one second + initSensorManager = true; + } else { + // Ping binder to check if sensorservice is alive. + status_t err = IInterface::asBinder(mSensorServer)->pingBinder(); + if (err != NO_ERROR) { + initSensorManager = true; + } + } + if (initSensorManager) { + // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ... const String16 name("sensorservice"); - for (int i=0 ; i<4 ; i++) { + for (int i = 0; i < 60; i++) { status_t err = getService(name, &mSensorServer); if (err == NAME_NOT_FOUND) { - usleep(250000); + sleep(1); continue; } if (err != NO_ERROR) { @@ -83,6 +145,8 @@ status_t SensorManager::assertStateLocked() const { DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { } }; + LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL"); + mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this)); IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver); @@ -90,6 +154,8 @@ status_t SensorManager::assertStateLocked() const { size_t count = mSensors.size(); mSensorList = static_cast<Sensor const**>(malloc(count * sizeof(Sensor*))); + LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL"); + for (size_t i=0 ; i<count ; i++) { mSensorList[i] = mSensors.array() + i; } diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 0382f57..7f83da5 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -51,6 +51,10 @@ 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 difference between consecutive samples before attempting to resample +// by extrapolation. +static const nsecs_t RESAMPLE_MAX_DELTA = 20 * 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; @@ -724,7 +728,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, nsecs_t delta = future.eventTime - current->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %lld ns.", delta); #endif return; } @@ -736,7 +740,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, nsecs_t delta = current->eventTime - other->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %lld ns.", delta); +#endif + return; + } else if (delta > RESAMPLE_MAX_DELTA) { +#if DEBUG_RESAMPLING + ALOGD("Not resampled, delta time is too large: %lld ns.", delta); #endif return; } diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index b03e01e..df3f0dd 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) { + *outKeyCode = mKeysByUsageCode.valueAt(index); #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", - scanCode, usageCode, *outKeyCode); + 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) { + *outKeyCode = mKeysByScanCode.valueAt(index); #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", - scanCode, usageCode, *outKeyCode); + 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); + 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> 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> 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 f4d9507..9a01395 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; } |