1 package com.android.mms.data;
2 
3 import java.util.ArrayList;
4 import java.util.List;
5 
6 import android.net.Uri;
7 import android.os.Parcelable;
8 import android.text.TextUtils;
9 import android.util.Log;
10 
11 import com.android.mms.LogTag;
12 import com.android.mms.ui.MessageUtils;
13 
14 public class ContactList extends ArrayList<Contact>  {
15     private static final long serialVersionUID = 1L;
16 
getByNumbers(Iterable<String> numbers, boolean canBlock)17     public static ContactList getByNumbers(Iterable<String> numbers, boolean canBlock) {
18         ContactList list = new ContactList();
19         for (String number : numbers) {
20             if (!TextUtils.isEmpty(number)) {
21                 list.add(Contact.get(number, canBlock));
22             }
23         }
24         return list;
25     }
26 
getByNumbers(String semiSepNumbers, boolean canBlock, boolean replaceNumber)27     public static ContactList getByNumbers(String semiSepNumbers,
28                                            boolean canBlock,
29                                            boolean replaceNumber) {
30         ContactList list = new ContactList();
31         for (String number : semiSepNumbers.split(";")) {
32             if (!TextUtils.isEmpty(number)) {
33                 Contact contact = Contact.get(number, canBlock);
34                 if (replaceNumber) {
35                     contact.setNumber(number);
36                 }
37                 list.add(contact);
38             }
39         }
40         return list;
41     }
42 
43     /**
44      * Returns a ContactList for the corresponding recipient URIs passed in. This method will
45      * always block to query provider. The given URIs could be the phone data URIs or tel URI
46      * for the numbers don't belong to any contact.
47      *
48      * @param uris phone URI to create the ContactList
49      */
blockingGetByUris(Parcelable[] uris)50     public static ContactList blockingGetByUris(Parcelable[] uris) {
51         ContactList list = new ContactList();
52         if (uris != null && uris.length > 0) {
53             for (Parcelable p : uris) {
54                 Uri uri = (Uri) p;
55                 if ("tel".equals(uri.getScheme())) {
56                     Contact contact = Contact.get(uri.getSchemeSpecificPart(), true);
57                     list.add(contact);
58                 }
59             }
60             final List<Contact> contacts = Contact.getByPhoneUris(uris);
61             if (contacts != null) {
62                 list.addAll(contacts);
63             }
64         }
65         return list;
66     }
67 
68     /**
69      * Returns a ContactList for the corresponding recipient ids passed in. This method will
70      * create the contact if it doesn't exist, and would inject the recipient id into the contact.
71      */
getByIds(String spaceSepIds, boolean canBlock)72     public static ContactList getByIds(String spaceSepIds, boolean canBlock) {
73         ContactList list = new ContactList();
74         for (RecipientIdCache.Entry entry : RecipientIdCache.getAddresses(spaceSepIds)) {
75             if (entry != null && !TextUtils.isEmpty(entry.number)) {
76                 Contact contact = Contact.get(entry.number, canBlock);
77                 contact.setRecipientId(entry.id);
78                 list.add(contact);
79             }
80         }
81         return list;
82     }
83 
getPresenceResId()84     public int getPresenceResId() {
85         // We only show presence for single contacts.
86         if (size() != 1)
87             return 0;
88 
89         return get(0).getPresenceResId();
90     }
91 
formatNames(String separator)92     public String formatNames(String separator) {
93         String[] names = new String[size()];
94         int i = 0;
95         for (Contact c : this) {
96             names[i++] = c.getName();
97         }
98         return TextUtils.join(separator, names);
99     }
100 
formatNamesAndNumbers(String separator)101     public String formatNamesAndNumbers(String separator) {
102         String[] nans = new String[size()];
103         int i = 0;
104         for (Contact c : this) {
105             nans[i++] = c.getNameAndNumber();
106         }
107         return TextUtils.join(separator, nans);
108     }
109 
serialize()110     public String serialize() {
111         return TextUtils.join(";", getNumbers());
112     }
113 
containsEmail()114     public boolean containsEmail() {
115         for (Contact c : this) {
116             if (c.isEmail()) {
117                 return true;
118             }
119         }
120         return false;
121     }
122 
getNumbers()123     public String[] getNumbers() {
124         return getNumbers(false /* don't scrub for MMS address */);
125     }
126 
getNumbers(boolean scrubForMmsAddress)127     public String[] getNumbers(boolean scrubForMmsAddress) {
128         List<String> numbers = new ArrayList<String>();
129         String number;
130         for (Contact c : this) {
131             number = c.getNumber();
132 
133             if (scrubForMmsAddress) {
134                 // parse/scrub the address for valid MMS address. The returned number
135                 // could be null if it's not a valid MMS address. We don't want to send
136                 // a message to an invalid number, as the network may do its own stripping,
137                 // and end up sending the message to a different number!
138                 number = MessageUtils.parseMmsAddress(number);
139             }
140 
141             // Don't add duplicate numbers. This can happen if a contact name has a comma.
142             // Since we use a comma as a delimiter between contacts, the code will consider
143             // the same recipient has been added twice. The recipients UI still works correctly.
144             // It's easiest to just make sure we only send to the same recipient once.
145             if (!TextUtils.isEmpty(number) && !numbers.contains(number)) {
146                 numbers.add(number);
147             }
148         }
149         return numbers.toArray(new String[numbers.size()]);
150     }
151 
152     @Override
equals(Object obj)153     public boolean equals(Object obj) {
154         try {
155             ContactList other = (ContactList)obj;
156             // If they're different sizes, the contact
157             // set is obviously different.
158             if (size() != other.size()) {
159                 return false;
160             }
161 
162             // Make sure all the individual contacts are the same.
163             for (Contact c : this) {
164                 if (!other.contains(c)) {
165                     return false;
166                 }
167             }
168 
169             return true;
170         } catch (ClassCastException e) {
171             return false;
172         }
173     }
174 
log(String msg)175     private void log(String msg) {
176         Log.d(LogTag.TAG, "[ContactList] " + msg);
177     }
178 }
179