CallerInfoAsyncQuery.java revision 3c513ed95cee2e0bcd7208cb7e46307f09c907c9
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.telephony;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.AsyncQueryHandler;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
273c513ed95cee2e0bcd7208cb7e46307f09c907c9Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.telephony.TelephonyManager;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ASYNCHRONOUS QUERY API
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class CallerInfoAsyncQuery {
382563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DBG = false;
40767a662ecde33c3979bf02b793d392aca0403162Wink Saville    private static final String LOG_TAG = "PHONE";
412563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int EVENT_NEW_QUERY = 1;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int EVENT_ADD_LISTENER = 2;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int EVENT_END_OF_QUEUE = 3;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int EVENT_EMERGENCY_NUMBER = 4;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int EVENT_VOICEMAIL_NUMBER = 5;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CallerInfoAsyncQueryHandler mHandler;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Don't keep checking VM if it's going to throw an exception for this proc.
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static boolean sSkipVmCheck = false;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Interface for a CallerInfoAsyncQueryHandler result return.
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnQueryCompleteListener {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
582563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * Called when the query is complete.
592563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         */
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onQueryComplete(int token, Object cookie, CallerInfo ci);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
622563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
632563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Wrap the cookie from the WorkerArgs with additional information needed by our
662563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville     * classes.
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final class CookieWrapper {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public OnQueryCompleteListener listener;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Object cookie;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int event;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String number;
732563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    }
742563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
752563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Simple exception used to communicate problems with the query pool.
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class QueryPoolException extends SQLException {
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public QueryPoolException(String error) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(error);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
842563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Our own implementation of the AsyncQueryHandler.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler {
892563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The information relevant to each CallerInfo query.  Each query may have multiple
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * objects in the queue (one with a new query event, and one with a end event, with
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * 0 or more additional listeners in between).
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Context mQueryContext;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Uri mQueryUri;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private CallerInfo mCallerInfo;
992563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Our own query worker thread.
1022563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This thread handles the messages enqueued in the looper.  The normal sequence
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * of events is that a new query shows up in the looper queue, followed by 0 or
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * more add listener requests, and then an end request.  Of course, these requests
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * can be interlaced with requests from other tokens, but is irrelevant to this
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * handler since the handler has no state.
1082563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Note that we depend on the queue to keep things in order; in other words, the
1102563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * looper queue must be FIFO with respect to input from the synchronous startQuery
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * calls and output to this handleMessage call.
1122563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This use of the queue is required because CallerInfo objects may be accessed
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * multiple times before the query is complete.  All accesses (listeners) must be
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * queued up and informed in order when the query is complete.
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected class CallerInfoWorkerHandler extends WorkerHandler {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public CallerInfoWorkerHandler(Looper looper) {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                super(looper);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void handleMessage(Message msg) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WorkerArgs args = (WorkerArgs) msg.obj;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CookieWrapper cw = (CookieWrapper) args.cookie;
1262563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cw == null) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Normally, this should never be the case for calls originating
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // from within this code.
1302563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // However, if there is any code that this Handler calls (such as in
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // super.handleMessage) that DOES place unexpected messages on the
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // queue, then we need pass these messages on.
1332563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " ignored by CallerInfoWorkerHandler, passing onto parent.");
1352563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    super.handleMessage(msg);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1382563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1392563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " command: " + msg.what + " query URI: " + args.uri);
1412563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (cw.event) {
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_NEW_QUERY:
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //start the sql command.
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            super.handleMessage(msg);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // shortcuts to avoid query for recognized numbers.
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_EMERGENCY_NUMBER:
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_VOICEMAIL_NUMBER:
1512563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_ADD_LISTENER:
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_END_OF_QUEUE:
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // query was already completed, so just send the reply.
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // passing the original token value back to the caller
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // on top of the event values in arg1.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Message reply = args.handler.obtainMessage(msg.what);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.obj = args;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.arg1 = msg.arg1;
1602563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.sendToTarget();
1622563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default:
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1692563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1702563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Asynchronous query handler class for the contact / callerinfo object.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private CallerInfoAsyncQueryHandler(Context context) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(context.getContentResolver());
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected Handler createHandler(Looper looper) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new CallerInfoWorkerHandler(looper);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Overrides onQueryComplete from AsyncQueryHandler.
1852563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This method takes into account the state of this class; we construct the CallerInfo
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * object only once for each set of listeners. When the query thread has done its work
1882563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * and calls this method, we inform the remaining listeners in the queue, until we're
1892563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * out of listeners.  Once we get the message indicating that we should expect no new
1902563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * pool.
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG) log("query complete for token: " + token);
1962563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //get the cookie and notify the listener.
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            CookieWrapper cw = (CookieWrapper) cookie;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw == null) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Normally, this should never be the case for calls originating
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // from within this code.
2022563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                // However, if there is any code that calls this method, we should
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // check the parameters to make sure they're viable.
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2072563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw.event == EVENT_END_OF_QUEUE) {
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                release();
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // check the token and if needed, create the callerinfo object.
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCallerInfo == null) {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((mQueryContext == null) || (mQueryUri == null)) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new QueryPoolException
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ("Bad context or query uri, or CallerInfoAsyncQuery already released.");
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2192563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // adjust the callerInfo data as needed, and only if it was set from the
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // initial query request.
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Change the callerInfo number ONLY if it is an emergency number or the
2232563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                // voicemail number, and adjust other data (including photoResource)
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // accordingly.
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cw.event == EVENT_EMERGENCY_NUMBER) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo = new CallerInfo();
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Note we're setting the phone number here (refer to javadoc
2282563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // comments at the top of CallerInfo class).
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo.phoneNumber = mQueryContext.getString(com.android.internal
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            .R.string.emergency_call_dialog_number_for_display);
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo.photoResource = com.android.internal.R.drawable.picture_emergency;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo = new CallerInfo();
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Note we're setting the phone number here (refer to javadoc
2372563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                        // comments at the top of CallerInfo class).
2382563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                        mCallerInfo.phoneNumber =
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                TelephonyManager.getDefault().getVoiceMailAlphaTag();
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (SecurityException ex) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Should never happen: if this process does not have
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // permission to retrieve VM tag, it should not have
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // permission to retrieve VM number and would not generate
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // an EVENT_VOICEMAIL_NUMBER.  But if it happens, don't crash.
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2462563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                } else {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Use the number entered by the user for display.
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!TextUtils.isEmpty(cw.number)) {
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2532563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DBG) log("constructing CallerInfo object for token: " + token);
2552563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //notify that we can clean up the queue after this.
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CookieWrapper endMarker = new CookieWrapper();
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                endMarker.event = EVENT_END_OF_QUEUE;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startQuery (token, endMarker, null, null, null, null, null);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2612563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //notify the listener that the query is complete.
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw.listener != null) {
2642563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        " for token: " + token);
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2702563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Private constructor for factory methods.
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CallerInfoAsyncQuery() {
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2772563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Factory method to start query with a Uri query spec
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2812563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OnQueryCompleteListener listener, Object cookie) {
2832563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.allocate(context, contactRef);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString());
2882563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, start query
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.event = EVENT_NEW_QUERY;
2942563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
2962563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2992563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Factory method to start query with a number
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3032563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OnQueryCompleteListener listener, Object cookie) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //contruct the URI object and start Query.
3063c513ed95cee2e0bcd7208cb7e46307f09c907c9Dmitri Plotnikov        Uri contactRef = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number);
3072563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.allocate(context, contactRef);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) log("starting query for number: " + number + " handler: " + c.toString());
3122563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, start query
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.number = number;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3192563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville        // check to see if these are recognized numbers, and use shortcuts if we can.
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (PhoneNumberUtils.isEmergencyNumber(number)) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cw.event = EVENT_EMERGENCY_NUMBER;
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            String vmNumber = null;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!sSkipVmCheck){
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    vmNumber = TelephonyManager.getDefault().getVoiceMailNumber();
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (SecurityException ex) {
3282563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // Don't crash if this process doesn't have permission to
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // retrieve VM number.  It's still allowed to look up caller info.
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // But don't try it again.
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sSkipVmCheck = true;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3342563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville            if (PhoneNumberUtils.compare(number, vmNumber)) {
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cw.event = EVENT_VOICEMAIL_NUMBER;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cw.event = EVENT_NEW_QUERY;
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
3422563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project   }
3452563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Method to add listeners to a currently running query
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3512563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville        if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHandler.toString());
3532563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, add query request to end of queue.
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.event = EVENT_ADD_LISTENER;
3592563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.startQuery (token, cw, null, null, null, null, null);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Method to create a new CallerInfoAsyncQueryHandler object, ensuring correct
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * state of context and uri.
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void allocate (Context context, Uri contactRef) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((context == null) || (contactRef == null)){
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new QueryPoolException("Bad context or query uri.");
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = new CallerInfoAsyncQueryHandler(context);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryContext = context;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryUri = contactRef;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Releases the relevant data.
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void release () {
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryContext = null;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryUri = null;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mCallerInfo = null;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = null;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3852563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * static logging method
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void log(String msg) {
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.d(LOG_TAG, msg);
3912563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    }
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
394