PhoneApp.java revision 8bb467d9a1106dedd79e42166c7b6e9fc9a897a7
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 com.android.internal.telephony.MmiCode;
20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Phone;
21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.PhoneFactory;
22b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.SimCard;
23b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents;
24b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
25b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.Activity;
26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.Application;
27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.KeyguardManager;
28b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.app.ProgressDialog;
29b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.bluetooth.BluetoothHeadset;
30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.bluetooth.BluetoothIntent;
31b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.BroadcastReceiver;
32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.ContentResolver;
33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context;
34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Intent;
35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.IntentFilter;
36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.AudioManager;
37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.net.Uri;
38b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.AsyncResult;
39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Binder;
40b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Handler;
41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.IBinder;
42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.IPowerManager;
43b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.LocalPowerManager;
44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Message;
45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.PowerManager;
46b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.RemoteException;
47b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.ServiceManager;
48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.SystemClock;
49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.SystemProperties;
50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.preference.PreferenceManager;
51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.Settings.System;
52b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Config;
53b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log;
54b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.view.KeyEvent;
55b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.widget.Toast;
56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/**
58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Top-level Application class for the Phone app.
59b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */
60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class PhoneApp extends Application {
61b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ static final String LOG_TAG = "PhoneApp";
62b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ static final boolean DBG =
63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            (SystemProperties.getInt("ro.debuggable", 0) == 1);
64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Message codes; see mHandler below.
66b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_SIM_ABSENT = 1;
67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_SIM_LOCKED = 2;
68b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_SIM_NETWORK_LOCKED = 3;
69b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_DATA_DISCONNECTED = 6;
70b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_WIRED_HEADSET_PLUG = 7;
71b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static final int EVENT_SIM_STATE_CHANGED = 8;
728bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private static final int EVENT_UPDATE_INCALL_NOTIFICATION = 9;
73b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
74b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // The MMI codes are also used by the InCallScreen.
75b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public static final int MMI_INITIATE = 10;
76b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public static final int MMI_COMPLETE = 11;
77b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public static final int MMI_CANCEL = 12;
78b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Don't use message codes larger than 99 here; those are reserved for
79b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // the individual Activities of the Phone UI.
80b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
81b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
82b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Allowable values for the poke lock code (timeout between a user activity and the
83b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * going to sleep), please refer to {@link com.android.server.PowerManagerService}
84b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * for additional reference.
85b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   SHORT uses the short delay for the timeout (SHORT_KEYLIGHT_DELAY, 6 sec)
86b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   MEDIUM uses the medium delay for the timeout (MEDIUM_KEYLIGHT_DELAY, 15 sec)
87b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   DEFAULT is the system-wide default delay for the timeout (1 min)
88b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
89b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public enum ScreenTimeoutDuration {
90b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SHORT,
91b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        MEDIUM,
92b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        DEFAULT
93b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
94b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
95b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
96b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Allowable values for the wake lock code.
97b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   SLEEP means the device can be put to sleep.
98b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   PARTIAL means wake the processor, but we display can be kept off.
99b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *   FULL means wake both the processor and the display.
100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public enum WakeState {
102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        SLEEP,
103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PARTIAL,
104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        FULL
105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private static PhoneApp sMe;
108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // A few important fields we expose to the rest of the package
110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // directly (rather than thru set/get methods) for efficiency.
111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    Phone phone;
112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    CallNotifier notifier;
113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    Ringer ringer;
114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    BluetoothHandsfree mBtHandsfree;
115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    PhoneInterfaceManager phoneMgr;
1168bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    int mBluetoothHeadsetState = BluetoothHeadset.STATE_ERROR;
1178bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    boolean mShowBluetoothIndication = false;
118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // The InCallScreen instance (or null if the InCallScreen hasn't been
120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // created yet.)
121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private InCallScreen mInCallScreen;
122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // The currently-active PUK entry activity and progress dialog.
124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Normally, these are the Emergency Dialer and the subsequent
125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // progress dialog.  null if there is are no such objects in
126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // the foreground.
127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private Activity mPUKEntryActivity;
128b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ProgressDialog mPUKEntryProgressDialog;
129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mIsSimPinEnabled;
131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private String mCachedSimPin;
132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // True if a wired headset is currently plugged in, based on the state
134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // from the latest Intent.ACTION_HEADSET_PLUG broadcast we received in
135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // mReceiver.onReceive().
136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mIsHeadsetPlugged;
137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
138b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private WakeState mWakeState = WakeState.SLEEP;
139b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private ScreenTimeoutDuration mPokeLockSetting = ScreenTimeoutDuration.DEFAULT;
140b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private IBinder mPokeLockToken = new Binder();
141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private IPowerManager mPowerManagerService;
142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private PowerManager.WakeLock mWakeLock;
143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private PowerManager.WakeLock mPartialWakeLock;
144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private KeyguardManager mKeyguardManager;
145b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private KeyguardManager.KeyguardLock mKeyguardLock;
146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Broadcast receiver for various intent broadcasts (see onCreate())
148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
150b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    // Broadcast receiver purely for ACTION_MEDIA_BUTTON broadcasts
151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private final BroadcastReceiver mMediaButtonReceiver = new MediaButtonBroadcastReceiver();
152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /** boolean indicating restoring mute state on InCallScreen.onResume() */
154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private boolean mShouldRestoreMuteOnInCallResume;
155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
156b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Set the restore mute state flag. Used when we are setting the mute state
158b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
160b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /*package*/void setRestoreMuteOnInCallResume (boolean mode) {
161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mShouldRestoreMuteOnInCallResume = mode;
162b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
164b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
165b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Get the restore mute state flag.
166b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
167b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * out if we need to restore the mute state for the current active call.
168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
169b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /*package*/boolean getRestoreMuteOnInCallResume () {
170b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mShouldRestoreMuteOnInCallResume;
171b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
172b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
173b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    Handler mHandler = new Handler() {
174b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
175b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void handleMessage(Message msg) {
176b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (msg.what) {
177b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_SIM_LOCKED:
178b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    mIsSimPinEnabled = true;
179b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//
180b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    if (Config.LOGV) Log.v(LOG_TAG, "show sim unlock panel");
181b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    SimPinUnlockPanel pinUnlockPanel = new SimPinUnlockPanel(
182b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                            PhoneApp.getInstance());
183b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    pinUnlockPanel.show();
184b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
185b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
186b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_SIM_ABSENT:
187b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project// Don't need this now that the lock screen handles this case
188b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    if (Config.LOGV) Log.v(LOG_TAG, "show sim missing panel");
189b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    SimMissingPanel missingPanel = new SimMissingPanel(
190b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                            PhoneApp.getInstance());
191b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project//                    missingPanel.show();
192b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
193b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
194b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_SIM_NETWORK_LOCKED:
195b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (Config.LOGV) Log.v(LOG_TAG, "show sim depersonal panel");
196b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    SimNetworkDepersonalizationPanel ndpPanel =
197b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        new SimNetworkDepersonalizationPanel(PhoneApp.getInstance());
198b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    ndpPanel.show();
199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
200b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
2018bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                case EVENT_UPDATE_INCALL_NOTIFICATION:
2028bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    // Tell the NotificationMgr to update the "ongoing
2038bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    // call" icon in the status bar, if necessary.
2048bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    // Currently, this is triggered by a bluetooth headset
2058bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    // state change (since the status bar icon needs to
2068bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    // turn blue when bluetooth is active.)
2078bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    NotificationMgr.getDefault().updateInCallNotification();
2088bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                    break;
2098bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_DATA_DISCONNECTED:
211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    Intent roaming = new Intent();
212b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    roaming.setClass(PhoneApp.getInstance(),  DataRoamingReenable.class);
213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    roaming.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneApp.getInstance().startActivity(roaming);
215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
216b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MMI_COMPLETE:
217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    onMMIComplete((AsyncResult) msg.obj);
218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case MMI_CANCEL:
221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.cancelMmiCode(phone);
222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_WIRED_HEADSET_PLUG:
225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Since the presence of a wired headset or bluetooth affects the
226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // speakerphone, update the "speaker" state.  We ONLY want to do
227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // this on the wired headset connect / disconnect events for now
228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // though, so we're only triggering on EVENT_WIRED_HEADSET_PLUG.
229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (!isHeadsetPlugged() &&
230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            (mBtHandsfree == null || !mBtHandsfree.isAudioOn())) {
231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // is the state is "not connected", restore the speaker state.
232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        PhoneUtils.restoreSpeakerMode(getApplicationContext());
233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    NotificationMgr.getDefault().updateSpeakerNotification();
235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case EVENT_SIM_STATE_CHANGED:
238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Marks the event where the SIM goes into ready state.
239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Right now, this is only used for the PUK-unlocking
240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // process.
241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (msg.obj.equals(SimCard.INTENT_VALUE_SIM_READY)) {
242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // when the right event is triggered and there
243b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // are UI objects in the foreground, we close
244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        // them to display the lock panel.
245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (mPUKEntryActivity != null) {
246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPUKEntryActivity.finish();
247b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPUKEntryActivity = null;
248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (mPUKEntryProgressDialog != null) {
250b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPUKEntryProgressDialog.dismiss();
251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                            mPUKEntryProgressDialog = null;
252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        }
253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
254b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    };
258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public PhoneApp() {
260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        sMe = this;
261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    @Override
264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    public void onCreate() {
265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (Config.LOGV) Log.v(LOG_TAG, "onCreate()...");
266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        ContentResolver resolver = getContentResolver();
268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (phone == null) {
270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Initialize the telephony framework
271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PhoneFactory.makeDefaultPhones(this);
272b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Get the default phone
274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            phone = PhoneFactory.getDefaultPhone();
275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            NotificationMgr.init(this);
277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            phoneMgr = new PhoneInterfaceManager(this, phone);
279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (getSystemService(Context.BLUETOOTH_SERVICE) != null) {
280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mBtHandsfree = new BluetoothHandsfree(this, phone);
281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                startService(new Intent(this, BluetoothHeadsetService.class));
282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Device is not bluetooth capable
284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mBtHandsfree = null;
285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            ringer = new Ringer(phone);
288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            SoundEffect.init();
290b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // before registering for phone state changes
292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
294b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    | PowerManager.ACQUIRE_CAUSES_WAKEUP
295b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
296b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // lock used to keep the processor awake, when we don't care for the display.
297b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
298b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
299b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
300b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mKeyguardLock = mKeyguardManager.newKeyguardLock(LOG_TAG);
301b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
302b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // get a handle to the service so that we can use it later when we
303b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // want to set the poke lock.
304b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPowerManagerService = IPowerManager.Stub.asInterface(
305b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    ServiceManager.getService("power"));
306b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
307b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            notifier = new CallNotifier(this, phone, ringer, mBtHandsfree);
308b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // register for SIM status
310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            SimCard sim = phone.getSimCard();
311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (sim != null) {
312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (Config.LOGV) Log.v(LOG_TAG, "register for SIM status");
313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                sim.registerForAbsent(mHandler, EVENT_SIM_ABSENT, null);
314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                sim.registerForLocked(mHandler, EVENT_SIM_LOCKED, null);
315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // register for MMI/USSD
319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            phone.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
321b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // register connection tracking to PhoneUtils
322b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PhoneUtils.initializeConnectionHandler(phone);
323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Register for misc other intent broadcasts.
325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            IntentFilter intentFilter =
326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            intentFilter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            registerReceiver(mReceiver, intentFilter);
333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // since we need to manually adjust its priority (to make sure
336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // we get these intents *before* the media player.)
337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            IntentFilter mediaButtonIntentFilter =
338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            //
340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Make sure we're higher priority than the media player's
341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // MediaButtonIntentReceiver (which currently has the default
342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // priority of zero; see apps/Music/AndroidManifest.xml.)
343b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mediaButtonIntentFilter.setPriority(1);
344b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            //
345b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
346b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
347b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            //set the default values for the preferences in the phone.
348b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PreferenceManager.setDefaultValues(this, R.xml.network_setting, false);
349b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
350b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
351b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Make sure the audio mode (along with some
352b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // audio-mode-related state of our own) is initialized
353b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // correctly, given the current state of the phone.
354b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (phone.getState()) {
355b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case IDLE:
356b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: IDLE");
357b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_IDLE);
358b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioMode(this, AudioManager.MODE_NORMAL);
359b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
360b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case RINGING:
361b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: RINGING");
362b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_RINGING);
363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioMode(this, AudioManager.MODE_RINGTONE);
364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case OFFHOOK:
366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "Resetting audio state/mode: OFFHOOK");
367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioControlState(PhoneUtils.AUDIO_OFFHOOK);
368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    PhoneUtils.setAudioMode(this, AudioManager.MODE_IN_CALL);
369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // XXX pre-load the SimProvider so that it's ready
374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        resolver.getType(Uri.parse("content://sim/adn"));
375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // start with the default value to set the mute state.
377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mShouldRestoreMuteOnInCallResume = false;
378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project   }
379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Returns the singleton instance of the PhoneApp.
382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static PhoneApp getInstance() {
384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return sMe;
385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    Ringer getRinger() {
388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return ringer;
389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    BluetoothHandsfree getBluetoothHandsfree() {
392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mBtHandsfree;
393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static Intent createCallLogIntent() {
396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Intent  intent = new Intent(Intent.ACTION_VIEW, null);
397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        intent.setType("vnd.android.cursor.dir/calls");
398b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return intent;
399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Return an Intent that can be used to bring up the in-call screen.
403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This intent can only be used from within the Phone app, since the
405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * InCallScreen is not exported from our AndroidManifest.
406b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
407b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ static Intent createInCallIntent() {
408b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Intent intent = new Intent(Intent.ACTION_MAIN, null);
409b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
410b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
411b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
412b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        intent.setClassName("com.android.phone", getCallScreenClassName());
413b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return intent;
414b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
417b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Variation of createInCallIntent() that also specifies whether the
418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * DTMF dialpad should be initially visible when the InCallScreen
419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * comes up.
420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
421b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ static Intent createInCallIntent(boolean showDialpad) {
422b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Intent intent = createInCallIntent();
423b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
424b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return intent;
425b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
426b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
427b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    static String getCallScreenClassName() {
428b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return InCallScreen.class.getName();
429b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
430b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Starts the InCallScreen Activity.
433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
434b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void displayCallScreen() {
435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) Log.d(LOG_TAG, "displayCallScreen()...", new Throwable("stack dump"));
436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        startActivity(createInCallIntent());
437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Profiler.callScreenRequested();
438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
439b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
441b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Helper function to check for one special feature of the CALL key:
442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Normally, when the phone is idle, CALL takes you to the call log
443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * (see the handler for KEYCODE_CALL in PhoneWindow.onKeyUp().)
444b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * But if the phone is in use (either off-hook or ringing) we instead
445b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * handle the CALL button by taking you to the in-call UI.
446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if we intercepted the CALL keypress (i.e. the phone
448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *              was in use)
449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
450b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @see DialerActivity#onCreate
451b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean handleInCallOrRinging() {
453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (phone.getState() != Phone.State.IDLE) {
454b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Phone is OFFHOOK or RINGING.
455b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) Log.v(LOG_TAG,
456b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                           "handleInCallOrRinging: show call screen");
457b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            displayCallScreen();
458b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return true;
459b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
460b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return false;
461b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
462b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
463b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean isSimPinEnabled() {
464b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mIsSimPinEnabled;
465b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean authenticateAgainstCachedSimPin(String pin) {
468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return (mCachedSimPin != null && mCachedSimPin.equals(pin));
469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void setCachedSimPin(String pin) {
472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mCachedSimPin = pin;
473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void setInCallScreenInstance(InCallScreen inCallScreen) {
476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mInCallScreen = inCallScreen;
477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if the in-call UI is running as the foreground
481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * activity.  (In other words, from the perspective of the
482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * InCallScreen activity, return true between onResume() and
483b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * onPause().)
484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Note this method will return false if the screen is currently off,
486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * even if the InCallScreen *was* in the foreground just before the
487b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * screen turned off.  (This is because the foreground activity is
488b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * always "paused" while the screen is off.)
489b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
490b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean isShowingCallScreen() {
491b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallScreen == null) return false;
492b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mInCallScreen.isForegroundActivity();
493b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
494b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
495b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
496b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Dismisses the in-call UI.
497b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
498b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This also ensures that you won't be able to get back to the in-call
499b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * UI via the BACK button (since this call removes the InCallScreen
500b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * from the activity history.)
501b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
502b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void dismissCallScreen() {
503b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mInCallScreen != null) {
504b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mInCallScreen.finish();
505b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
506b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
507b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
508b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
509b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the activity responsible for un-PUK-blocking the device
510b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * so that we may close it when we receive a positive result.
511b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * mPUKEntryActivity is also used to indicate to the device that
512b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * we are trying to un-PUK-lock the phone. In other words, iff
513b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * it is NOT null, then we are trying to unlock and waiting for
514b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the SIM to move to READY state.
515b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
516b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param activity is the activity to close when PUK has
517b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * finished unlocking. Can be set to null to indicate the unlock
518b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * or SIM READYing process is over.
519b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
520b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void setPukEntryActivity(Activity activity) {
521b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPUKEntryActivity = activity;
522b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
523b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
524b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    Activity getPUKEntryActivity() {
525b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mPUKEntryActivity;
526b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
527b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
528b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
529b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the dialog responsible for notifying the user of un-PUK-
530b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * blocking - SIM READYing progress, so that we may dismiss it
531b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * when we receive a positive result.
532b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
533b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param dialog indicates the progress dialog informing the user
534b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * of the state of the device.  Dismissed upon completion of
535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * READYing process
536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    void setPukEntryProgressDialog(ProgressDialog dialog) {
538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPUKEntryProgressDialog = dialog;
539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    ProgressDialog getPUKEntryProgressDialog() {
542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mPUKEntryProgressDialog;
543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Disables the keyguard.  This is used by the phone app to allow
547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * interaction with the Phone UI when the keyguard would otherwise be
548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * active (like receiving an incoming call while the device is
549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * locked.)
550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Any call to this method MUST be followed (eventually)
552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * by a corresponding reenableKeyguard() call.
553b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
554b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void disableKeyguard() {
555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "disable keyguard");
556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) Log.d(LOG_TAG, "disableKeyguard()...", new Throwable("stack dump"));
557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mKeyguardLock.disableKeyguard();
558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Re-enables the keyguard after a previous disableKeyguard() call.
562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Any call to this method MUST correspond to (i.e. be balanced with)
564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * a previous disableKeyguard() call.
565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void reenableKeyguard() {
567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "re-enable keyguard");
568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // if (DBG) Log.d(LOG_TAG, "reenableKeyguard()...", new Throwable("stack dump"));
569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mKeyguardLock.reenableKeyguard();
570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Controls how quickly the screen times out.
574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * The poke lock controls how long it takes before the screen powers
576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * down, and therefore has no immediate effect when the current
577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * WakeState (see {@link PhoneApp#requestWakeState}) is FULL.
578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If we're in a state where the screen *is* allowed to turn off,
579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * though, the poke lock will determine the timeout interval (long or
580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * short).
581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param shortPokeLock tells the device the timeout duration to use
583b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * before going to sleep
584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * {@link com.android.server.PowerManagerService#SHORT_KEYLIGHT_DELAY}.
585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void setScreenTimeout(ScreenTimeoutDuration duration) {
587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "setScreenTimeout(" + duration + ")...");
588b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // make sure we don't set the poke lock repeatedly so that we
590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // avoid triggering the userActivity calls in
591b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // PowerManagerService.setPokeLock().
592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (duration == mPokeLockSetting) {
593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            return;
594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
595b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        mPokeLockSetting = duration;
596b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // This is kind of convoluted, but the basic thing to remember is
598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // that the poke lock just sends a message to the screen to tell
599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // it to stay on for a while.
600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // The default is 0, for a long timeout and should be set that way
601b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // when we are heading back into a the keyguard / screen off
602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // state, and also when we're trying to keep the screen alive
603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // while ringing.  We'll also want to ignore the cheek events
604b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // regardless of the timeout duration.
605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // The short timeout is really used whenever we want to give up
606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the screen lock, such as when we're in call.
607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        int pokeLockSetting = LocalPowerManager.POKE_LOCK_IGNORE_CHEEK_EVENTS;
608b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        switch (duration) {
609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case SHORT:
610b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Set the poke lock to timeout the display after a short
611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // timeout (5s). This ensures that the screen goes to sleep
612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // as soon as acceptably possible after we the wake lock
613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // has been released.
614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "setting short poke lock");
615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                pokeLockSetting |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
616b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case MEDIUM:
619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Set the poke lock to timeout the display after a medium
620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // timeout (15s). This ensures that the screen goes to sleep
621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // as soon as acceptably possible after we the wake lock
622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // has been released.
623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "setting medium poke lock");
624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                pokeLockSetting |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            case DEFAULT:
628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            default:
629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // set the poke lock to timeout the display after a long
630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // delay by default.
631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // TODO: it may be nice to be able to disable cheek presses
632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // for long poke locks (emergency dialer, for instance).
633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "reverting to normal long poke lock");
634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                break;
635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Send the request
638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        try {
639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPowerManagerService.setPokeLock(pokeLockSetting, mPokeLockToken, LOG_TAG);
640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } catch (RemoteException e) {
641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
643b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Controls whether or not the screen is allowed to sleep.
646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Once sleep is allowed (WakeState is SLEEP), it will rely on the
648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * settings for the poke lock to determine when to timeout and let
649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * the device sleep {@link PhoneApp#setScreenTimeout}.
650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @param ws tells the device to how to wake.
652b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void requestWakeState(WakeState ws) {
654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mWakeState != ws) {
656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            switch (ws) {
657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case PARTIAL:
658b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // acquire the processor wake lock, and release the FULL
659b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // lock if it is being held.
660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "acquire partial wake lock (CPU only)");
661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mPartialWakeLock.acquire();
662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (mWakeLock.isHeld()) {
663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mWakeLock.release();
664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
666b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case FULL:
667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // acquire the full wake lock, and release the PARTIAL
668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // lock if it is being held.
669b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "acquire full wake lock (CPU + Screen)");
670b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    mWakeLock.acquire();
671b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (mPartialWakeLock.isHeld()) {
672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mPartialWakeLock.release();
673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
675b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                case SLEEP:
676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                default:
677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // release both the PARTIAL and FULL locks.
678b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "release all wake locks");
679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (mWakeLock.isHeld()) {
680b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mWakeLock.release();
681b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (mPartialWakeLock.isHeld()) {
683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mPartialWakeLock.release();
684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
685b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    break;
686b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
687b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mWakeState = ws;
688b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
689b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
690b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
691b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
692b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * If we are not currently keeping the screen on, then poke the power
693b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * manager to wake up the screen for the user activity timeout duration.
694b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
695b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void wakeUpScreen() {
696b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (mWakeState == WakeState.SLEEP) {
697b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) Log.d(LOG_TAG, "pulse screen lock");
698b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            try {
699b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
700b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } catch (RemoteException ex) {
701b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // Ignore -- the system process is dead.
702b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
703b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
704b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
705b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
706b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
707b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Sets the wake state and screen timeout based on the current state
708b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * of the phone, and the current state of the in-call UI.
709b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
710b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This method is a "UI Policy" wrapper around
711b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * {@link PhoneApp#requestWakeState} and {@link PhoneApp#setScreenTimeout}.
712b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
713b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * It's safe to call this method regardless of the state of the Phone
714b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * (e.g. whether or not it's idle), and regardless of the state of the
715b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Phone UI (e.g. whether or not the InCallScreen is active.)
716b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
717b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void updateWakeState() {
718b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        Phone.State state = phone.getState();
719b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
720b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // True if the in-call UI is the foreground activity.
721b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // (Note this will be false if the screen is currently off,
722b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // since in that case *no* activity is in the foreground.)
723b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isShowingCallScreen = isShowingCallScreen();
724b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
725b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // True if the InCallScreen's DTMF dialer is currently opened.
726b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // (Note this does NOT imply whether or not the InCallScreen
727b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // itself is visible.)
728b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
729b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
730b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // True if the speakerphone is in use.  (If so, we *always* use
731b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the default timeout.  Since the user is obviously not holding
732b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the phone up to his/her face, we don't need to worry about
733b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // false touches, and thus don't need to turn the screen off so
734b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // aggressively.)
735b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Note that we need to make a fresh call to this method any
736b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // time the speaker state changes.  (That happens in
737b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // PhoneUtils.turnOnSpeaker().)
738b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isSpeakerInUse = (state == Phone.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
739b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
740b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // TODO (bug 1440854): The screen timeout *might* also need to
741b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // depend on the bluetooth state, but this isn't as clear-cut as
742b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // the speaker state (since while using BT it's common for the
743b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // user to put the phone straight into a pocket, in which case the
744b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // timeout should probably still be short.)
745b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
746b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "updateWakeState: isShowingCallScreen " + isShowingCallScreen
747b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                       + ", isDialerOpened " + isDialerOpened
748b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                       + ", isSpeakerInUse " + isSpeakerInUse + "...");
749b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
750b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
751b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // (1) Set the screen timeout.
752b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
753b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Note that the "screen timeout" value we determine here is
754b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // meaningless if the screen is forced on (see (2) below.)
755b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
756b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (!isShowingCallScreen || isSpeakerInUse) {
757b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // Use the system-wide default timeout.
758b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
759b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } else {
760b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            // We're on the in-call screen, and *not* using the speakerphone.
761b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (isDialerOpened) {
762b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // The DTMF dialpad is up.  This case is special because
763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // the in-call UI has its own "touch lock" mechanism to
764b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // disable the dialpad after a very short amount of idle
765b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // time (to avoid false touches from the user's face while
766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // in-call.)
767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                //
768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // In this case the *physical* screen just uses the
769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // system-wide default timeout.
770b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else {
772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // We're on the in-call screen, and not using the DTMF dialpad.
773b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // There's actually no touchable UI onscreen at all in
774b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // this state.  Also, the user is (most likely) not
775b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // looking at the screen at all, since they're probably
776b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // holding the phone up to their face.  Here we use a
777b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // special screen timeout value specific to the in-call
778b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // screen, purely to save battery life.
779b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                setScreenTimeout(ScreenTimeoutDuration.MEDIUM);
780b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
781b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
782b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
783b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
784b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // (2) Decide whether to force the screen on or not.
785b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
786b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // Force the screen to be on if the phone is ringing, or if we're
787b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // displaying the "Call ended" UI for a connection in the
788b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // "disconnected" state.
789b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        //
790b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean isRinging = (state == Phone.State.RINGING);
791b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean showingDisconnectedConnection =
792b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
793b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        boolean keepScreenOn = isRinging || showingDisconnectedConnection;
794b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
795b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                       + " (isRinging " + isRinging
796b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                       + ", showingDisconnectedConnection " + showingDisconnectedConnection + ")");
797b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        // keepScreenOn == true means we'll hold a full wake lock:
798b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
800b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
801b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
802b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Wrapper around the PowerManagerService.preventScreenOn() API.
803b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This allows the in-call UI to prevent the screen from turning on
804b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * even if a subsequent call to updateWakeState() causes us to acquire
805b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * a full wake lock.
806b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
807b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /* package */ void preventScreenOn(boolean prevent) {
808b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "- preventScreenOn(" + prevent + ")...");
809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        try {
810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            mPowerManagerService.preventScreenOn(prevent);
811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        } catch (RemoteException e) {
812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            Log.w(LOG_TAG, "mPowerManagerService.preventScreenOn() failed: " + e);
813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    KeyguardManager getKeyguardManager() {
817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mKeyguardManager;
818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private void onMMIComplete(AsyncResult r) {
821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        if (DBG) Log.d(LOG_TAG, "onMMIComplete()...");
822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        MmiCode mmiCode = (MmiCode) r.result;
823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
826b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
827b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @return true if a wired headset is currently plugged in.
828b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
829b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * @see Intent.ACTION_HEADSET_PLUG (which we listen for in mReceiver.onReceive())
830b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
831b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    boolean isHeadsetPlugged() {
832b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        return mIsHeadsetPlugged;
833b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
834b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
8358bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
8368bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * @return true if the onscreen UI should currently be showing the
8378bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * special "bluetooth is active" indication in a couple of places (in
8388bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * which UI elements turn blue and/or show the bluetooth logo.)
8398bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *
8408bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * This depends on the BluetoothHeadset state *and* the current
8418bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * telephony state; see shouldShowBluetoothIndication().
8428bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *
8438bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * @see CallCard
8448bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * @see NotificationMgr.updateInCallNotification
8458bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
8468bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /* package */ boolean showBluetoothIndication() {
8478bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        return mShowBluetoothIndication;
8488bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
8498bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
8508bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
8518bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * Recomputes the mShowBluetoothIndication flag based on the current
8528bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * bluetooth state and current telephony state.
8538bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *
8548bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * This needs to be called any time the bluetooth headset state or the
8558bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * telephony state changes.
8568bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
8578bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /* package */ void updateBluetoothIndication() {
8588bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
8598bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                                                                 phone);
8608bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
8618bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
8628bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    /**
8638bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * UI policy helper function for the couple of places in the UI that
8648bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * have some way of indicating that "bluetooth is in use."
8658bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *
8668bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * @return true if the onscreen UI should indicate that "bluetooth is in use",
8678bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *         based on the specified bluetooth headset state, and the
8688bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     *         current state of the phone.
8698bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     * @see showBluetoothIndication()
8708bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project     */
8718bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    private static boolean shouldShowBluetoothIndication(int bluetoothState,
8728bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                                                         Phone phone) {
8738bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // We want the UI to indicate that "bluetooth is in use" in two
8748bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // slightly different cases:
8758bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        //
8768bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // (a) The obvious case: if a bluetooth headset is currently in
8778bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        //     use for an ongoing call.
8788bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        //
8798bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        // (b) The not-so-obvious case: if an incoming call is ringing,
8808bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        //     and we expect that audio *will* be routed to a bluetooth
8818bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        //     headset once the call is answered.
8828bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
8838bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        switch (phone.getState()) {
8848bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            case OFFHOOK:
8858bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // This covers normal active calls, and also the case if
8868bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // the foreground call is DIALING or ALERTING.  (If
8878bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // DIALING or ALERTING, audio *is* routed to the headset
8888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // while the other end is ringing, so we just check for
8898bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // the bluetooth headset PLAYING state.  We don't need to
8908bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // do any tricks like we do below for the RINGING state.)
8918bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
8928bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // TODO: we really need to know whether or not the headset
8938bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // is getting audio routed to it, rather than just whether
8948bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // or not the headset is connected.  So we really want to
8958bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // check for the "PLAYING" state here.  (But
8968bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // BluetoothHeadset doesn't have the concept of a
8978bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // "PLAYING" state yet; see bug 1695249.)
8988bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // For now:
8998bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
9008bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
9018bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            case RINGING:
9028bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // If an incoming call is ringing, we're *not* yet routing
9038bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // audio to the headset (since there's no in-call audio
9048bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // yet!)  In this case, if a bluetooth headset is
9058bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // connected at all, we assume that it'll become active
9068bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // once the user answers the phone.
9078bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
9088bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
9098bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project            default:  // Presumably IDLE
9108bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                return false;
9118bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project        }
9128bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project    }
9138bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
914b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
915b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
916b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Receiver for misc intent broadcasts the Phone app cares about.
917b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
918b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
919b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
920b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void onReceive(Context context, Intent intent) {
921b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            String action = intent.getAction();
922b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
923b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                boolean enabled = System.getInt(getContentResolver(),
924b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        System.AIRPLANE_MODE_ON, 0) == 0;
925b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                phone.setRadioPower(enabled);
926b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
9278bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                mBluetoothHeadsetState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
9288bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                                                            BluetoothHeadset.STATE_ERROR);
9298bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
9308bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
9318bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
9328bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // First, recompute the mShowBluetoothIndication flag based on
9338bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // the (new) bluetooth state and current telephony state.
9348bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                updateBluetoothIndication();
9358bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project
9368bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // Then, post Handler messages to the various components that
9378bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                // might need to update their UI based on the new state.
9388bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                if (isShowingCallScreen()) mInCallScreen.updateBluetoothIndication();
9398bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project                mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if ("DISCONNECTED".equals(intent.getStringExtra(Phone.STATE_KEY))) {
942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (Phone.REASON_ROAMING_ON.equals(reason)) {
944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        mHandler.sendMessage(mHandler.obtainMessage(EVENT_DATA_DISCONNECTED, 0));
945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
946b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
948b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");
949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));
950b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));
951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
952b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));
953b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
954b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (DBG) Log.d(LOG_TAG, "mReceiver: ACTION_BATTERY_LOW");
955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                notifier.sendBatteryLow();  // Play a warning tone if in-call
956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    (mPUKEntryActivity != null)) {
958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // if an attempt to un-PUK-lock the device was made, while we're
959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // receiving this state change notification, notify the handler.
960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                // been attempted.
962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        intent.getStringExtra(SimCard.INTENT_KEY_SIM_STATE)));
964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    /**
969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * Broadcast receiver for the ACTION_MEDIA_BUTTON broadcast intent.
970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     *
971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * This functionality isn't lumped in with the other intents in
972b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * PhoneAppBroadcastReceiver because we instantiate this as a totally
973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * separate BroadcastReceiver instance, since we need to manually
974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * adjust its IntentFilter's priority (to make sure we get these
975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     * intents *before* the media player.)
976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project     */
977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        @Override
979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        public void onReceive(Context context, Intent intent) {
980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if (DBG) Log.d(LOG_TAG,
982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                           "MediaButtonBroadcastReceiver.onReceive()...  event = " + event);
983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            if ((event != null)
984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)
985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                && (event.getAction() == KeyEvent.ACTION_DOWN)) {
986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project
987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                if (event.getRepeatCount() == 0) {
988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Mute ONLY on the initial keypress.
989b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: HEADSETHOOK down!");
990b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    boolean consumed = PhoneUtils.handleHeadsetHook(phone);
991b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "==> called handleHeadsetHook(), consumed = " + consumed);
992b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (consumed) {
993b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        if (DBG) Log.d(LOG_TAG, "==> Aborting broadcast!");
994b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                        abortBroadcast();
995b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    }
996b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                } else if (phone.getState() != Phone.State.IDLE){
997b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // Otherwise if the phone is active, then just consume / ignore the event.
998b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // If we do not do this, the music player handles the event, which doesn't
999b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    // make sense to the user.
1000b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    if (DBG) Log.d(LOG_TAG, "==> Phone is busy, aborting broadcast!");
1001b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                    abortBroadcast();
1002b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project                }
1003b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project            }
1004b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project        }
1005b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project    }
1006b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project}
1007