Fix race condition.

Crash was reported where the checked item position had yet to be
set when the list tried to get it. This uses a listener to make sure
that the checked item isnt set in the list until the adapter has it.

Change-Id: I2b5170ab9440bbb0a69989657313b1a4b6d653cd
diff --git a/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/src/com/android/ex/chips/RecipientAlternatesAdapter.java
index 3d2c87b..792fdcc 100644
--- a/src/com/android/ex/chips/RecipientAlternatesAdapter.java
+++ b/src/com/android/ex/chips/RecipientAlternatesAdapter.java
@@ -37,7 +37,10 @@
 
     private int mCheckedItemPosition = -1;
 
-    public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId) {
+    private OnCheckedItemChangedListener mCheckedItemChangedListener;
+
+    public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId,
+            OnCheckedItemChangedListener listener) {
         super(context, context.getContentResolver().query(Email.CONTENT_URI, EmailQuery.PROJECTION,
                 Email.CONTACT_ID + " =?", new String[] {
                     String.valueOf(contactId)
@@ -45,6 +48,7 @@
         mLayoutInflater = LayoutInflater.from(context);
         mLayoutId = viewId;
         mCurrentId = currentId;
+        mCheckedItemChangedListener = listener;
     }
 
     @Override
@@ -71,6 +75,9 @@
         }
         if (cursor.getLong(EmailQuery.DATA_ID) == mCurrentId) {
             mCheckedItemPosition = position;
+            if (mCheckedItemChangedListener != null) {
+                mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
+            }
         }
         bindView(convertView, convertView.getContext(), cursor);
         return convertView;
@@ -109,10 +116,7 @@
         return mLayoutInflater.inflate(mLayoutId, null);
     }
 
-    /**
-     * Get the position of the item that should be checked.
-     */
-    public int getCheckedItemPosition() {
-        return mCheckedItemPosition;
+    /*package*/ static interface OnCheckedItemChangedListener {
+        public void onCheckedItemChanged(int position);
     }
 }
diff --git a/src/com/android/ex/chips/RecipientEditTextView.java b/src/com/android/ex/chips/RecipientEditTextView.java
index 7cda831..9819e02 100644
--- a/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/src/com/android/ex/chips/RecipientEditTextView.java
@@ -921,7 +921,8 @@
      * RecipientChip defines an ImageSpan that contains information relevant to
      * a particular recipient.
      */
-    public class RecipientChip extends ImageSpan implements OnItemClickListener {
+    public class RecipientChip extends ImageSpan implements OnItemClickListener,
+            RecipientAlternatesAdapter.OnCheckedItemChangedListener {
         private final CharSequence mDisplay;
 
         private final CharSequence mValue;
@@ -944,6 +945,8 @@
 
         private ListPopupWindow mAlternatesPopup;
 
+        private int mCheckedItem;
+
         public RecipientChip(Drawable drawable, RecipientEntry entry, int offset) {
             super(drawable);
             mDisplay = entry.getDisplayName();
@@ -1159,8 +1162,9 @@
                 int bottom = calculateLineBottom(xy[1], line, (int) mChipHeight);
                 mAnchorView.setBottom(bottom);
                 mAnchorView.setTop(bottom);
-                mAlternatesAdapter = new RecipientAlternatesAdapter(getContext(),
-                        mEntry.getContactId(), mEntry.getDataId(), mAlternatesLayout);
+                mCheckedItem = -1;
+                mAlternatesAdapter = new RecipientAlternatesAdapter(getContext(), mEntry
+                        .getContactId(), mEntry.getDataId(), mAlternatesLayout, this);
                 // Align the alternates popup with the left side of the View, regardless
                 // of the position of the chip tapped.
                 mAlternatesPopup.setAnchorView(mAnchorView);
@@ -1170,7 +1174,23 @@
                 mAlternatesPopup.show();
                 ListView listView = mAlternatesPopup.getListView();
                 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-                listView.setItemChecked(mAlternatesAdapter.getCheckedItemPosition(), true);
+                // Checked item would be -1 if the adapter has not
+                // loaded the view that should be checked yet. The
+                // variable will be set correctly when onCheckedItemChanged
+                // is called in a separate thread.
+                if (mCheckedItem != -1) {
+                    listView.setItemChecked(mCheckedItem, true);
+                }
+            }
+        }
+
+        @Override
+        public void onCheckedItemChanged(int position) {
+            ListView listView = mAlternatesPopup.getListView();
+            if (listView != null && listView.getCheckedItemCount() == 0) {
+                listView.setItemChecked(position, true);
+            } else {
+                mCheckedItem = position;
             }
         }