Merge "Race condition patched in Email autocompletion." into honeycomb

This commit is contained in:
Gilles Debunne
2011-01-19 16:08:20 -08:00
committed by Android (Google) Code Review
3 changed files with 58 additions and 46 deletions

View File

@@ -817,7 +817,7 @@ public interface WindowManager extends ViewManager {
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
/**
* Desired operating mode for any soft input area. May any combination
* Desired operating mode for any soft input area. May be any combination
* of:
*
* <ul>

View File

@@ -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);

View File

@@ -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);
}
}
});