summaryrefslogtreecommitdiff
path: root/core/java/android/widget/AutoCompleteTextView.java
diff options
context:
space:
mode:
authorGilles Debunne <debunne@google.com>2011-01-17 15:14:32 -0800
committerGilles Debunne <debunne@google.com>2011-01-19 15:10:09 -0800
commitbe2c4f92a990ca48ad6ede252343dd9574dfe505 (patch)
tree4b800d707c3e0f802a7b0ffc29bcabd8fb1f1089 /core/java/android/widget/AutoCompleteTextView.java
parent9240f16d771549b62b5f10efe9f784d87a0afaa4 (diff)
Race condition patched in Email autocompletion.
Bug 3347962 Root cause of this problem: if the adapter's content gets updated by a backgroung thread, the PopupDataSetObserver will call showDropDown which will popup the list. Added a flag to make this call show the popup iif it is already visible. This relayout is needed to clear the mDataChanged flag set when the content was modified and which otherwise prevents touch events on the result list. ArrayAdapter didn't use its lock to protect access to mObject. ------------------------------------------------- However, the study of the this race conditions revealed an other bug: Updated adapter's content is not displayed in filtered AutoCompleteTextView Bug 3369097 Change-Id: Icd90d452f98231866f4d8a1f6994c1492febecb9
Diffstat (limited to 'core/java/android/widget/AutoCompleteTextView.java')
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java23
1 files changed, 15 insertions, 8 deletions
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4d8d21f4a3e0..707b92d5c164 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
@@ -36,8 +38,6 @@ import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import com.android.internal.R;
-
/**
* <p>An editable text view that shows completion suggestions automatically
@@ -113,6 +113,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private Validator mValidator = null;
+ // Set to true when text is set directly and no filtering shall be performed
private boolean mBlockCompletion;
private PassThroughClickListener mPassThroughClickListener;
@@ -721,6 +722,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
return;
}
+ updateList();
+ }
+
+ private void updateList() {
// the drop down is shown only when a minimum number of characters
// was typed in the text view
if (enoughToFilter()) {
@@ -840,7 +845,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
mBlockCompletion = true;
replaceText(convertSelectionToString(selectedItem));
- mBlockCompletion = false;
+ mBlockCompletion = false;
if (mItemClickListener != null) {
final ListPopupWindow list = mPopup;
@@ -903,10 +908,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
/** {@inheritDoc} */
public void onFilterComplete(int count) {
- updateDropDownForFilter(count);
+ updateDropDownForFilter(count, true);
}
- private void updateDropDownForFilter(int count) {
+ private void updateDropDownForFilter(int count, boolean forceShow) {
// Not attached to window, don't update drop-down
if (getWindowVisibility() == View.GONE) return;
@@ -919,7 +924,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
- if (hasFocus() && hasWindowFocus()) {
+ if (hasFocus() && hasWindowFocus() && (forceShow || isPopupShowing())) {
showDropDown();
}
} else if (!dropDownAlwaysVisible) {
@@ -1182,12 +1187,14 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
// If the popup is not showing already, showing it will cause
// the list of data set observers attached to the adapter to
// change. We can't do it from here, because we are in the middle
- // of iterating throught he list of observers.
+ // of iterating through the list of observers.
post(new Runnable() {
public void run() {
final ListAdapter adapter = mAdapter;
if (adapter != null) {
- updateDropDownForFilter(adapter.getCount());
+ // This will re-layout, thus resetting mDataChanged, so that the
+ // listView click listener stays responsive
+ updateDropDownForFilter(adapter.getCount(), false);
}
}
});