summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget/ArrayAdapter.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/ArrayAdapter.java
parent9240f16d771549b62b5f10efe9f784d87a0afaa4 (diff)
downloadframeworks_base-be2c4f92a990ca48ad6ede252343dd9574dfe505.zip
frameworks_base-be2c4f92a990ca48ad6ede252343dd9574dfe505.tar.gz
frameworks_base-be2c4f92a990ca48ad6ede252343dd9574dfe505.tar.bz2
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/ArrayAdapter.java')
-rw-r--r--core/java/android/widget/ArrayAdapter.java79
1 files changed, 42 insertions, 37 deletions
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index b4ece24..593cb59 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,9 +25,9 @@ import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
-import java.util.Comparator;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* A concrete BaseAdapter that is backed by an array of arbitrary
@@ -86,6 +86,8 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
private Context mContext;
+ // A copy of the original mObjects array, initialized from and then used instead as soon as
+ // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
private ArrayList<T> mOriginalValues;
private ArrayFilter mFilter;
@@ -170,15 +172,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param object The object to add at the end of the array.
*/
public void add(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(object);
}
- } else {
- mObjects.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -187,15 +188,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param collection The Collection to add at the end of the array.
*/
public void addAll(Collection<? extends T> collection) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.addAll(collection);
}
- } else {
- mObjects.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -204,19 +204,18 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param items The items to add at the end of the array.
*/
public void addAll(T ... items) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
for (T item : items) {
mOriginalValues.add(item);
}
- if (mNotifyOnChange) notifyDataSetChanged();
- }
- } else {
- for (T item : items) {
- mObjects.add(item);
+ } else {
+ for (T item : items) {
+ mObjects.add(item);
+ }
}
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -226,15 +225,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param index The index at which the object must be inserted.
*/
public void insert(T object, int index) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(index, object);
}
- } else {
- mObjects.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -243,12 +241,12 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* @param object The object to remove.
*/
public void remove(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.remove(object);
+ } else {
+ mObjects.remove(object);
}
- } else {
- mObjects.remove(object);
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -257,12 +255,12 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* Remove all elements from the list.
*/
public void clear() {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.clear();
+ } else {
+ mObjects.clear();
}
- } else {
- mObjects.clear();
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -274,7 +272,13 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
* in this adapter.
*/
public void sort(Comparator<? super T> comparator) {
- Collections.sort(mObjects, comparator);
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
+ Collections.sort(mOriginalValues, comparator);
+ } else {
+ Collections.sort(mObjects, comparator);
+ }
+ }
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -482,6 +486,7 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
+ // Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);