From 2b6c32ca4177f1a97307f9cbd81ca485df28762c Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Tue, 13 Mar 2012 15:00:09 -0700 Subject: Fix spurious ANRs in native activities. Some native activities experienced ANRs when the input consumer deferred an input event due to client-side batching. If the input channel was fully emptied then the client had no way of knowing that it should wake up to handle the deferred input event. This patch also fixes some lock issues in the native activity input queue implementation. In at least one error case, it was possible for a function to exit without releasing the lock. Bug: 6051176 Change-Id: I4d9d843237e69b9834f8d8b360031b677fcab8c3 --- libs/androidfw/Input.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'libs/androidfw/Input.cpp') diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp index ca09caf6a255..da578395500e 100644 --- a/libs/androidfw/Input.cpp +++ b/libs/androidfw/Input.cpp @@ -683,6 +683,58 @@ bool MotionEvent::isTouchEvent(int32_t source, int32_t action) { } +// --- 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(event)); + return; + } + break; + case AINPUT_EVENT_TYPE_MOTION: + if (mMotionEventPool.size() < mMaxPoolSize) { + mMotionEventPool.push(static_cast(event)); + return; + } + break; + } + delete event; +} + + // --- VelocityTracker --- const uint32_t VelocityTracker::DEFAULT_DEGREE; -- cgit v1.2.3-59-g8ed1b