11d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickpackage com.android.mms.data;
21d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
31d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport java.util.ArrayList;
41d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport java.util.HashMap;
51d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport java.util.List;
61d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport java.util.Map;
71d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
8ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrickimport javax.annotation.concurrent.GuardedBy;
9ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrickimport javax.annotation.concurrent.ThreadSafe;
10ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick
11415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrickimport android.content.ContentResolver;
12431e11d429783c07eca6e789de0518d17b42fb74Wei Huangimport android.content.ContentUris;
13d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.ContentValues;
14d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.Context;
151d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport android.database.Cursor;
16d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.database.sqlite.SqliteWrapper;
171d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport android.net.Uri;
18d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.provider.Telephony;
198074e71a4cdf1a8548743e38155f1bcea04d05feTom Taylorimport android.text.TextUtils;
201d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickimport android.util.Log;
211d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
22431e11d429783c07eca6e789de0518d17b42fb74Wei Huangimport com.android.mms.LogTag;
231d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
24ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick@ThreadSafe
251d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrickpublic class RecipientIdCache {
265e99cf133219e11a0a3ec1f37131b7d6811b7fb3Tom Taylor    private static final boolean LOCAL_DEBUG = false;
27431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    private static final String TAG = "Mms/cache";
28431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
29431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    private static Uri sAllCanonical =
30431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            Uri.parse("content://mms-sms/canonical-addresses");
31431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
32431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    private static Uri sSingleCanonicalAddressUri =
33431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            Uri.parse("content://mms-sms/canonical-address");
341d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
351d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    private static RecipientIdCache sInstance;
361d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    static RecipientIdCache getInstance() { return sInstance; }
37ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick
38ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick    @GuardedBy("this")
39431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    private final Map<Long, String> mCache;
40ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick
411d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    private final Context mContext;
421d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
43431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    public static class Entry {
44431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        public long id;
45431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        public String number;
46431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
47431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        public Entry(long id, String number) {
48431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            this.id = id;
49431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            this.number = number;
50431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        }
51431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    };
52431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
531d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    static void init(Context context) {
541d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        sInstance = new RecipientIdCache(context);
551d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        new Thread(new Runnable() {
561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            public void run() {
571d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                fill();
581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
59ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev        }, "RecipientIdCache.init").start();
601d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
611d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
621d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    RecipientIdCache(Context context) {
63431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        mCache = new HashMap<Long, String>();
641d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        mContext = context;
651d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
661d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
671d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    public static void fill() {
68b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        if (LogTag.VERBOSE || Log.isLoggable(LogTag.THREAD_CACHE, Log.VERBOSE)) {
6909a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            LogTag.debug("[RecipientIdCache] fill: begin");
7009a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
7109a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
721d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        Context context = sInstance.mContext;
731d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
741d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                sAllCanonical, null, null, null, null);
75db8958a358ad2aa4766027893f3d324007ab976cBrad Fitzpatrick        if (c == null) {
76db8958a358ad2aa4766027893f3d324007ab976cBrad Fitzpatrick            Log.w(TAG, "null Cursor in fill()");
77db8958a358ad2aa4766027893f3d324007ab976cBrad Fitzpatrick            return;
78db8958a358ad2aa4766027893f3d324007ab976cBrad Fitzpatrick        }
79431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
801d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        try {
811d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            synchronized (sInstance) {
821d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                // Technically we don't have to clear this because the stupid
831d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                // canonical_addresses table is never GC'ed.
841d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                sInstance.mCache.clear();
851d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                while (c.moveToNext()) {
86431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    // TODO: don't hardcode the column indices
87431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    long id = c.getLong(0);
881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    String number = c.getString(1);
891d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    sInstance.mCache.put(id, number);
901d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                }
911d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
921d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        } finally {
931d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            c.close();
941d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
9509a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
96b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        if (LogTag.VERBOSE || Log.isLoggable(LogTag.THREAD_CACHE, Log.VERBOSE)) {
9709a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            LogTag.debug("[RecipientIdCache] fill: finished");
9809a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            dump();
9909a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
1001d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
1011d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
102431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    public static List<Entry> getAddresses(String spaceSepIds) {
1031d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        synchronized (sInstance) {
104431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            List<Entry> numbers = new ArrayList<Entry>();
1051d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            String[] ids = spaceSepIds.split(" ");
1061d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            for (String id : ids) {
107431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                long longId;
108431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
109431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                try {
110431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    longId = Long.parseLong(id);
111431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                } catch (NumberFormatException ex) {
112431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    // skip this id
113431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    continue;
114431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                }
115431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
116431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                String number = sInstance.mCache.get(longId);
117431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
1181d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (number == null) {
1196595d80abc6ab706ae296e9e51351c8ef6299219Wei Huang                    Log.w(TAG, "RecipientId " + longId + " not in cache!");
12009a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                    if (Log.isLoggable(LogTag.THREAD_CACHE, Log.VERBOSE)) {
12109a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                        dump();
12209a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                    }
123ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick
1241d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    fill();
1256595d80abc6ab706ae296e9e51351c8ef6299219Wei Huang                    number = sInstance.mCache.get(longId);
126431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                }
127431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
1288074e71a4cdf1a8548743e38155f1bcea04d05feTom Taylor                if (TextUtils.isEmpty(number)) {
1296595d80abc6ab706ae296e9e51351c8ef6299219Wei Huang                    Log.w(TAG, "RecipientId " + longId + " has empty number!");
1308074e71a4cdf1a8548743e38155f1bcea04d05feTom Taylor                } else {
131431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    numbers.add(new Entry(longId, number));
1321d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                }
1331d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
1341d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            return numbers;
1351d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
1361d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
1371d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
138431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    public static void updateNumbers(long threadId, ContactList contacts) {
139431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        long recipientId = 0;
140431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
141431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        for (Contact contact : contacts) {
142431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            if (contact.isNumberModified()) {
143431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                contact.setIsNumberModified(false);
144431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            } else {
145431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                // if the contact's number wasn't modified, don't bother.
146431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                continue;
147431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            }
148431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
149431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            recipientId = contact.getRecipientId();
150431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            if (recipientId == 0) {
151431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                continue;
152431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            }
153431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
154431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            String number1 = contact.getNumber();
155ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick            boolean needsDbUpdate = false;
156ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick            synchronized (sInstance) {
157ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                String number2 = sInstance.mCache.get(recipientId);
158431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
159ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
160b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                    Log.d(TAG, "[RecipientIdCache] updateNumbers: contact=" + contact +
161b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                            ", wasModified=true, recipientId=" + recipientId);
162b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                    Log.d(TAG, "   contact.getNumber=" + number1 +
163b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                            ", sInstance.mCache.get(recipientId)=" + number2);
164ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                }
165e86abc71912704dd67664a44a33e84d5847ca64bBrad Fitzpatrick
166ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                // if the numbers don't match, let's update the RecipientIdCache's number
167ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                // with the new number in the contact.
168ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                if (!number1.equalsIgnoreCase(number2)) {
169ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                    sInstance.mCache.put(recipientId, number1);
170ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                    needsDbUpdate = true;
171ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                }
172ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick            }
173ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick            if (needsDbUpdate) {
174ccc3a9219b3e1d1cff5dde3c13ecea1bb06226c3Brad Fitzpatrick                // Do this without the lock held.
175431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                sInstance.updateCanonicalAddressInDb(recipientId, number1);
176431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            }
177431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        }
178431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    }
179431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
180431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    private void updateCanonicalAddressInDb(long id, String number) {
181b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        if (LogTag.VERBOSE || Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
182431e11d429783c07eca6e789de0518d17b42fb74Wei Huang            Log.d(TAG, "[RecipientIdCache] updateCanonicalAddressInDb: id=" + id +
183431e11d429783c07eca6e789de0518d17b42fb74Wei Huang                    ", number=" + number);
184431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        }
185431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
186415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        final ContentValues values = new ContentValues();
187f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylor        values.put(Telephony.CanonicalAddressesColumns.ADDRESS, number);
188431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
189415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        final StringBuilder buf = new StringBuilder(Telephony.CanonicalAddressesColumns._ID);
190431e11d429783c07eca6e789de0518d17b42fb74Wei Huang        buf.append('=').append(id);
191431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
192415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        final Uri uri = ContentUris.withAppendedId(sSingleCanonicalAddressUri, id);
193415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        final ContentResolver cr = mContext.getContentResolver();
194415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick
195415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        // We're running on the UI thread so just fire & forget, hope for the best.
196415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        // (We were ignoring the return value anyway...)
197415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        new Thread("updateCanonicalAddressInDb") {
198415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick            public void run() {
199415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick                cr.update(uri, values, buf.toString(), null);
200415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick            }
201415dc85e9a69638b69c097cc3f263a48712be3d9Brad Fitzpatrick        }.start();
202431e11d429783c07eca6e789de0518d17b42fb74Wei Huang    }
203431e11d429783c07eca6e789de0518d17b42fb74Wei Huang
2041d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    public static void dump() {
20509a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        // Only dump user private data if we're in special debug mode
20609a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        synchronized (sInstance) {
20709a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            Log.d(TAG, "*** Recipient ID cache dump ***");
20809a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            for (Long id : sInstance.mCache.keySet()) {
20909a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                Log.d(TAG, id + ": " + sInstance.mCache.get(id));
2101d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
2111d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
2121d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
213b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor
214b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor    public static void canonicalTableDump() {
215b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        Log.d(TAG, "**** Dump of canoncial_addresses table ****");
216b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        Context context = sInstance.mContext;
217b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
218b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                sAllCanonical, null, null, null, null);
219b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        if (c == null) {
220b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor            Log.w(TAG, "null Cursor in content://mms-sms/canonical-addresses");
221b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        }
222b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        try {
223b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor            while (c.moveToNext()) {
224b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                // TODO: don't hardcode the column indices
225b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                long id = c.getLong(0);
226b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                String number = c.getString(1);
227b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor                Log.d(TAG, "id: " + id + " number: " + number);
228b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor            }
229b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        } finally {
230b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor            c.close();
231b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor        }
232b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor    }
233b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
234b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    /**
235b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     * getSingleNumberFromCanonicalAddresses looks up the recipientId in the canonical_addresses
236b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     * table and returns the associated number or email address.
237b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     * @param context needed for the ContentResolver
238b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     * @param recipientId of the contact to look up
239b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     * @return phone number or email address of the recipientId
240b736686638eca62aa89cb15184711ef38413cb3eTom Taylor     */
241b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    public static String getSingleAddressFromCanonicalAddressInDb(final Context context,
242b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            final String recipientId) {
243b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        Cursor c = SqliteWrapper.query(context, context.getContentResolver(),
244b736686638eca62aa89cb15184711ef38413cb3eTom Taylor                ContentUris.withAppendedId(sSingleCanonicalAddressUri, Long.parseLong(recipientId)),
245b736686638eca62aa89cb15184711ef38413cb3eTom Taylor                null, null, null, null);
246b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        if (c == null) {
247b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            LogTag.warn(TAG, "null Cursor looking up recipient: " + recipientId);
248b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            return null;
249b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        }
250b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        try {
251b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            if (c.moveToFirst()) {
252b736686638eca62aa89cb15184711ef38413cb3eTom Taylor                String number = c.getString(0);
253b736686638eca62aa89cb15184711ef38413cb3eTom Taylor                return number;
254b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            }
255b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        } finally {
256b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            c.close();
257b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        }
258b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        return null;
259b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    }
260b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
261b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    // used for unit tests
262b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    public static void insertCanonicalAddressInDb(final Context context, String number) {
263b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        if (LogTag.VERBOSE || Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
264b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            Log.d(TAG, "[RecipientIdCache] insertCanonicalAddressInDb: number=" + number);
265b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        }
266b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
267b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        final ContentValues values = new ContentValues();
268b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        values.put(Telephony.CanonicalAddressesColumns.ADDRESS, number);
269b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
270b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        final ContentResolver cr = context.getContentResolver();
271b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
272b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        // We're running on the UI thread so just fire & forget, hope for the best.
273b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        // (We were ignoring the return value anyway...)
274ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev        new Thread("insertCanonicalAddressInDb") {
275b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            public void run() {
276b736686638eca62aa89cb15184711ef38413cb3eTom Taylor                cr.insert(sAllCanonical, values);
277b736686638eca62aa89cb15184711ef38413cb3eTom Taylor            }
278b736686638eca62aa89cb15184711ef38413cb3eTom Taylor        }.start();
279b736686638eca62aa89cb15184711ef38413cb3eTom Taylor    }
280b736686638eca62aa89cb15184711ef38413cb3eTom Taylor
2811d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick}
282