Allow support for alternate data sources.

BaseRecipientAdapter adds a bunch of methods that can be
overridden to change the default behavior. Also makes a bunch
of private methods protected so that derived classes can use those
methods.

Abstracts the calls to update the various internal data structures
so that derived classes can utilize their own structures by just
overriding a few methods.

Refactors photo loading into the PhotoManager interface
with a default implementation living in DefaultPhotoManager.

Provides the ability to not use the RecipientAlternatesAdapter
and instead just use SingleRecipientAddressAdapter when showing
a dropdown after clicking on a chip.

Also allows overriding the default behavior for creating chips
when pasting in email addresses or editing drafts.

b/11387812

Change-Id: I826c30edeee1752b7a3d4108e777f90b79d0f7f8
diff --git a/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/src/com/android/ex/chips/RecipientAlternatesAdapter.java
index f6f662d..d091fa6 100644
--- a/src/com/android/ex/chips/RecipientAlternatesAdapter.java
+++ b/src/com/android/ex/chips/RecipientAlternatesAdapter.java
@@ -49,7 +49,7 @@
  * queried by email or by phone number.
  */
 public class RecipientAlternatesAdapter extends CursorAdapter {
-    static final int MAX_LOOKUPS = 50;
+    public static final int MAX_LOOKUPS = 50;
 
     private final long mCurrentId;
 
@@ -87,7 +87,6 @@
      * @param context Context.
      * @param inAddresses Array of addresses on which to perform the lookup.
      * @param callback RecipientMatchCallback called when a match or matches are found.
-     * @return HashMap<String,RecipientEntry>
      */
     public static void getMatchingRecipients(Context context, BaseRecipientAdapter adapter,
             ArrayList<String> inAddresses, int addressType, Account account,
@@ -133,9 +132,31 @@
                 c.close();
             }
         }
+
+        final Set<String> matchesNotFound = new HashSet<String>();
+
+        getMatchingRecipientsFromDirectoryQueries(context, recipientEntries,
+                addresses, account, matchesNotFound, query, callback);
+
+        getMatchingRecipientsFromExtensionMatcher(adapter, matchesNotFound, callback);
+    }
+
+    public static void getMatchingRecipientsFromDirectoryQueries(Context context,
+            Map<String, RecipientEntry> recipientEntries, Set<String> addresses,
+            Account account, Set<String> matchesNotFound,
+            RecipientMatchCallback callback) {
+        getMatchingRecipientsFromDirectoryQueries(
+                context, recipientEntries, addresses, account,
+                matchesNotFound, Queries.EMAIL, callback);
+    }
+
+    private static void getMatchingRecipientsFromDirectoryQueries(Context context,
+            Map<String, RecipientEntry> recipientEntries, Set<String> addresses,
+            Account account, Set<String> matchesNotFound, Queries.Query query,
+            RecipientMatchCallback callback) {
         // See if any entries did not resolve; if so, we need to check other
         // directories
-        final Set<String> matchesNotFound = new HashSet<String>();
+
         if (recipientEntries.size() < addresses.size()) {
             final List<DirectorySearchParams> paramsList;
             Cursor directoryCursor = null;
@@ -200,7 +221,10 @@
                 }
             }
         }
+    }
 
+    public static void getMatchingRecipientsFromExtensionMatcher(BaseRecipientAdapter adapter,
+            Set<String> matchesNotFound, RecipientMatchCallback callback) {
         // If no matches found in contact provider or the directories, try the extension
         // matcher.
         // todo (aalbert): This whole method needs to be in the adapter?