SpecialCharSequenceMgr.java revision b16363f5fc191b769e88c364243e34b92eb22688
1b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/*
2b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
3b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
4b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * you may not use this file except in compliance with the License.
6b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * You may obtain a copy of the License at
7b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
8b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project *
10b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * See the License for the specific language governing permissions and
14b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * limitations under the License.
15b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
16b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
17b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpackage com.android.phone;
18b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
19b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.Activity;
20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.AlertDialog;
21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context;
22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Intent;
23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.net.Uri;
24b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.Telephony.Intents;
25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.PhoneFactory;
26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log;
28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.WindowManager;
29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Helper class to listen for some magic character sequences
32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * that are handled specially by the Phone app.
33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class SpecialCharSequenceMgr {
35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final String TAG = PhoneApp.LOG_TAG;
36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final boolean DBG = false;
37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final String MMI_IMEI_DISPLAY = "*#06#";
39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** This class is never instantiated. */
41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private SpecialCharSequenceMgr() {
42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleChars(Context context, String input) {
45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return handleChars(context, input, false, null);
46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Generally used for the PUK unlocking case, where we
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * want to be able to maintain a handle to the calling
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * activity so that we can close it or otherwise display
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * indication if the PUK code is recognized.
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * NOTE: The counterpart to this file in Contacts does
55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * NOT contain the special PUK handling code, since it
56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * does NOT need it.  When the device gets into PUK-
57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * locked state, the keyguard comes up and the only way
58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * to unlock the device is through the Emergency dialer,
59b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * which is still in the Phone App.
60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
61b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleChars(Context context, String input, Activity pukInputActivity) {
62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return handleChars(context, input, false, pukInputActivity);
63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleChars(Context context, String input, boolean useSystemWindow) {
66b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return handleChars(context, input, useSystemWindow, null);
67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
68b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
69b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Check for special strings of digits from an input
71b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * string.
72b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param context input Context for the events we handle
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param input the dial string to be examined
75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param useSystemWindow used for the IMEI event to
76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * determine display behaviour.
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param pukInputActivity activity that originated this
78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * PUK call, tracked so that we can close it or otherwise
79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * indicate that special character sequence is
80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * successfully processed.
81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleChars(Context context,
83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                               String input,
84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                               boolean useSystemWindow,
85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                               Activity pukInputActivity) {
86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //get rid of the separators so that the string gets parsed correctly
88b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String dialString = PhoneNumberUtils.stripSeparators(input);
89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (handleIMEIDisplay(context, dialString, useSystemWindow)
91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            || handlePinEntry(context, dialString, pukInputActivity)
92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            || handleAdnEntry(context, dialString)
93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            || handleSecretCode(context, dialString)) {
94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Handles secret codes to launch arbitrary activities in the form of *#*#<code>#*#*.
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If a secret code is encountered an Intent is started with the android_secret_code://<code>
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * URI.
104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param context the context to use
106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param input the text to check for a secret code in
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if a secret code was encountered
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleSecretCode(Context context, String input) {
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Secret codes are in the form *#*#<code>#*#*
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int len = input.length();
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            context.sendBroadcast(intent);
116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleAdnEntry(Context context, String input) {
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        /* ADN entries are of the form "N(N)(N)#" */
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if the phone is keyguard-restricted, then just ignore this
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // input.  We want to make sure that sim card contacts are NOT
127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // exposed unless the phone is unlocked, and this code can be
128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // accessed from the emergency dialer.
129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (PhoneApp.getInstance().getKeyguardManager().inKeyguardRestrictedInputMode()) {
130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return false;
131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int len = input.length();
134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if ((len > 1) && (len < 5) && (input.endsWith("#"))) {
135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            try {
136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                int index = Integer.parseInt(input.substring(0, len-1));
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                Intent intent = new Intent(Intent.ACTION_PICK);
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                intent.setClassName("com.android.phone",
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                    "com.android.phone.SimContacts");
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                intent.putExtra("index", index);
143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                PhoneApp.getInstance().startActivity(intent);
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                return true;
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } catch (NumberFormatException ex) {}
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handlePinEntry(Context context, String input, Activity pukInputActivity) {
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO: The string constants here should be removed in favor of some call to a
153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // static the MmiCode class that determines if a dialstring is an MMI code.
154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if ((input.startsWith("**04") || input.startsWith("**05"))
155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                && input.endsWith("#")) {
156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PhoneApp app = PhoneApp.getInstance();
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            boolean isMMIHandled = app.phone.handlePinMmi(input);
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // if the PUK code is recognized then indicate to the
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // phone app that an attempt to unPUK the device was
161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // made with this activity.  The PUK code may still
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // fail though, but we won't know until the MMI code
163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // returns a result.
164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (isMMIHandled && input.startsWith("**05")) {
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                app.setPukEntryActivity(pukInputActivity);
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return isMMIHandled;
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static boolean handleIMEIDisplay(Context context,
173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                                     String input, boolean useSystemWindow) {
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (input.equals(MMI_IMEI_DISPLAY)) {
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            showIMEIPanel(context, useSystemWindow);
176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static void showIMEIPanel(Context context, boolean useSystemWindow) {
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) log("showIMEIPanel");
184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        String imeiStr = PhoneFactory.getDefaultPhone().getDeviceId();
186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        AlertDialog alert = new AlertDialog.Builder(context)
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                .setTitle(R.string.imei)
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                .setMessage(imeiStr)
190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                .setPositiveButton(R.string.ok, null)
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                .setCancelable(false)
192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                .show();
193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_PRIORITY_PHONE);
194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static void log(String msg) {
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Log.d(TAG, "[SpecialCharSequenceMgr] " + msg);
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
200