Loading include/ui/InputDispatcher.h +19 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,12 @@ public: virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) = 0; /* Gets the maximum suggested event delivery rate per second. * This value is used to throttle motion event movement actions on a per-device * basis. It is not intended to be a hard limit. */ virtual int32_t getMaxEventsPerSecond() = 0; }; Loading Loading @@ -332,6 +338,8 @@ private: // Linked list of motion samples associated with this motion event. MotionSample firstSample; MotionSample* lastSample; uint32_t countSamples() const; }; // Tracks the progress of dispatching a particular event to a particular connection. Loading Loading @@ -587,6 +595,17 @@ private: Condition mInjectionSyncFinishedCondition; void decrementPendingSyncDispatchesLocked(EventEntry* entry); // Throttling state. struct ThrottleState { nsecs_t minTimeBetweenEvents; nsecs_t lastEventTime; int32_t lastDeviceId; uint32_t lastSource; uint32_t originalSampleCount; // only collected during debugging } mThrottleState; // Key repeat tracking. // XXX Move this up to the input reader instead. struct KeyRepeatState { Loading include/utils/ObbFile.h +31 −4 Original line number Diff line number Diff line Loading @@ -18,12 +18,16 @@ #define OBBFILE_H_ #include <stdint.h> #include <strings.h> #include <utils/RefBase.h> #include <utils/String8.h> namespace android { // OBB flags (bit 0) #define OBB_OVERLAY (1 << 0) class ObbFile : public RefBase { protected: virtual ~ObbFile(); Loading @@ -46,18 +50,38 @@ public: return mPackageName; } int32_t getVersion() const { return mVersion; } void setPackageName(String8 packageName) { mPackageName = packageName; } int32_t getVersion() const { return mVersion; } void setVersion(int32_t version) { mVersion = version; } int32_t getFlags() const { return mFlags; } void setFlags(int32_t flags) { mFlags = flags; } bool isOverlay() { return (mFlags & OBB_OVERLAY) == OBB_OVERLAY; } void setOverlay(bool overlay) { if (overlay) { mFlags |= OBB_OVERLAY; } else { mFlags &= ~OBB_OVERLAY; } } static inline uint32_t get4LE(const unsigned char* buf) { return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); } Loading @@ -76,6 +100,9 @@ private: /* Package version this ObbFile is associated with */ int32_t mVersion; /* Flags for this OBB type. */ int32_t mFlags; const char* mFileName; size_t mFileSize; Loading libs/ui/InputDispatcher.cpp +78 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ // Log debug messages about input event injection. #define DEBUG_INJECTION 0 // Log debug messages about input event throttling. #define DEBUG_THROTTLING 0 #include <cutils/log.h> #include <ui/InputDispatcher.h> Loading Loading @@ -66,6 +69,15 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic mKeyRepeatState.lastKeyEntry = NULL; int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond(); mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond; mThrottleState.lastDeviceId = -1; #if DEBUG_THROTTLING mThrottleState.originalSampleCount = 0; LOGD("Throttling - Max events per second = %d", maxEventsPerSecond); #endif mCurrentInputTargetsValid = false; } Loading Loading @@ -144,12 +156,61 @@ void InputDispatcher::dispatchOnce() { } } else { // Inbound queue has at least one entry. // Start processing it but leave it on the queue until later so that the EventEntry* entry = mInboundQueue.head.next; // Consider throttling the entry if it is a move event and there are no // other events behind it in the queue. Due to movement batching, additional // samples may be appended to this event by the time the throttling timeout // expires. // TODO Make this smarter and consider throttling per device independently. if (entry->type == EventEntry::TYPE_MOTION) { MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); int32_t deviceId = motionEntry->deviceId; uint32_t source = motionEntry->source; if (motionEntry->next == & mInboundQueue.tail && motionEntry->action == AMOTION_EVENT_ACTION_MOVE && deviceId == mThrottleState.lastDeviceId && source == mThrottleState.lastSource) { nsecs_t nextTime = mThrottleState.lastEventTime + mThrottleState.minTimeBetweenEvents; if (currentTime < nextTime) { // Throttle it! #if DEBUG_THROTTLING LOGD("Throttling - Delaying motion event for " "device 0x%x, source 0x%08x by up to %0.3fms.", deviceId, source, (nextTime - currentTime) * 0.000001); #endif if (nextTime < nextWakeupTime) { nextWakeupTime = nextTime; } if (mThrottleState.originalSampleCount == 0) { mThrottleState.originalSampleCount = motionEntry->countSamples(); } goto Throttle; } } #if DEBUG_THROTTLING if (mThrottleState.originalSampleCount != 0) { uint32_t count = motionEntry->countSamples(); LOGD("Throttling - Motion event sample count grew by %d from %d to %d.", count - mThrottleState.originalSampleCount, mThrottleState.originalSampleCount, count); mThrottleState.originalSampleCount = 0; } #endif mThrottleState.lastEventTime = entry->eventTime < currentTime ? entry->eventTime : currentTime; mThrottleState.lastDeviceId = deviceId; mThrottleState.lastSource = source; } // Start processing the entry but leave it on the queue until later so that the // input reader can keep appending samples onto a motion event between the // time we started processing it and the time we finally enqueue dispatch // entries for it. EventEntry* entry = mInboundQueue.head.next; switch (entry->type) { case EventEntry::TYPE_CONFIGURATION_CHANGED: { ConfigurationChangedEntry* typedEntry = Loading Loading @@ -179,6 +240,8 @@ void InputDispatcher::dispatchOnce() { mInboundQueue.dequeue(entry); mAllocator.releaseEventEntry(entry); skipPoll = true; Throttle: ; } } Loading @@ -192,8 +255,8 @@ void InputDispatcher::dispatchOnce() { return; } // Wait for callback or timeout or wake. nsecs_t timeout = nanoseconds_to_milliseconds(nextWakeupTime - currentTime); // Wait for callback or timeout or wake. (make sure we round up, not down) nsecs_t timeout = (nextWakeupTime - currentTime + 999999LL) / 1000000LL; int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0; mPollLoop->pollOnce(timeoutMillis); } Loading Loading @@ -1708,6 +1771,16 @@ void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry, motionEntry->lastSample = sample; } // --- InputDispatcher::MotionEntry --- uint32_t InputDispatcher::MotionEntry::countSamples() const { uint32_t count = 1; for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) { count += 1; } return count; } // --- InputDispatcher::Connection --- InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) : Loading libs/ui/PixelFormat.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) info->bitsPerPixel = 16; goto done; case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: case HAL_PIXEL_FORMAT_YV12: info->bitsPerPixel = 12; done: Loading libs/utils/ObbFile.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -29,12 +29,13 @@ #define kFooterTagSize 8 /* last two 32-bit integers */ #define kFooterMinSize 21 /* 32-bit signature version * 32-bit package version * 32-bit package name size * 1-character package name * 32-bit footer size * 32-bit footer marker #define kFooterMinSize 25 /* 32-bit signature version (4 bytes) * 32-bit package version (4 bytes) * 32-bit flags (4 bytes) * 32-bit package name size (4-bytes) * >=1-character package name (1 byte) * 32-bit footer size (4 bytes) * 32-bit footer marker (4 bytes) */ #define kMaxBufSize 32768 /* Maximum file read buffer */ Loading @@ -45,8 +46,9 @@ /* offsets in version 1 of the header */ #define kPackageVersionOffset 4 #define kPackageNameLenOffset 8 #define kPackageNameOffset 12 #define kFlagsOffset 8 #define kPackageNameLenOffset 12 #define kPackageNameOffset 16 /* * TEMP_FAILURE_RETRY is defined by some, but not all, versions of Loading Loading @@ -78,7 +80,10 @@ typedef off64_t my_off64_t; namespace android { ObbFile::ObbFile() : mVersion(-1) { mPackageName(""), mVersion(-1), mFlags(0) { } ObbFile::~ObbFile() { Loading Loading @@ -199,6 +204,7 @@ bool ObbFile::parseObbFile(int fd) } mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset); mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset); uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset); if (packageNameLen <= 0 Loading Loading @@ -268,6 +274,12 @@ bool ObbFile::writeTo(int fd) return false; } put4LE(intBuf, mFlags); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { LOGW("couldn't write package version"); return false; } size_t packageNameLen = mPackageName.size(); put4LE(intBuf, packageNameLen); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { Loading @@ -280,7 +292,7 @@ bool ObbFile::writeTo(int fd) return false; } put4LE(intBuf, 3*sizeof(uint32_t) + packageNameLen); put4LE(intBuf, kPackageNameOffset + packageNameLen); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { LOGW("couldn't write footer size: %s", strerror(errno)); return false; Loading Loading
include/ui/InputDispatcher.h +19 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,12 @@ public: virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) = 0; /* Gets the maximum suggested event delivery rate per second. * This value is used to throttle motion event movement actions on a per-device * basis. It is not intended to be a hard limit. */ virtual int32_t getMaxEventsPerSecond() = 0; }; Loading Loading @@ -332,6 +338,8 @@ private: // Linked list of motion samples associated with this motion event. MotionSample firstSample; MotionSample* lastSample; uint32_t countSamples() const; }; // Tracks the progress of dispatching a particular event to a particular connection. Loading Loading @@ -587,6 +595,17 @@ private: Condition mInjectionSyncFinishedCondition; void decrementPendingSyncDispatchesLocked(EventEntry* entry); // Throttling state. struct ThrottleState { nsecs_t minTimeBetweenEvents; nsecs_t lastEventTime; int32_t lastDeviceId; uint32_t lastSource; uint32_t originalSampleCount; // only collected during debugging } mThrottleState; // Key repeat tracking. // XXX Move this up to the input reader instead. struct KeyRepeatState { Loading
include/utils/ObbFile.h +31 −4 Original line number Diff line number Diff line Loading @@ -18,12 +18,16 @@ #define OBBFILE_H_ #include <stdint.h> #include <strings.h> #include <utils/RefBase.h> #include <utils/String8.h> namespace android { // OBB flags (bit 0) #define OBB_OVERLAY (1 << 0) class ObbFile : public RefBase { protected: virtual ~ObbFile(); Loading @@ -46,18 +50,38 @@ public: return mPackageName; } int32_t getVersion() const { return mVersion; } void setPackageName(String8 packageName) { mPackageName = packageName; } int32_t getVersion() const { return mVersion; } void setVersion(int32_t version) { mVersion = version; } int32_t getFlags() const { return mFlags; } void setFlags(int32_t flags) { mFlags = flags; } bool isOverlay() { return (mFlags & OBB_OVERLAY) == OBB_OVERLAY; } void setOverlay(bool overlay) { if (overlay) { mFlags |= OBB_OVERLAY; } else { mFlags &= ~OBB_OVERLAY; } } static inline uint32_t get4LE(const unsigned char* buf) { return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); } Loading @@ -76,6 +100,9 @@ private: /* Package version this ObbFile is associated with */ int32_t mVersion; /* Flags for this OBB type. */ int32_t mFlags; const char* mFileName; size_t mFileSize; Loading
libs/ui/InputDispatcher.cpp +78 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ // Log debug messages about input event injection. #define DEBUG_INJECTION 0 // Log debug messages about input event throttling. #define DEBUG_THROTTLING 0 #include <cutils/log.h> #include <ui/InputDispatcher.h> Loading Loading @@ -66,6 +69,15 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic mKeyRepeatState.lastKeyEntry = NULL; int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond(); mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond; mThrottleState.lastDeviceId = -1; #if DEBUG_THROTTLING mThrottleState.originalSampleCount = 0; LOGD("Throttling - Max events per second = %d", maxEventsPerSecond); #endif mCurrentInputTargetsValid = false; } Loading Loading @@ -144,12 +156,61 @@ void InputDispatcher::dispatchOnce() { } } else { // Inbound queue has at least one entry. // Start processing it but leave it on the queue until later so that the EventEntry* entry = mInboundQueue.head.next; // Consider throttling the entry if it is a move event and there are no // other events behind it in the queue. Due to movement batching, additional // samples may be appended to this event by the time the throttling timeout // expires. // TODO Make this smarter and consider throttling per device independently. if (entry->type == EventEntry::TYPE_MOTION) { MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); int32_t deviceId = motionEntry->deviceId; uint32_t source = motionEntry->source; if (motionEntry->next == & mInboundQueue.tail && motionEntry->action == AMOTION_EVENT_ACTION_MOVE && deviceId == mThrottleState.lastDeviceId && source == mThrottleState.lastSource) { nsecs_t nextTime = mThrottleState.lastEventTime + mThrottleState.minTimeBetweenEvents; if (currentTime < nextTime) { // Throttle it! #if DEBUG_THROTTLING LOGD("Throttling - Delaying motion event for " "device 0x%x, source 0x%08x by up to %0.3fms.", deviceId, source, (nextTime - currentTime) * 0.000001); #endif if (nextTime < nextWakeupTime) { nextWakeupTime = nextTime; } if (mThrottleState.originalSampleCount == 0) { mThrottleState.originalSampleCount = motionEntry->countSamples(); } goto Throttle; } } #if DEBUG_THROTTLING if (mThrottleState.originalSampleCount != 0) { uint32_t count = motionEntry->countSamples(); LOGD("Throttling - Motion event sample count grew by %d from %d to %d.", count - mThrottleState.originalSampleCount, mThrottleState.originalSampleCount, count); mThrottleState.originalSampleCount = 0; } #endif mThrottleState.lastEventTime = entry->eventTime < currentTime ? entry->eventTime : currentTime; mThrottleState.lastDeviceId = deviceId; mThrottleState.lastSource = source; } // Start processing the entry but leave it on the queue until later so that the // input reader can keep appending samples onto a motion event between the // time we started processing it and the time we finally enqueue dispatch // entries for it. EventEntry* entry = mInboundQueue.head.next; switch (entry->type) { case EventEntry::TYPE_CONFIGURATION_CHANGED: { ConfigurationChangedEntry* typedEntry = Loading Loading @@ -179,6 +240,8 @@ void InputDispatcher::dispatchOnce() { mInboundQueue.dequeue(entry); mAllocator.releaseEventEntry(entry); skipPoll = true; Throttle: ; } } Loading @@ -192,8 +255,8 @@ void InputDispatcher::dispatchOnce() { return; } // Wait for callback or timeout or wake. nsecs_t timeout = nanoseconds_to_milliseconds(nextWakeupTime - currentTime); // Wait for callback or timeout or wake. (make sure we round up, not down) nsecs_t timeout = (nextWakeupTime - currentTime + 999999LL) / 1000000LL; int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0; mPollLoop->pollOnce(timeoutMillis); } Loading Loading @@ -1708,6 +1771,16 @@ void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry, motionEntry->lastSample = sample; } // --- InputDispatcher::MotionEntry --- uint32_t InputDispatcher::MotionEntry::countSamples() const { uint32_t count = 1; for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) { count += 1; } return count; } // --- InputDispatcher::Connection --- InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) : Loading
libs/ui/PixelFormat.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,6 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) info->bitsPerPixel = 16; goto done; case HAL_PIXEL_FORMAT_YCrCb_420_SP: case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: case HAL_PIXEL_FORMAT_YV12: info->bitsPerPixel = 12; done: Loading
libs/utils/ObbFile.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -29,12 +29,13 @@ #define kFooterTagSize 8 /* last two 32-bit integers */ #define kFooterMinSize 21 /* 32-bit signature version * 32-bit package version * 32-bit package name size * 1-character package name * 32-bit footer size * 32-bit footer marker #define kFooterMinSize 25 /* 32-bit signature version (4 bytes) * 32-bit package version (4 bytes) * 32-bit flags (4 bytes) * 32-bit package name size (4-bytes) * >=1-character package name (1 byte) * 32-bit footer size (4 bytes) * 32-bit footer marker (4 bytes) */ #define kMaxBufSize 32768 /* Maximum file read buffer */ Loading @@ -45,8 +46,9 @@ /* offsets in version 1 of the header */ #define kPackageVersionOffset 4 #define kPackageNameLenOffset 8 #define kPackageNameOffset 12 #define kFlagsOffset 8 #define kPackageNameLenOffset 12 #define kPackageNameOffset 16 /* * TEMP_FAILURE_RETRY is defined by some, but not all, versions of Loading Loading @@ -78,7 +80,10 @@ typedef off64_t my_off64_t; namespace android { ObbFile::ObbFile() : mVersion(-1) { mPackageName(""), mVersion(-1), mFlags(0) { } ObbFile::~ObbFile() { Loading Loading @@ -199,6 +204,7 @@ bool ObbFile::parseObbFile(int fd) } mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset); mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset); uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset); if (packageNameLen <= 0 Loading Loading @@ -268,6 +274,12 @@ bool ObbFile::writeTo(int fd) return false; } put4LE(intBuf, mFlags); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { LOGW("couldn't write package version"); return false; } size_t packageNameLen = mPackageName.size(); put4LE(intBuf, packageNameLen); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { Loading @@ -280,7 +292,7 @@ bool ObbFile::writeTo(int fd) return false; } put4LE(intBuf, 3*sizeof(uint32_t) + packageNameLen); put4LE(intBuf, kPackageNameOffset + packageNameLen); if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) { LOGW("couldn't write footer size: %s", strerror(errno)); return false; Loading