summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Brown <jeffbrown@google.com> 2013-04-03 14:39:19 -0700
committer Jeff Brown <jeffbrown@google.com> 2013-04-03 14:40:57 -0700
commit4d656885ed9afec7d758c1862df6f040f5fe16a9 (patch)
tree7d6370f50da0dc13618036a09ee3bf4c6ca0b05b
parentd72317abd79ddf95d48c8f35bf1070900ff55b5e (diff)
Clear mCurSender when mCurChannel is modified.
This fixed an issue where an InputEventSender might outlive its usefulness and continue to be used well after it should have been disposed or recreated. Also improves the queue management somewhat. Bug: 8493879 Change-Id: I7e0b6a3c43cbe72f8762991f5d36560feebd214b
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java85
1 files changed, 42 insertions, 43 deletions
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7f9969cfcc5c..855b6d4fc126 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -325,7 +325,8 @@ public final class InputMethodManager {
PendingEvent mPendingEventPool;
int mPendingEventPoolSize;
- PendingEvent mFirstPendingEvent;
+ PendingEvent mPendingEventHead;
+ PendingEvent mPendingEventTail;
// -----------------------------------------------------------
@@ -366,18 +367,14 @@ public final class InputMethodManager {
if (mBindSequence < 0 || mBindSequence != res.sequence) {
Log.w(TAG, "Ignoring onBind: cur seq=" + mBindSequence
+ ", given seq=" + res.sequence);
- if (res.channel != null) {
+ if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
}
return;
}
-
- flushPendingEventsLocked();
+
+ setInputChannelLocked(res.channel);
mCurMethod = res.method;
- if (mCurChannel != null) {
- mCurChannel.dispose();
- }
- mCurChannel = res.channel;
mCurId = res.id;
mBindSequence = res.sequence;
}
@@ -719,20 +716,26 @@ public final class InputMethodManager {
*/
void clearBindingLocked() {
clearConnectionLocked();
- flushPendingEventsLocked();
+ setInputChannelLocked(null);
mBindSequence = -1;
mCurId = null;
mCurMethod = null;
- if (mCurSender != null) {
- mCurSender.dispose();
- mCurSender = null;
- }
- if (mCurChannel != null) {
- mCurChannel.dispose();
- mCurChannel = null;
+ }
+
+ void setInputChannelLocked(InputChannel channel) {
+ if (mCurChannel != channel) {
+ if (mCurSender != null) {
+ flushPendingEventsLocked();
+ mCurSender.dispose();
+ mCurSender = null;
+ }
+ if (mCurChannel != null) {
+ mCurChannel.dispose();
+ }
+ mCurChannel = channel;
}
}
-
+
/**
* Reset all of the state associated with a served view being connected
* to an input method
@@ -1174,15 +1177,12 @@ public final class InputMethodManager {
if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
if (res != null) {
if (res.id != null) {
+ setInputChannelLocked(res.channel);
mBindSequence = res.sequence;
mCurMethod = res.method;
- if (mCurChannel != null) {
- mCurChannel.dispose();
- }
- mCurChannel = res.channel;
mCurId = res.id;
} else {
- if (res.channel != null) {
+ if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
}
if (mCurMethod == null) {
@@ -1655,8 +1655,13 @@ public final class InputMethodManager {
private void enqueuePendingEventLocked(
long startTime, int seq, String inputMethodId, FinishedEventCallback callback) {
PendingEvent p = obtainPendingEventLocked(startTime, seq, inputMethodId, callback);
- p.mNext = mFirstPendingEvent;
- mFirstPendingEvent = p;
+ if (mPendingEventTail != null) {
+ mPendingEventTail.mNext = p;
+ mPendingEventTail = p;
+ } else {
+ mPendingEventHead = p;
+ mPendingEventTail = p;
+ }
Message msg = mH.obtainMessage(MSG_EVENT_TIMEOUT, seq, 0, p);
msg.setAsynchronous(true);
@@ -1664,12 +1669,15 @@ public final class InputMethodManager {
}
private PendingEvent dequeuePendingEventLocked(int seq) {
- PendingEvent p = mFirstPendingEvent;
+ PendingEvent p = mPendingEventHead;
if (p == null) {
return null;
}
if (p.mSeq == seq) {
- mFirstPendingEvent = p.mNext;
+ mPendingEventHead = p.mNext;
+ if (mPendingEventHead == null) {
+ mPendingEventTail = null;
+ }
} else {
PendingEvent prev;
do {
@@ -1680,6 +1688,9 @@ public final class InputMethodManager {
}
} while (p.mSeq != seq);
prev.mNext = p.mNext;
+ if (mPendingEventTail == p) {
+ mPendingEventTail = prev;
+ }
}
p.mNext = null;
return p;
@@ -1716,25 +1727,13 @@ public final class InputMethodManager {
private void flushPendingEventsLocked() {
mH.removeMessages(MSG_EVENT_TIMEOUT);
- PendingEvent curr, prev, next;
- curr = mFirstPendingEvent;
- prev = null;
- while (curr != null) {
- next = curr.mNext;
- curr.mNext = prev;
- prev = curr;
- curr = next;
- }
- curr = prev;
- prev = null;
- while (curr != null) {
- Message msg = mH.obtainMessage(MSG_EVENT_TIMEOUT, curr.mSeq, 0, curr);
+
+ PendingEvent p = mPendingEventHead;
+ while (p != null) {
+ Message msg = mH.obtainMessage(MSG_EVENT_TIMEOUT, p.mSeq, 0, p);
msg.setAsynchronous(true);
mH.sendMessage(msg);
- next = curr.mNext;
- curr.mNext = prev;
- prev = curr;
- curr = next;
+ p = p.mNext;
}
}