CallerInfoAsyncQuery.java revision 60d45f0f0320801a16db2ad038453c098e98966c
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;
40e22415817febc8d3229d1774f3b0dfda0fda8f46Nicolas Catania    private static final String LOG_TAG = "CallerInfoAsyncQuery";
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    /**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Interface for a CallerInfoAsyncQueryHandler result return.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnQueryCompleteListener {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
552563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * Called when the query is complete.
562563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onQueryComplete(int token, Object cookie, CallerInfo ci);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
592563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
602563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Wrap the cookie from the WorkerArgs with additional information needed by our
632563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville     * classes.
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final class CookieWrapper {
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public OnQueryCompleteListener listener;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Object cookie;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int event;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String number;
702563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    }
712563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
722563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Simple exception used to communicate problems with the query pool.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class QueryPoolException extends SQLException {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public QueryPoolException(String error) {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(error);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
812563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Our own implementation of the AsyncQueryHandler.
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler {
862563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The information relevant to each CallerInfo query.  Each query may have multiple
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * objects in the queue (one with a new query event, and one with a end event, with
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * 0 or more additional listeners in between).
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Context mQueryContext;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private Uri mQueryUri;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private CallerInfo mCallerInfo;
962563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Our own query worker thread.
992563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This thread handles the messages enqueued in the looper.  The normal sequence
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * of events is that a new query shows up in the looper queue, followed by 0 or
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * more add listener requests, and then an end request.  Of course, these requests
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * can be interlaced with requests from other tokens, but is irrelevant to this
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * handler since the handler has no state.
1052563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Note that we depend on the queue to keep things in order; in other words, the
1072563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * looper queue must be FIFO with respect to input from the synchronous startQuery
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * calls and output to this handleMessage call.
1092563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This use of the queue is required because CallerInfo objects may be accessed
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * multiple times before the query is complete.  All accesses (listeners) must be
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * queued up and informed in order when the query is complete.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected class CallerInfoWorkerHandler extends WorkerHandler {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public CallerInfoWorkerHandler(Looper looper) {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                super(looper);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            @Override
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void handleMessage(Message msg) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                WorkerArgs args = (WorkerArgs) msg.obj;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CookieWrapper cw = (CookieWrapper) args.cookie;
1232563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cw == null) {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Normally, this should never be the case for calls originating
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // from within this code.
1272563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // However, if there is any code that this Handler calls (such as in
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // super.handleMessage) that DOES place unexpected messages on the
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // queue, then we need pass these messages on.
1302563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what +
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " ignored by CallerInfoWorkerHandler, passing onto parent.");
1322563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    super.handleMessage(msg);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
1352563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1362563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 +
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            " command: " + msg.what + " query URI: " + args.uri);
1382563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    switch (cw.event) {
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_NEW_QUERY:
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            //start the sql command.
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            super.handleMessage(msg);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // shortcuts to avoid query for recognized numbers.
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_EMERGENCY_NUMBER:
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_VOICEMAIL_NUMBER:
1482563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_ADD_LISTENER:
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        case EVENT_END_OF_QUEUE:
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // query was already completed, so just send the reply.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // passing the original token value back to the caller
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // on top of the event values in arg1.
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Message reply = args.handler.obtainMessage(msg.what);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.obj = args;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.arg1 = msg.arg1;
1572563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reply.sendToTarget();
1592563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        default:
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1662563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1672563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Asynchronous query handler class for the contact / callerinfo object.
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private CallerInfoAsyncQueryHandler(Context context) {
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(context.getContentResolver());
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected Handler createHandler(Looper looper) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new CallerInfoWorkerHandler(looper);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Overrides onQueryComplete from AsyncQueryHandler.
1822563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         *
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This method takes into account the state of this class; we construct the CallerInfo
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * object only once for each set of listeners. When the query thread has done its work
1852563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * and calls this method, we inform the remaining listeners in the queue, until we're
1862563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * out of listeners.  Once we get the message indicating that we should expect no new
1872563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville         * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * pool.
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DBG) log("query complete for token: " + token);
1932563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //get the cookie and notify the listener.
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            CookieWrapper cw = (CookieWrapper) cookie;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw == null) {
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Normally, this should never be the case for calls originating
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // from within this code.
1992563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                // However, if there is any code that calls this method, we should
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // check the parameters to make sure they're viable.
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DBG) log("Cookie is null, ignoring onQueryComplete() request.");
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2042563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw.event == EVENT_END_OF_QUEUE) {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                release();
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // check the token and if needed, create the callerinfo object.
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCallerInfo == null) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((mQueryContext == null) || (mQueryUri == null)) {
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new QueryPoolException
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ("Bad context or query uri, or CallerInfoAsyncQuery already released.");
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2162563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // adjust the callerInfo data as needed, and only if it was set from the
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // initial query request.
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Change the callerInfo number ONLY if it is an emergency number or the
2202563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                // voicemail number, and adjust other data (including photoResource)
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // accordingly.
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cw.event == EVENT_EMERGENCY_NUMBER) {
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Note we're setting the phone number here (refer to javadoc
2242563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                    // comments at the top of CallerInfo class).
225e22415817febc8d3229d1774f3b0dfda0fda8f46Nicolas Catania                    mCallerInfo = new CallerInfo().markAsEmergency(mQueryContext);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (cw.event == EVENT_VOICEMAIL_NUMBER) {
22760d45f0f0320801a16db2ad038453c098e98966cNicolas Catania                    mCallerInfo = new CallerInfo().markAsVoiceMail();
2282563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                } else {
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Use the number entered by the user for display.
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!TextUtils.isEmpty(cw.number)) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2352563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DBG) log("constructing CallerInfo object for token: " + token);
2372563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //notify that we can clean up the queue after this.
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                CookieWrapper endMarker = new CookieWrapper();
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                endMarker.event = EVENT_END_OF_QUEUE;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startQuery (token, endMarker, null, null, null, null, null);
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2432563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            //notify the listener that the query is complete.
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cw.listener != null) {
2462563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville                if (DBG) log("notifying listener: " + cw.listener.getClass().toString() +
24760d45f0f0320801a16db2ad038453c098e98966cNicolas Catania                             " for token: " + token + mCallerInfo);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2522563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Private constructor for factory methods.
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private CallerInfoAsyncQuery() {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2592563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Factory method to start query with a Uri query spec
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2632563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef,
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OnQueryCompleteListener listener, Object cookie) {
2652563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.allocate(context, contactRef);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString());
2702563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, start query
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.event = EVENT_NEW_QUERY;
2762563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
2782563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2812563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Factory method to start query with a number
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2852563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    public static CallerInfoAsyncQuery startQuery(int token, Context context, String number,
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OnQueryCompleteListener listener, Object cookie) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //contruct the URI object and start Query.
28884b4d37dd1e9269f73c2a9cacadcd88ec4256e3fDmitri Plotnikov        Uri contactRef = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
2892563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CallerInfoAsyncQuery c = new CallerInfoAsyncQuery();
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.allocate(context, contactRef);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DBG) log("starting query for number: " + number + " handler: " + c.toString());
2942563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, start query
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.number = number;
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3012563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville        // check to see if these are recognized numbers, and use shortcuts if we can.
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (PhoneNumberUtils.isEmergencyNumber(number)) {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            cw.event = EVENT_EMERGENCY_NUMBER;
30460d45f0f0320801a16db2ad038453c098e98966cNicolas Catania        } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
30560d45f0f0320801a16db2ad038453c098e98966cNicolas Catania            cw.event = EVENT_VOICEMAIL_NUMBER;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
30760d45f0f0320801a16db2ad038453c098e98966cNicolas Catania            cw.event = EVENT_NEW_QUERY;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        c.mHandler.startQuery (token, cw, contactRef, null, null, null, null);
3112563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return c;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project   }
3142563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Method to add listeners to a currently running query
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) {
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3202563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville        if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " +
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHandler.toString());
3222563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //create cookieWrapper, add query request to end of queue.
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CookieWrapper cw = new CookieWrapper();
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.listener = listener;
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.cookie = cookie;
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        cw.event = EVENT_ADD_LISTENER;
3282563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.startQuery (token, cw, null, null, null, null, null);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Method to create a new CallerInfoAsyncQueryHandler object, ensuring correct
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * state of context and uri.
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void allocate (Context context, Uri contactRef) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((context == null) || (contactRef == null)){
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new QueryPoolException("Bad context or query uri.");
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = new CallerInfoAsyncQueryHandler(context);
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryContext = context;
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryUri = contactRef;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Releases the relevant data.
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void release () {
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryContext = null;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mQueryUri = null;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler.mCallerInfo = null;
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = null;
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3542563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * static logging method
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void log(String msg) {
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.d(LOG_TAG, msg);
3602563a3ac05dd3cf8a07203ae682c243f2e793137Wink Saville    }
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
362