1package com.android.mms.data;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import android.net.Uri;
7import android.os.Parcelable;
8import android.text.TextUtils;
9import android.util.Log;
10
11import com.android.mms.LogTag;
12import com.android.mms.ui.MessageUtils;
13
14public class ContactList extends ArrayList<Contact>  {
15    private static final long serialVersionUID = 1L;
16
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
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     */
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     */
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
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
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
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
110    public String serialize() {
111        return TextUtils.join(";", getNumbers());
112    }
113
114    public boolean containsEmail() {
115        for (Contact c : this) {
116            if (c.isEmail()) {
117                return true;
118            }
119        }
120        return false;
121    }
122
123    public String[] getNumbers() {
124        return getNumbers(false /* don't scrub for MMS address */);
125    }
126
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
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
175    private void log(String msg) {
176        Log.d(LogTag.TAG, "[ContactList] " + msg);
177    }
178}
179