191197049c458f07092b31501d2ed512180b13d58Chiao Cheng/*
291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Copyright (C) 2006 The Android Open Source Project
391197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
591197049c458f07092b31501d2ed512180b13d58Chiao Cheng * you may not use this file except in compliance with the License.
691197049c458f07092b31501d2ed512180b13d58Chiao Cheng * You may obtain a copy of the License at
791197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
891197049c458f07092b31501d2ed512180b13d58Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
991197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
1091197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Unless required by applicable law or agreed to in writing, software
1191197049c458f07092b31501d2ed512180b13d58Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
1291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391197049c458f07092b31501d2ed512180b13d58Chiao Cheng * See the License for the specific language governing permissions and
1491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * limitations under the License.
1591197049c458f07092b31501d2ed512180b13d58Chiao Cheng */
1691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
1791197049c458f07092b31501d2ed512180b13d58Chiao Chengpackage com.android.dialer;
1891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
19675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chenimport android.app.Activity;
2091197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.app.AlertDialog;
21384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shraunerimport android.app.DialogFragment;
2291197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.app.KeyguardManager;
2391197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.app.ProgressDialog;
241d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hambyimport android.content.ActivityNotFoundException;
2591197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.content.ContentResolver;
2691197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.content.Context;
2791197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.content.DialogInterface;
2891197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.content.Intent;
2991197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.database.Cursor;
3091197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.net.Uri;
3191197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.os.Looper;
32f4f47665942b34a1bab272b84f223bb06825a57fJeff Sharkeyimport android.provider.Settings;
333af7e5675e118b3f135b5bab1da1f666c8f268d6Yorke Leeimport android.telecom.PhoneAccount;
34675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chenimport android.telecom.PhoneAccountHandle;
3591197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.telephony.PhoneNumberUtils;
3691197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.telephony.TelephonyManager;
370f4ec2a7c965a8fa23fa32373fbdbbb3e4be1ea4Nancy Chenimport android.text.TextUtils;
3891197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.util.Log;
3991197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.view.WindowManager;
4091197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.widget.EditText;
4191197049c458f07092b31501d2ed512180b13d58Chiao Chengimport android.widget.Toast;
4291197049c458f07092b31501d2ed512180b13d58Chiao Cheng
43ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shraunerimport com.android.common.io.MoreCloseables;
44ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chenimport com.android.contacts.common.compat.CompatUtils;
45fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chenimport com.android.contacts.common.compat.TelephonyManagerCompat;
4607af764827a7d6d426f6097d3e769084968f84fdChiao Chengimport com.android.contacts.common.database.NoNullCursorAsyncQueryHandler;
476d98cf688855372ffbef12a41ef1f69f990409f1Ta-wei Yenimport com.android.contacts.common.util.ContactDisplayUtils;
48675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chenimport com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
49675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chenimport com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener;
50675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chenimport com.android.dialer.calllog.PhoneAccountUtils;
514aece9536ed64da965fd42da07a393f935abd6b1Yorke Leeimport com.android.dialer.util.TelecomUtil;
5291197049c458f07092b31501d2ed512180b13d58Chiao Cheng
538c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chenimport java.util.ArrayList;
548c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chenimport java.util.List;
558c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen
5691197049c458f07092b31501d2ed512180b13d58Chiao Cheng/**
5791197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Helper class to listen for some magic character sequences
5891197049c458f07092b31501d2ed512180b13d58Chiao Cheng * that are handled specially by the dialer.
5991197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
6091197049c458f07092b31501d2ed512180b13d58Chiao Cheng * Note the Phone app also handles these sequences too (in a couple of
611d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby * relatively obscure places in the UI), so there's a separate version of
6291197049c458f07092b31501d2ed512180b13d58Chiao Cheng * this class under apps/Phone.
6391197049c458f07092b31501d2ed512180b13d58Chiao Cheng *
6491197049c458f07092b31501d2ed512180b13d58Chiao Cheng * TODO: there's lots of duplicated code between this class and the
6591197049c458f07092b31501d2ed512180b13d58Chiao Cheng * corresponding class under apps/Phone.  Let's figure out a way to
6691197049c458f07092b31501d2ed512180b13d58Chiao Cheng * unify these two classes (in the framework? in a common shared library?)
6791197049c458f07092b31501d2ed512180b13d58Chiao Cheng */
6891197049c458f07092b31501d2ed512180b13d58Chiao Chengpublic class SpecialCharSequenceMgr {
6991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static final String TAG = "SpecialCharSequenceMgr";
701d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby
71384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner    private static final String TAG_SELECT_ACCT_FRAGMENT = "tag_select_acct_fragment";
72384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner
73f90dadaf0e46463e4ff24ad4267981b7196fe96fYorke Lee    private static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
7491197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static final String MMI_IMEI_DISPLAY = "*#06#";
751d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby    private static final String MMI_REGULATORY_INFO_DISPLAY = "*#07#";
7691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
7791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
7891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Remembers the previous {@link QueryHandler} and cancel the operation when needed, to
7991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * prevent possible crash.
8091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
8191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * QueryHandler may call {@link ProgressDialog#dismiss()} when the screen is already gone,
8291197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * which will cause the app crash. This variable enables the class to prevent the crash
8391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * on {@link #cleanup()}.
8491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
8591197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * TODO: Remove this and replace it (and {@link #cleanup()}) with better implementation.
861d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby     * One complication is that we have SpecialCharSequenceMgr in Phone package too, which has
8791197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * *slightly* different implementation. Note that Phone package doesn't have this problem,
8891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * so the class on Phone side doesn't have this functionality.
8991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Fundamental fix would be to have one shared implementation and resolve this corner case more
9091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * gracefully.
9191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
9291197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static QueryHandler sPreviousAdnQueryHandler;
9391197049c458f07092b31501d2ed512180b13d58Chiao Cheng
9489e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee    public static class HandleAdnEntryAccountSelectedCallback extends SelectPhoneAccountListener{
95762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee        final private Context mContext;
9689e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        final private QueryHandler mQueryHandler;
9789e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        final private SimContactQueryCookie mCookie;
9889e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
99762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee        public HandleAdnEntryAccountSelectedCallback(Context context,
10089e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                QueryHandler queryHandler, SimContactQueryCookie cookie) {
101762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee            mContext = context;
10289e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            mQueryHandler = queryHandler;
10389e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            mCookie = cookie;
10489e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        }
10589e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
10689e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        @Override
10789e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle,
10889e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                boolean setDefault) {
109762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee            Uri uri = TelecomUtil.getAdnUriForPhoneAccount(mContext, selectedAccountHandle);
11089e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            handleAdnQuery(mQueryHandler, mCookie, uri);
11189e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            // TODO: Show error dialog if result isn't valid.
11289e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        }
11389e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
11489e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee    }
11589e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
11689e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee    public static class HandleMmiAccountSelectedCallback extends SelectPhoneAccountListener{
11789e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        final private Context mContext;
11889e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        final private String mInput;
11989e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        public HandleMmiAccountSelectedCallback(Context context, String input) {
12089e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            mContext = context.getApplicationContext();
12189e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            mInput = input;
12289e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        }
12389e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
12489e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        @Override
12589e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        public void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle,
12689e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                boolean setDefault) {
12789e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee            TelecomUtil.handleMmi(mContext, mInput, selectedAccountHandle);
12889e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee        }
12989e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee    }
13089e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
13191197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /** This class is never instantiated. */
13291197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private SpecialCharSequenceMgr() {
13391197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
13491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
13591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static boolean handleChars(Context context, String input, EditText textField) {
13691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        //get rid of the separators so that the string gets parsed correctly
13791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        String dialString = PhoneNumberUtils.stripSeparators(input);
13891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
1398c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen        if (handleDeviceIdDisplay(context, dialString)
1401d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby                || handleRegulatoryInfoDisplay(context, dialString)
14191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                || handlePinEntry(context, dialString)
14291197049c458f07092b31501d2ed512180b13d58Chiao Cheng                || handleAdnEntry(context, dialString, textField)
14391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                || handleSecretCode(context, dialString)) {
14491197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return true;
14591197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
14691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
14791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        return false;
14891197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
14991197049c458f07092b31501d2ed512180b13d58Chiao Cheng
15091197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
15191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Cleanup everything around this class. Must be run inside the main thread.
15291197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
15391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * This should be called when the screen becomes background.
15491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
15591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    public static void cleanup() {
15691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (Looper.myLooper() != Looper.getMainLooper()) {
15791197049c458f07092b31501d2ed512180b13d58Chiao Cheng            Log.wtf(TAG, "cleanup() is called outside the main thread");
15891197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return;
15991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
16091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
16191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (sPreviousAdnQueryHandler != null) {
16291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            sPreviousAdnQueryHandler.cancel();
16391197049c458f07092b31501d2ed512180b13d58Chiao Cheng            sPreviousAdnQueryHandler = null;
16491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
16591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
16691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
16791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
16891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
16991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * If a secret code is encountered an Intent is started with the android_secret_code://<code>
17091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * URI.
17191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
17291197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * @param context the context to use
17391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * @param input the text to check for a secret code in
17491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * @return true if a secret code was encountered
17591197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
17691197049c458f07092b31501d2ed512180b13d58Chiao Cheng    static boolean handleSecretCode(Context context, String input) {
17791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // Secret codes are in the form *#*#<code>#*#*
17891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        int len = input.length();
17991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
180f90dadaf0e46463e4ff24ad4267981b7196fe96fYorke Lee            final Intent intent = new Intent(SECRET_CODE_ACTION,
18191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
18291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            context.sendBroadcast(intent);
18391197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return true;
18491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
18591197049c458f07092b31501d2ed512180b13d58Chiao Cheng
18691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        return false;
18791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
18891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
18991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
19091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Handle ADN requests by filling in the SIM contact number into the requested
19191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * EditText.
19291197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
19391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * This code works alongside the Asynchronous query handler {@link QueryHandler}
19491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * and query cancel handler implemented in {@link SimContactQueryCookie}.
19591197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
19689e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee    static boolean handleAdnEntry(Context context, String input, EditText textField) {
19791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        /* ADN entries are of the form "N(N)(N)#" */
19891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        TelephonyManager telephonyManager =
19991197049c458f07092b31501d2ed512180b13d58Chiao Cheng                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
20091197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (telephonyManager == null
20162280c72fd651b00dd5499f4c3b32f30be57ce0dYorke Lee                || telephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_GSM) {
20291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return false;
20391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
20491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
20591197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // if the phone is keyguard-restricted, then just ignore this
20691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // input.  We want to make sure that sim card contacts are NOT
20791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // exposed unless the phone is unlocked, and this code can be
20891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // accessed from the emergency dialer.
20991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        KeyguardManager keyguardManager =
21091197049c458f07092b31501d2ed512180b13d58Chiao Cheng                (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
21191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (keyguardManager.inKeyguardRestrictedInputMode()) {
21291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return false;
21391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
21491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
21591197049c458f07092b31501d2ed512180b13d58Chiao Cheng        int len = input.length();
21691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if ((len > 1) && (len < 5) && (input.endsWith("#"))) {
21791197049c458f07092b31501d2ed512180b13d58Chiao Cheng            try {
21891197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // get the ordinal number of the sim contact
21918c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                final int index = Integer.parseInt(input.substring(0, len-1));
22091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
22191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // The original code that navigated to a SIM Contacts list view did not
22291197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // highlight the requested contact correctly, a requirement for PTCRB
22391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // certification.  This behaviour is consistent with the UI paradigm
22491197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // for touch-enabled lists, so it does not make sense to try to work
22591197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // around it.  Instead we fill in the the requested phone number into
22691197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // the dialer text field.
22791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
22891197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // create the async query handler
229f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                final QueryHandler handler = new QueryHandler(context.getContentResolver());
23091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
23191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // create the cookie object
23218c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                final SimContactQueryCookie sc = new SimContactQueryCookie(index - 1, handler,
23391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                        ADN_QUERY_TOKEN);
23491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
23591197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // setup the cookie fields
23691197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.contactNum = index - 1;
23791197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.setTextField(textField);
23891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
23991197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // create the progress dialog
24091197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog = new ProgressDialog(context);
24191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.setTitle(R.string.simContacts_title);
24291197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.setMessage(context.getText(R.string.simContacts_emptyLoading));
24391197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.setIndeterminate(true);
24491197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.setCancelable(true);
24591197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.setOnCancelListener(sc);
24691197049c458f07092b31501d2ed512180b13d58Chiao Cheng                sc.progressDialog.getWindow().addFlags(
24791197049c458f07092b31501d2ed512180b13d58Chiao Cheng                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
24891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
24939c18f27ed2929fae220a9b4a101d8dc7c83e217Nancy Chen                List<PhoneAccountHandle> subscriptionAccountHandles =
25018c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                        PhoneAccountUtils.getSubscriptionPhoneAccounts(context);
251f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                Context applicationContext = context.getApplicationContext();
25239c18f27ed2929fae220a9b4a101d8dc7c83e217Nancy Chen                boolean hasUserSelectedDefault = subscriptionAccountHandles.contains(
253f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                        TelecomUtil.getDefaultOutgoingPhoneAccount(applicationContext,
254762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee                                PhoneAccount.SCHEME_TEL));
25518c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
256fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen                if (subscriptionAccountHandles.size() <= 1 || hasUserSelectedDefault) {
257f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                    Uri uri = TelecomUtil.getAdnUriForPhoneAccount(applicationContext, null);
25818c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                    handleAdnQuery(handler, sc, uri);
259fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen                } else {
260f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                    SelectPhoneAccountListener callback = new HandleAdnEntryAccountSelectedCallback(
261f6bf9e4c680355bf597447bbda043f3b611734d0Brandon Maxwell                            applicationContext, handler, sc);
26289e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
263384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                    DialogFragment dialogFragment = SelectPhoneAccountDialogFragment.newInstance(
26489e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                            subscriptionAccountHandles, callback);
265384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                    dialogFragment.show(((Activity) context).getFragmentManager(),
266384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                            TAG_SELECT_ACCT_FRAGMENT);
26791197049c458f07092b31501d2ed512180b13d58Chiao Cheng                }
26818c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
26991197049c458f07092b31501d2ed512180b13d58Chiao Cheng                return true;
27091197049c458f07092b31501d2ed512180b13d58Chiao Cheng            } catch (NumberFormatException ex) {
27191197049c458f07092b31501d2ed512180b13d58Chiao Cheng                // Ignore
27291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
27391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
27491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        return false;
27591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
27691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
27718c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen    private static void handleAdnQuery(QueryHandler handler, SimContactQueryCookie cookie,
27818c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            Uri uri) {
27918c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        if (handler == null || cookie == null || uri == null) {
28018c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            Log.w(TAG, "queryAdn parameters incorrect");
28118c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            return;
28218c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        }
28318c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
28418c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        // display the progress dialog
28518c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        cookie.progressDialog.show();
28618c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
28718c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        // run the query.
28818c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        handler.startQuery(ADN_QUERY_TOKEN, cookie, uri, new String[]{ADN_PHONE_NUMBER_COLUMN_NAME},
28918c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                null, null, null);
29018c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
29118c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        if (sPreviousAdnQueryHandler != null) {
29218c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            // It is harmless to call cancel() even after the handler's gone.
29318c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            sPreviousAdnQueryHandler.cancel();
29418c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        }
29518c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen        sPreviousAdnQueryHandler = handler;
29618c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen    }
29718c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen
2984aece9536ed64da965fd42da07a393f935abd6b1Yorke Lee    static boolean handlePinEntry(final Context context, final String input) {
29991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
30039c18f27ed2929fae220a9b4a101d8dc7c83e217Nancy Chen            List<PhoneAccountHandle> subscriptionAccountHandles =
301675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen                    PhoneAccountUtils.getSubscriptionPhoneAccounts(context);
30239c18f27ed2929fae220a9b4a101d8dc7c83e217Nancy Chen            boolean hasUserSelectedDefault = subscriptionAccountHandles.contains(
303762b357ec94aef3e7ee6f991c553aa950840a8bcYorke Lee                    TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL));
304675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen
305fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen            if (subscriptionAccountHandles.size() <= 1 || hasUserSelectedDefault) {
306675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen                // Don't bring up the dialog for single-SIM or if the default outgoing account is
307675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen                // a subscription account.
3084aece9536ed64da965fd42da07a393f935abd6b1Yorke Lee                return TelecomUtil.handleMmi(context, input, null);
309fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen            } else {
31089e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                SelectPhoneAccountListener listener =
31189e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee                        new HandleMmiAccountSelectedCallback(context, input);
31289e784b2673351e0d0a818124d02bcd5f81a14c0Yorke Lee
313384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                DialogFragment dialogFragment = SelectPhoneAccountDialogFragment.newInstance(
314384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                        subscriptionAccountHandles, listener);
315384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                dialogFragment.show(((Activity) context).getFragmentManager(),
316384eaad571ec047d14d33761b152625e8a9ee9b0Jay Shrauner                        TAG_SELECT_ACCT_FRAGMENT);
317675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen            }
318675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen            return true;
319675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen        }
320675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen        return false;
321675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen    }
322675af1f3d3dbaedad78920f36fa501113a55ba65Nancy Chen
3238c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen    // TODO: Use TelephonyCapabilities.getDeviceIdLabel() to get the device id label instead of a
3248c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen    // hard-coded string.
3258c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen    static boolean handleDeviceIdDisplay(Context context, String input) {
32691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        TelephonyManager telephonyManager =
32791197049c458f07092b31501d2ed512180b13d58Chiao Cheng                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
3288c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen
32991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        if (telephonyManager != null && input.equals(MMI_IMEI_DISPLAY)) {
3308c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen            int labelResId = (telephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) ?
3318c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen                    R.string.imei : R.string.meid;
3328c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen
3338c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen            List<String> deviceIds = new ArrayList<String>();
334fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen            if (TelephonyManagerCompat.getPhoneCount(telephonyManager) > 1 &&
335fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen                    CompatUtils.isMethodAvailable(TelephonyManagerCompat.TELEPHONY_MANAGER_CLASS,
336fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen                            "getDeviceId", Integer.TYPE)) {
337ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chen                for (int slot = 0; slot < telephonyManager.getPhoneCount(); slot++) {
338ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chen                    String deviceId = telephonyManager.getDeviceId(slot);
339ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chen                    if (!TextUtils.isEmpty(deviceId)) {
340ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chen                        deviceIds.add(deviceId);
341ee5b3dcb3f505395ed95eeca0085783030135a2dNancy Chen                    }
3420f4ec2a7c965a8fa23fa32373fbdbbb3e4be1ea4Nancy Chen                }
343fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen            } else {
344fdb93b7079d522d688ec0ebe58c92d45aee48786Nancy Chen                deviceIds.add(telephonyManager.getDeviceId());
34591197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
34691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
3478c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen            AlertDialog alert = new AlertDialog.Builder(context)
3488c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen                    .setTitle(labelResId)
3498c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen                    .setItems(deviceIds.toArray(new String[deviceIds.size()]), null)
3500f4ec2a7c965a8fa23fa32373fbdbbb3e4be1ea4Nancy Chen                    .setPositiveButton(android.R.string.ok, null)
3518c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen                    .setCancelable(false)
3528c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen                    .show();
3538c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen            return true;
3548c258ac5eee9d1e0c3f8a4d895dda84a2c9ac71aNancy Chen        }
35591197049c458f07092b31501d2ed512180b13d58Chiao Cheng        return false;
35691197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
35791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
3581d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby    private static boolean handleRegulatoryInfoDisplay(Context context, String input) {
3591d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby        if (input.equals(MMI_REGULATORY_INFO_DISPLAY)) {
3601d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby            Log.d(TAG, "handleRegulatoryInfoDisplay() sending intent to settings app");
361f4f47665942b34a1bab272b84f223bb06825a57fJeff Sharkey            Intent showRegInfoIntent = new Intent(Settings.ACTION_SHOW_REGULATORY_INFO);
3621d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby            try {
3631d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby                context.startActivity(showRegInfoIntent);
3641d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby            } catch (ActivityNotFoundException e) {
3651d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby                Log.e(TAG, "startActivity() failed: " + e);
3661d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby            }
3671d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby            return true;
3681d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby        }
3691d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby        return false;
3701d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby    }
3711d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby
37291197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /*******
37391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * This code is used to handle SIM Contact queries
37491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *******/
37591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static final String ADN_PHONE_NUMBER_COLUMN_NAME = "number";
37691197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static final String ADN_NAME_COLUMN_NAME = "name";
37791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static final int ADN_QUERY_TOKEN = -1;
37891197049c458f07092b31501d2ed512180b13d58Chiao Cheng
37991197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
38091197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Cookie object that contains everything we need to communicate to the
38191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * handler's onQuery Complete, as well as what we need in order to cancel
38291197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * the query (if requested).
38391197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
38491197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Note, access to the textField field is going to be synchronized, because
38591197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * the user can request a cancel at any time through the UI.
38691197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
38791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    private static class SimContactQueryCookie implements DialogInterface.OnCancelListener{
38891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public ProgressDialog progressDialog;
38991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public int contactNum;
39091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
39191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // Used to identify the query request.
39291197049c458f07092b31501d2ed512180b13d58Chiao Cheng        private int mToken;
39391197049c458f07092b31501d2ed512180b13d58Chiao Cheng        private QueryHandler mHandler;
39491197049c458f07092b31501d2ed512180b13d58Chiao Cheng
39591197049c458f07092b31501d2ed512180b13d58Chiao Cheng        // The text field we're going to update
39691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        private EditText textField;
39791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
39891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public SimContactQueryCookie(int number, QueryHandler handler, int token) {
39991197049c458f07092b31501d2ed512180b13d58Chiao Cheng            contactNum = number;
40091197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mHandler = handler;
40191197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mToken = token;
40291197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
40391197049c458f07092b31501d2ed512180b13d58Chiao Cheng
40491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        /**
40591197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * Synchronized getter for the EditText.
40691197049c458f07092b31501d2ed512180b13d58Chiao Cheng         */
40791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public synchronized EditText getTextField() {
40891197049c458f07092b31501d2ed512180b13d58Chiao Cheng            return textField;
40991197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
41091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
41191197049c458f07092b31501d2ed512180b13d58Chiao Cheng        /**
41291197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * Synchronized setter for the EditText.
41391197049c458f07092b31501d2ed512180b13d58Chiao Cheng         */
41491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public synchronized void setTextField(EditText text) {
41591197049c458f07092b31501d2ed512180b13d58Chiao Cheng            textField = text;
41691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
41791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
41891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        /**
41991197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * Cancel the ADN query by stopping the operation and signaling
42091197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * the cookie that a cancel request is made.
42191197049c458f07092b31501d2ed512180b13d58Chiao Cheng         */
42291197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public synchronized void onCancel(DialogInterface dialog) {
42391197049c458f07092b31501d2ed512180b13d58Chiao Cheng            // close the progress dialog
42491197049c458f07092b31501d2ed512180b13d58Chiao Cheng            if (progressDialog != null) {
42591197049c458f07092b31501d2ed512180b13d58Chiao Cheng                progressDialog.dismiss();
42691197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
42791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
42891197049c458f07092b31501d2ed512180b13d58Chiao Cheng            // setting the textfield to null ensures that the UI does NOT get
42991197049c458f07092b31501d2ed512180b13d58Chiao Cheng            // updated.
43091197049c458f07092b31501d2ed512180b13d58Chiao Cheng            textField = null;
43191197049c458f07092b31501d2ed512180b13d58Chiao Cheng
43291197049c458f07092b31501d2ed512180b13d58Chiao Cheng            // Cancel the operation if possible.
43391197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mHandler.cancelOperation(mToken);
43491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
43591197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
43691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
43791197049c458f07092b31501d2ed512180b13d58Chiao Cheng    /**
43891197049c458f07092b31501d2ed512180b13d58Chiao Cheng     * Asynchronous query handler that services requests to look up ADNs
43991197049c458f07092b31501d2ed512180b13d58Chiao Cheng     *
4401d6fb57f3a53db34bfcb3dacdf11bcb6fb091b06Jake Hamby     * Queries originate from {@link #handleAdnEntry}.
44191197049c458f07092b31501d2ed512180b13d58Chiao Cheng     */
44207af764827a7d6d426f6097d3e769084968f84fdChiao Cheng    private static class QueryHandler extends NoNullCursorAsyncQueryHandler {
44391197049c458f07092b31501d2ed512180b13d58Chiao Cheng
44491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        private boolean mCanceled;
44591197049c458f07092b31501d2ed512180b13d58Chiao Cheng
44691197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public QueryHandler(ContentResolver cr) {
44791197049c458f07092b31501d2ed512180b13d58Chiao Cheng            super(cr);
44891197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
44991197049c458f07092b31501d2ed512180b13d58Chiao Cheng
45091197049c458f07092b31501d2ed512180b13d58Chiao Cheng        /**
45191197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * Override basic onQueryComplete to fill in the textfield when
45291197049c458f07092b31501d2ed512180b13d58Chiao Cheng         * we're handed the ADN cursor.
45391197049c458f07092b31501d2ed512180b13d58Chiao Cheng         */
45491197049c458f07092b31501d2ed512180b13d58Chiao Cheng        @Override
45507af764827a7d6d426f6097d3e769084968f84fdChiao Cheng        protected void onNotNullableQueryComplete(int token, Object cookie, Cursor c) {
456ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner            try {
457ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                sPreviousAdnQueryHandler = null;
458ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                if (mCanceled) {
459ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    return;
460ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                }
46191197049c458f07092b31501d2ed512180b13d58Chiao Cheng
462ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                SimContactQueryCookie sc = (SimContactQueryCookie) cookie;
46391197049c458f07092b31501d2ed512180b13d58Chiao Cheng
464ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                // close the progress dialog.
465ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                sc.progressDialog.dismiss();
46691197049c458f07092b31501d2ed512180b13d58Chiao Cheng
467ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                // get the EditText to update or see if the request was cancelled.
468ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                EditText text = sc.getTextField();
46991197049c458f07092b31501d2ed512180b13d58Chiao Cheng
47018c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                // if the TextView is valid, and the cursor is valid and positionable on the
47118c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                // Nth number, then we update the text field and display a toast indicating the
47218c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                // caller name.
473ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                if ((c != null) && (text != null) && (c.moveToPosition(sc.contactNum))) {
474ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    String name = c.getString(c.getColumnIndexOrThrow(ADN_NAME_COLUMN_NAME));
47518c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                    String number =
47618c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen                            c.getString(c.getColumnIndexOrThrow(ADN_PHONE_NUMBER_COLUMN_NAME));
47791197049c458f07092b31501d2ed512180b13d58Chiao Cheng
478ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    // fill the text in.
479ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    text.getText().replace(0, 0, number);
48091197049c458f07092b31501d2ed512180b13d58Chiao Cheng
481ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    // display the name as a toast
482ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                    Context context = sc.progressDialog.getContext();
483f0017b72f44f39448c87186e59da8e568ebc5dd1Ta-wei Yen                    CharSequence msg = ContactDisplayUtils.getTtsSpannedPhoneNumber(
4846d98cf688855372ffbef12a41ef1f69f990409f1Ta-wei Yen                            context.getResources(), R.string.menu_callNumber, name);
4856d98cf688855372ffbef12a41ef1f69f990409f1Ta-wei Yen                    Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
486ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                }
487ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner            } finally {
488ede67ec7813fb2c6fcda485adf82f11b55e3562cJay Shrauner                MoreCloseables.closeQuietly(c);
48991197049c458f07092b31501d2ed512180b13d58Chiao Cheng            }
49091197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
49191197049c458f07092b31501d2ed512180b13d58Chiao Cheng
49291197049c458f07092b31501d2ed512180b13d58Chiao Cheng        public void cancel() {
49391197049c458f07092b31501d2ed512180b13d58Chiao Cheng            mCanceled = true;
49418c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            // Ask AsyncQueryHandler to cancel the whole request. This will fail when the query is
49518c52ffec7896bbbb7f161994b4453d91fcc79efNancy Chen            // already started.
49691197049c458f07092b31501d2ed512180b13d58Chiao Cheng            cancelOperation(ADN_QUERY_TOKEN);
49791197049c458f07092b31501d2ed512180b13d58Chiao Cheng        }
49891197049c458f07092b31501d2ed512180b13d58Chiao Cheng    }
49991197049c458f07092b31501d2ed512180b13d58Chiao Cheng}
500