summaryrefslogtreecommitdiffstats
path: root/libs/androidfw
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-03-13 15:00:09 -0700
committerJeff Brown <jeffbrown@google.com>2012-03-13 15:00:09 -0700
commit2b6c32ca4177f1a97307f9cbd81ca485df28762c (patch)
treeabc217f8ff191ce1ecc7c4eb9b51185b6d47625d /libs/androidfw
parentb2679481b57d87945df02983f95ff8e6c9ba5928 (diff)
downloadframeworks_base-2b6c32ca4177f1a97307f9cbd81ca485df28762c.zip
frameworks_base-2b6c32ca4177f1a97307f9cbd81ca485df28762c.tar.gz
frameworks_base-2b6c32ca4177f1a97307f9cbd81ca485df28762c.tar.bz2
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
Diffstat (limited to 'libs/androidfw')
-rw-r--r--libs/androidfw/Input.cpp52
-rw-r--r--libs/androidfw/InputTransport.cpp4
2 files changed, 56 insertions, 0 deletions
diff --git a/libs/androidfw/Input.cpp b/libs/androidfw/Input.cpp
index ca09caf..da57839 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<KeyEvent*>(event));
+ return;
+ }
+ break;
+ case AINPUT_EVENT_TYPE_MOTION:
+ if (mMotionEventPool.size() < mMaxPoolSize) {
+ mMotionEventPool.push(static_cast<MotionEvent*>(event));
+ return;
+ }
+ break;
+ }
+ delete event;
+}
+
+
// --- VelocityTracker ---
const uint32_t VelocityTracker::DEFAULT_DEGREE;
diff --git a/libs/androidfw/InputTransport.cpp b/libs/androidfw/InputTransport.cpp
index 1ebd75c..294236f 100644
--- a/libs/androidfw/InputTransport.cpp
+++ b/libs/androidfw/InputTransport.cpp
@@ -527,6 +527,10 @@ status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled)
return mChannel->sendMessage(&msg);
}
+bool InputConsumer::hasDeferredEvent() const {
+ return mMsgDeferred;
+}
+
bool InputConsumer::hasPendingBatch() const {
return !mBatches.isEmpty();
}