• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.phone;
18 
19 import android.app.Activity;
20 import android.app.Application;
21 import android.app.KeyguardManager;
22 import android.app.ProgressDialog;
23 import android.app.StatusBarManager;
24 import android.bluetooth.BluetoothAdapter;
25 import android.bluetooth.BluetoothHeadset;
26 import android.content.BroadcastReceiver;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.res.Configuration;
32 import android.media.AudioManager;
33 import android.net.Uri;
34 import android.os.AsyncResult;
35 import android.os.Binder;
36 import android.os.Handler;
37 import android.os.IBinder;
38 import android.os.IPowerManager;
39 import android.os.LocalPowerManager;
40 import android.os.Message;
41 import android.os.PowerManager;
42 import android.os.RemoteException;
43 import android.os.ServiceManager;
44 import android.os.SystemClock;
45 import android.os.SystemProperties;
46 import android.preference.PreferenceManager;
47 import android.provider.Settings.System;
48 import android.telephony.ServiceState;
49 import android.util.Config;
50 import android.util.Log;
51 import android.view.KeyEvent;
52 import android.widget.Toast;
53 
54 import com.android.internal.telephony.Call;
55 import com.android.internal.telephony.CallManager;
56 import com.android.internal.telephony.IccCard;
57 import com.android.internal.telephony.MmiCode;
58 import com.android.internal.telephony.Phone;
59 import com.android.internal.telephony.PhoneFactory;
60 import com.android.internal.telephony.TelephonyIntents;
61 import com.android.internal.telephony.cdma.EriInfo;
62 import com.android.internal.telephony.cdma.TtyIntent;
63 import com.android.internal.telephony.sip.SipPhoneFactory;
64 import com.android.phone.OtaUtils.CdmaOtaScreenState;
65 import com.android.server.sip.SipService;
66 
67 /**
68  * Top-level Application class for the Phone app.
69  */
70 public class PhoneApp extends Application implements AccelerometerListener.OrientationListener {
71     /* package */ static final String LOG_TAG = "PhoneApp";
72 
73     /**
74      * Phone app-wide debug level:
75      *   0 - no debug logging
76      *   1 - normal debug logging if ro.debuggable is set (which is true in
77      *       "eng" and "userdebug" builds but not "user" builds)
78      *   2 - ultra-verbose debug logging
79      *
80      * Most individual classes in the phone app have a local DBG constant,
81      * typically set to
82      *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
83      * or else
84      *   (PhoneApp.DBG_LEVEL >= 2)
85      * depending on the desired verbosity.
86      *
87      * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
88      */
89     /* package */ static final int DBG_LEVEL = 0;
90 
91     private static final boolean DBG =
92             (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
93     private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2);
94 
95     // Message codes; see mHandler below.
96     private static final int EVENT_SIM_NETWORK_LOCKED = 3;
97     private static final int EVENT_WIRED_HEADSET_PLUG = 7;
98     private static final int EVENT_SIM_STATE_CHANGED = 8;
99     private static final int EVENT_UPDATE_INCALL_NOTIFICATION = 9;
100     private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
101     private static final int EVENT_DATA_ROAMING_OK = 11;
102     private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 12;
103     private static final int EVENT_DOCK_STATE_CHANGED = 13;
104     private static final int EVENT_TTY_PREFERRED_MODE_CHANGED = 14;
105     private static final int EVENT_TTY_MODE_GET = 15;
106     private static final int EVENT_TTY_MODE_SET = 16;
107     private static final int EVENT_START_SIP_SERVICE = 17;
108 
109     // The MMI codes are also used by the InCallScreen.
110     public static final int MMI_INITIATE = 51;
111     public static final int MMI_COMPLETE = 52;
112     public static final int MMI_CANCEL = 53;
113     // Don't use message codes larger than 99 here; those are reserved for
114     // the individual Activities of the Phone UI.
115 
116     /**
117      * Allowable values for the poke lock code (timeout between a user activity and the
118      * going to sleep), please refer to {@link com.android.server.PowerManagerService}
119      * for additional reference.
120      *   SHORT uses the short delay for the timeout (SHORT_KEYLIGHT_DELAY, 6 sec)
121      *   MEDIUM uses the medium delay for the timeout (MEDIUM_KEYLIGHT_DELAY, 15 sec)
122      *   DEFAULT is the system-wide default delay for the timeout (1 min)
123      */
124     public enum ScreenTimeoutDuration {
125         SHORT,
126         MEDIUM,
127         DEFAULT
128     }
129 
130     /**
131      * Allowable values for the wake lock code.
132      *   SLEEP means the device can be put to sleep.
133      *   PARTIAL means wake the processor, but we display can be kept off.
134      *   FULL means wake both the processor and the display.
135      */
136     public enum WakeState {
137         SLEEP,
138         PARTIAL,
139         FULL
140     }
141 
142     private static PhoneApp sMe;
143 
144     // A few important fields we expose to the rest of the package
145     // directly (rather than thru set/get methods) for efficiency.
146     Phone phone;
147     CallNotifier notifier;
148     Ringer ringer;
149     BluetoothHandsfree mBtHandsfree;
150     PhoneInterfaceManager phoneMgr;
151     CallManager mCM;
152     int mBluetoothHeadsetState = BluetoothHeadset.STATE_ERROR;
153     int mBluetoothHeadsetAudioState = BluetoothHeadset.STATE_ERROR;
154     boolean mShowBluetoothIndication = false;
155     static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
156 
157     // Internal PhoneApp Call state tracker
158     CdmaPhoneCallState cdmaPhoneCallState;
159 
160     // The InCallScreen instance (or null if the InCallScreen hasn't been
161     // created yet.)
162     private InCallScreen mInCallScreen;
163 
164     // The currently-active PUK entry activity and progress dialog.
165     // Normally, these are the Emergency Dialer and the subsequent
166     // progress dialog.  null if there is are no such objects in
167     // the foreground.
168     private Activity mPUKEntryActivity;
169     private ProgressDialog mPUKEntryProgressDialog;
170 
171     private boolean mIsSimPinEnabled;
172     private String mCachedSimPin;
173 
174     // True if a wired headset is currently plugged in, based on the state
175     // from the latest Intent.ACTION_HEADSET_PLUG broadcast we received in
176     // mReceiver.onReceive().
177     private boolean mIsHeadsetPlugged;
178 
179     // True if the keyboard is currently *not* hidden
180     // Gets updated whenever there is a Configuration change
181     private boolean mIsHardKeyboardOpen;
182 
183     // True if we are beginning a call, but the phone state has not changed yet
184     private boolean mBeginningCall;
185 
186     // Last phone state seen by updatePhoneState()
187     Phone.State mLastPhoneState = Phone.State.IDLE;
188 
189     private WakeState mWakeState = WakeState.SLEEP;
190     private ScreenTimeoutDuration mScreenTimeoutDuration = ScreenTimeoutDuration.DEFAULT;
191     private boolean mIgnoreTouchUserActivity = false;
192     private IBinder mPokeLockToken = new Binder();
193     private IPowerManager mPowerManagerService;
194     private PowerManager.WakeLock mWakeLock;
195     private PowerManager.WakeLock mPartialWakeLock;
196     private PowerManager.WakeLock mProximityWakeLock;
197     private KeyguardManager mKeyguardManager;
198     private StatusBarManager mStatusBarManager;
199     private int mStatusBarDisableCount;
200     private AccelerometerListener mAccelerometerListener;
201     private int mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
202 
203     // Broadcast receiver for various intent broadcasts (see onCreate())
204     private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
205 
206     // Broadcast receiver purely for ACTION_MEDIA_BUTTON broadcasts
207     private final BroadcastReceiver mMediaButtonReceiver = new MediaButtonBroadcastReceiver();
208 
209     /** boolean indicating restoring mute state on InCallScreen.onResume() */
210     private boolean mShouldRestoreMuteOnInCallResume;
211 
212     // Following are the CDMA OTA information Objects used during OTA Call.
213     // cdmaOtaProvisionData object store static OTA information that needs
214     // to be maintained even during Slider open/close scenarios.
215     // cdmaOtaConfigData object stores configuration info to control visiblity
216     // of each OTA Screens.
217     // cdmaOtaScreenState object store OTA Screen State information.
218     public OtaUtils.CdmaOtaProvisionData cdmaOtaProvisionData;
219     public OtaUtils.CdmaOtaConfigData cdmaOtaConfigData;
220     public OtaUtils.CdmaOtaScreenState cdmaOtaScreenState;
221     public OtaUtils.CdmaOtaInCallScreenUiState cdmaOtaInCallScreenUiState;
222 
223     // TTY feature enabled on this platform
224     private boolean mTtyEnabled;
225     // Current TTY operating mode selected by user
226     private int mPreferredTtyMode = Phone.TTY_MODE_OFF;
227 
228     /**
229      * Set the restore mute state flag. Used when we are setting the mute state
230      * OUTSIDE of user interaction {@link PhoneUtils#startNewCall(Phone)}
231      */
setRestoreMuteOnInCallResume(boolean mode)232     /*package*/void setRestoreMuteOnInCallResume (boolean mode) {
233         mShouldRestoreMuteOnInCallResume = mode;
234     }
235 
236     /**
237      * Get the restore mute state flag.
238      * This is used by the InCallScreen {@link InCallScreen#onResume()} to figure
239      * out if we need to restore the mute state for the current active call.
240      */
getRestoreMuteOnInCallResume()241     /*package*/boolean getRestoreMuteOnInCallResume () {
242         return mShouldRestoreMuteOnInCallResume;
243     }
244 
245     Handler mHandler = new Handler() {
246         @Override
247         public void handleMessage(Message msg) {
248             Phone.State phoneState;
249             switch (msg.what) {
250                 // Starts the SIP service. It's a no-op if SIP API is not supported
251                 // on the deivce.
252                 // TODO: Having the phone process host the SIP service is only
253                 // temporary. Will move it to a persistent communication process
254                 // later.
255                 case EVENT_START_SIP_SERVICE:
256                     SipService.start(getApplicationContext());
257                     break;
258 
259                 // TODO: This event should be handled by the lock screen, just
260                 // like the "SIM missing" and "Sim locked" cases (bug 1804111).
261                 case EVENT_SIM_NETWORK_LOCKED:
262                     if (getResources().getBoolean(R.bool.ignore_sim_network_locked_events)) {
263                         // Some products don't have the concept of a "SIM network lock"
264                         Log.i(LOG_TAG, "Ignoring EVENT_SIM_NETWORK_LOCKED event; "
265                               + "not showing 'SIM network unlock' PIN entry screen");
266                     } else {
267                         // Normal case: show the "SIM network unlock" PIN entry screen.
268                         // The user won't be able to do anything else until
269                         // they enter a valid SIM network PIN.
270                         Log.i(LOG_TAG, "show sim depersonal panel");
271                         IccNetworkDepersonalizationPanel ndpPanel =
272                                 new IccNetworkDepersonalizationPanel(PhoneApp.getInstance());
273                         ndpPanel.show();
274                     }
275                     break;
276 
277                 case EVENT_UPDATE_INCALL_NOTIFICATION:
278                     // Tell the NotificationMgr to update the "ongoing
279                     // call" icon in the status bar, if necessary.
280                     // Currently, this is triggered by a bluetooth headset
281                     // state change (since the status bar icon needs to
282                     // turn blue when bluetooth is active.)
283                     if (DBG) Log.d (LOG_TAG, "- updating in-call notification from handler...");
284                     NotificationMgr.getDefault().updateInCallNotification();
285                     break;
286 
287                 case EVENT_DATA_ROAMING_DISCONNECTED:
288                     NotificationMgr.getDefault().showDataDisconnectedRoaming();
289                     break;
290 
291                 case EVENT_DATA_ROAMING_OK:
292                     NotificationMgr.getDefault().hideDataDisconnectedRoaming();
293                     break;
294 
295                 case MMI_COMPLETE:
296                     onMMIComplete((AsyncResult) msg.obj);
297                     break;
298 
299                 case MMI_CANCEL:
300                     PhoneUtils.cancelMmiCode(phone);
301                     break;
302 
303                 case EVENT_WIRED_HEADSET_PLUG:
304                     // Since the presence of a wired headset or bluetooth affects the
305                     // speakerphone, update the "speaker" state.  We ONLY want to do
306                     // this on the wired headset connect / disconnect events for now
307                     // though, so we're only triggering on EVENT_WIRED_HEADSET_PLUG.
308 
309                     phoneState = mCM.getState();
310                     // Do not change speaker state if phone is not off hook
311                     if (phoneState == Phone.State.OFFHOOK) {
312                         if (mBtHandsfree == null || !mBtHandsfree.isAudioOn()) {
313                             if (!isHeadsetPlugged()) {
314                                 // if the state is "not connected", restore the speaker state.
315                                 PhoneUtils.restoreSpeakerMode(getApplicationContext());
316                             } else {
317                                 // if the state is "connected", force the speaker off without
318                                 // storing the state.
319                                 PhoneUtils.turnOnSpeaker(getApplicationContext(), false, false);
320                             }
321                         }
322                     }
323                     // Update the Proximity sensor based on headset state
324                     updateProximitySensorMode(phoneState);
325 
326                     // Force TTY state update according to new headset state
327                     if (mTtyEnabled) {
328                         sendMessage(obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
329                     }
330                     break;
331 
332                 case EVENT_SIM_STATE_CHANGED:
333                     // Marks the event where the SIM goes into ready state.
334                     // Right now, this is only used for the PUK-unlocking
335                     // process.
336                     if (msg.obj.equals(IccCard.INTENT_VALUE_ICC_READY)) {
337                         // when the right event is triggered and there
338                         // are UI objects in the foreground, we close
339                         // them to display the lock panel.
340                         if (mPUKEntryActivity != null) {
341                             mPUKEntryActivity.finish();
342                             mPUKEntryActivity = null;
343                         }
344                         if (mPUKEntryProgressDialog != null) {
345                             mPUKEntryProgressDialog.dismiss();
346                             mPUKEntryProgressDialog = null;
347                         }
348                     }
349                     break;
350 
351                 case EVENT_UNSOL_CDMA_INFO_RECORD:
352                     //TODO: handle message here;
353                     break;
354 
355                 case EVENT_DOCK_STATE_CHANGED:
356                     // If the phone is docked/undocked during a call, and no wired or BT headset
357                     // is connected: turn on/off the speaker accordingly.
358                     boolean inDockMode = false;
359                     if (mDockState == Intent.EXTRA_DOCK_STATE_DESK ||
360                             mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
361                         inDockMode = true;
362                     }
363                     if (VDBG) Log.d(LOG_TAG, "received EVENT_DOCK_STATE_CHANGED. Phone inDock = "
364                             + inDockMode);
365 
366                     phoneState = mCM.getState();
367                     if (phoneState == Phone.State.OFFHOOK &&
368                             !isHeadsetPlugged() &&
369                             !(mBtHandsfree != null && mBtHandsfree.isAudioOn())) {
370                         PhoneUtils.turnOnSpeaker(getApplicationContext(), inDockMode, true);
371 
372                         if (mInCallScreen != null) {
373                             mInCallScreen.requestUpdateTouchUi();
374                         }
375                     }
376 
377                 case EVENT_TTY_PREFERRED_MODE_CHANGED:
378                     // TTY mode is only applied if a headset is connected
379                     int ttyMode;
380                     if (isHeadsetPlugged()) {
381                         ttyMode = mPreferredTtyMode;
382                     } else {
383                         ttyMode = Phone.TTY_MODE_OFF;
384                     }
385                     phone.setTTYMode(ttyMode, mHandler.obtainMessage(EVENT_TTY_MODE_SET));
386                     break;
387 
388                 case EVENT_TTY_MODE_GET:
389                     handleQueryTTYModeResponse(msg);
390                     break;
391 
392                 case EVENT_TTY_MODE_SET:
393                     handleSetTTYModeResponse(msg);
394                     break;
395             }
396         }
397     };
398 
PhoneApp()399     public PhoneApp() {
400         sMe = this;
401     }
402 
403     @Override
onCreate()404     public void onCreate() {
405         if (VDBG) Log.v(LOG_TAG, "onCreate()...");
406 
407         ContentResolver resolver = getContentResolver();
408 
409         if (phone == null) {
410             // Initialize the telephony framework
411             PhoneFactory.makeDefaultPhones(this);
412 
413             // Get the default phone
414             phone = PhoneFactory.getDefaultPhone();
415 
416             mCM = CallManager.getInstance();
417             mCM.registerPhone(phone);
418 
419 
420             NotificationMgr.init(this);
421 
422             phoneMgr = new PhoneInterfaceManager(this, phone);
423 
424             mHandler.sendEmptyMessage(EVENT_START_SIP_SERVICE);
425 
426             int phoneType = phone.getPhoneType();
427 
428             if (phoneType == Phone.PHONE_TYPE_CDMA) {
429                 // Create an instance of CdmaPhoneCallState and initialize it to IDLE
430                 cdmaPhoneCallState = new CdmaPhoneCallState();
431                 cdmaPhoneCallState.CdmaPhoneCallStateInit();
432             }
433 
434             if (BluetoothAdapter.getDefaultAdapter() != null) {
435                 mBtHandsfree = new BluetoothHandsfree(this, mCM);
436                 startService(new Intent(this, BluetoothHeadsetService.class));
437             } else {
438                 // Device is not bluetooth capable
439                 mBtHandsfree = null;
440             }
441 
442             ringer = new Ringer(this);
443 
444             // before registering for phone state changes
445             PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
446             mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
447                     | PowerManager.ACQUIRE_CAUSES_WAKEUP,
448                     LOG_TAG);
449             // lock used to keep the processor awake, when we don't care for the display.
450             mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
451                     | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
452             // Wake lock used to control proximity sensor behavior.
453             if ((pm.getSupportedWakeLockFlags()
454                  & PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) {
455                 mProximityWakeLock =
456                         pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
457             }
458             if (DBG) Log.d(LOG_TAG, "onCreate: mProximityWakeLock: " + mProximityWakeLock);
459 
460             // create mAccelerometerListener only if we are using the proximity sensor
461             if (proximitySensorModeEnabled()) {
462                 mAccelerometerListener = new AccelerometerListener(this, this);
463             }
464 
465             mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
466             mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
467 
468             // get a handle to the service so that we can use it later when we
469             // want to set the poke lock.
470             mPowerManagerService = IPowerManager.Stub.asInterface(
471                     ServiceManager.getService("power"));
472 
473             notifier = new CallNotifier(this, phone, ringer, mBtHandsfree, new CallLogAsync());
474 
475             // register for ICC status
476             IccCard sim = phone.getIccCard();
477             if (sim != null) {
478                 if (VDBG) Log.v(LOG_TAG, "register for ICC status");
479                 sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
480             }
481 
482             // register for MMI/USSD
483             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
484 
485             // register connection tracking to PhoneUtils
486             PhoneUtils.initializeConnectionHandler(mCM);
487 
488             // Read platform settings for TTY feature
489             mTtyEnabled = getResources().getBoolean(R.bool.tty_enabled);
490 
491             // Register for misc other intent broadcasts.
492             IntentFilter intentFilter =
493                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
494             intentFilter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
495             intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
496             intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
497             intentFilter.addAction(Intent.ACTION_HEADSET_PLUG);
498             intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
499             intentFilter.addAction(Intent.ACTION_BATTERY_LOW);
500             intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
501             intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
502             intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
503             intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
504             if (mTtyEnabled) {
505                 intentFilter.addAction(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION);
506             }
507             intentFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
508             registerReceiver(mReceiver, intentFilter);
509 
510             // Use a separate receiver for ACTION_MEDIA_BUTTON broadcasts,
511             // since we need to manually adjust its priority (to make sure
512             // we get these intents *before* the media player.)
513             IntentFilter mediaButtonIntentFilter =
514                     new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
515             //
516             // Make sure we're higher priority than the media player's
517             // MediaButtonIntentReceiver (which currently has the default
518             // priority of zero; see apps/Music/AndroidManifest.xml.)
519             mediaButtonIntentFilter.setPriority(1);
520             //
521             registerReceiver(mMediaButtonReceiver, mediaButtonIntentFilter);
522 
523             //set the default values for the preferences in the phone.
524             PreferenceManager.setDefaultValues(this, R.xml.network_setting, false);
525 
526             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
527 
528             // Make sure the audio mode (along with some
529             // audio-mode-related state of our own) is initialized
530             // correctly, given the current state of the phone.
531             PhoneUtils.setAudioMode(mCM);
532         }
533 
534         boolean phoneIsCdma = (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA);
535 
536         if (phoneIsCdma) {
537             cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
538             cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
539             cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
540             cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
541         }
542 
543         // XXX pre-load the SimProvider so that it's ready
544         resolver.getType(Uri.parse("content://icc/adn"));
545 
546         // start with the default value to set the mute state.
547         mShouldRestoreMuteOnInCallResume = false;
548 
549         // TODO: Register for Cdma Information Records
550         // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
551 
552         // Read TTY settings and store it into BP NV.
553         // AP owns (i.e. stores) the TTY setting in AP settings database and pushes the setting
554         // to BP at power up (BP does not need to make the TTY setting persistent storage).
555         // This way, there is a single owner (i.e AP) for the TTY setting in the phone.
556         if (mTtyEnabled) {
557             mPreferredTtyMode = android.provider.Settings.Secure.getInt(
558                     phone.getContext().getContentResolver(),
559                     android.provider.Settings.Secure.PREFERRED_TTY_MODE,
560                     Phone.TTY_MODE_OFF);
561             mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
562         }
563         // Read HAC settings and configure audio hardware
564         if (getResources().getBoolean(R.bool.hac_enabled)) {
565             int hac = android.provider.Settings.System.getInt(phone.getContext().getContentResolver(),
566                                                               android.provider.Settings.System.HEARING_AID,
567                                                               0);
568             AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
569             audioManager.setParameter(CallFeaturesSetting.HAC_KEY, hac != 0 ?
570                                       CallFeaturesSetting.HAC_VAL_ON :
571                                       CallFeaturesSetting.HAC_VAL_OFF);
572         }
573    }
574 
575     @Override
onConfigurationChanged(Configuration newConfig)576     public void onConfigurationChanged(Configuration newConfig) {
577         if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
578             mIsHardKeyboardOpen = true;
579         } else {
580             mIsHardKeyboardOpen = false;
581         }
582 
583         // Update the Proximity sensor based on keyboard state
584         updateProximitySensorMode(mCM.getState());
585         super.onConfigurationChanged(newConfig);
586     }
587 
588     /**
589      * Returns the singleton instance of the PhoneApp.
590      */
getInstance()591     static PhoneApp getInstance() {
592         return sMe;
593     }
594 
595     /**
596      * Returns the Phone associated with this instance
597      */
getPhone()598     static Phone getPhone() {
599         return getInstance().phone;
600     }
601 
getRinger()602     Ringer getRinger() {
603         return ringer;
604     }
605 
getBluetoothHandsfree()606     BluetoothHandsfree getBluetoothHandsfree() {
607         return mBtHandsfree;
608     }
609 
createCallLogIntent()610     static Intent createCallLogIntent() {
611         Intent  intent = new Intent(Intent.ACTION_VIEW, null);
612         intent.setType("vnd.android.cursor.dir/calls");
613         return intent;
614     }
615 
616     /**
617      * Return an Intent that can be used to bring up the in-call screen.
618      *
619      * This intent can only be used from within the Phone app, since the
620      * InCallScreen is not exported from our AndroidManifest.
621      */
createInCallIntent()622     /* package */ static Intent createInCallIntent() {
623         Intent intent = new Intent(Intent.ACTION_MAIN, null);
624         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
625                 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
626                 | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
627         intent.setClassName("com.android.phone", getCallScreenClassName());
628         return intent;
629     }
630 
631     /**
632      * Variation of createInCallIntent() that also specifies whether the
633      * DTMF dialpad should be initially visible when the InCallScreen
634      * comes up.
635      */
createInCallIntent(boolean showDialpad)636     /* package */ static Intent createInCallIntent(boolean showDialpad) {
637         Intent intent = createInCallIntent();
638         intent.putExtra(InCallScreen.SHOW_DIALPAD_EXTRA, showDialpad);
639         return intent;
640     }
641 
getCallScreenClassName()642     static String getCallScreenClassName() {
643         return InCallScreen.class.getName();
644     }
645 
646     /**
647      * Starts the InCallScreen Activity.
648      */
displayCallScreen()649     private void displayCallScreen() {
650         if (VDBG) Log.d(LOG_TAG, "displayCallScreen()...");
651         startActivity(createInCallIntent());
652         Profiler.callScreenRequested();
653     }
654 
isSimPinEnabled()655     boolean isSimPinEnabled() {
656         return mIsSimPinEnabled;
657     }
658 
authenticateAgainstCachedSimPin(String pin)659     boolean authenticateAgainstCachedSimPin(String pin) {
660         return (mCachedSimPin != null && mCachedSimPin.equals(pin));
661     }
662 
setCachedSimPin(String pin)663     void setCachedSimPin(String pin) {
664         mCachedSimPin = pin;
665     }
666 
setInCallScreenInstance(InCallScreen inCallScreen)667     void setInCallScreenInstance(InCallScreen inCallScreen) {
668         mInCallScreen = inCallScreen;
669     }
670 
671     /**
672      * @return true if the in-call UI is running as the foreground
673      * activity.  (In other words, from the perspective of the
674      * InCallScreen activity, return true between onResume() and
675      * onPause().)
676      *
677      * Note this method will return false if the screen is currently off,
678      * even if the InCallScreen *was* in the foreground just before the
679      * screen turned off.  (This is because the foreground activity is
680      * always "paused" while the screen is off.)
681      */
isShowingCallScreen()682     boolean isShowingCallScreen() {
683         if (mInCallScreen == null) return false;
684         return mInCallScreen.isForegroundActivity();
685     }
686 
687     /**
688      * Dismisses the in-call UI.
689      *
690      * This also ensures that you won't be able to get back to the in-call
691      * UI via the BACK button (since this call removes the InCallScreen
692      * from the activity history.)
693      * For OTA Call, it call InCallScreen api to handle OTA Call End scenario
694      * to display OTA Call End screen.
695      */
dismissCallScreen()696     void dismissCallScreen() {
697         if (mInCallScreen != null) {
698             if ((phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) &&
699                     (mInCallScreen.isOtaCallInActiveState()
700                     || mInCallScreen.isOtaCallInEndState()
701                     || ((cdmaOtaScreenState != null)
702                     && (cdmaOtaScreenState.otaScreenState
703                             != CdmaOtaScreenState.OtaScreenState.OTA_STATUS_UNDEFINED)))) {
704                 // TODO: During OTA Call, display should not become dark to
705                 // allow user to see OTA UI update. Phone app needs to hold
706                 // a SCREEN_DIM_WAKE_LOCK wake lock during the entire OTA call.
707                 wakeUpScreen();
708                 // If InCallScreen is not in foreground we resume it to show the OTA call end screen
709                 // Fire off the InCallScreen intent
710                 displayCallScreen();
711 
712                 mInCallScreen.handleOtaCallEnd();
713                 return;
714             } else {
715                 mInCallScreen.finish();
716             }
717         }
718     }
719 
720     /**
721      * Handle OTA events
722      *
723      * When OTA call is active and display becomes dark, then CallNotifier will
724      * handle OTA Events by calling this api which then calls OtaUtil function.
725      */
handleOtaEvents(Message msg)726     void handleOtaEvents(Message msg) {
727 
728         if (DBG) Log.d(LOG_TAG, "Enter handleOtaEvents");
729         if ((mInCallScreen != null) && (!isShowingCallScreen())) {
730             if (mInCallScreen.otaUtils != null) {
731                 mInCallScreen.otaUtils.onOtaProvisionStatusChanged((AsyncResult) msg.obj);
732             }
733         }
734     }
735 
736 
737     /**
738      * Sets the activity responsible for un-PUK-blocking the device
739      * so that we may close it when we receive a positive result.
740      * mPUKEntryActivity is also used to indicate to the device that
741      * we are trying to un-PUK-lock the phone. In other words, iff
742      * it is NOT null, then we are trying to unlock and waiting for
743      * the SIM to move to READY state.
744      *
745      * @param activity is the activity to close when PUK has
746      * finished unlocking. Can be set to null to indicate the unlock
747      * or SIM READYing process is over.
748      */
setPukEntryActivity(Activity activity)749     void setPukEntryActivity(Activity activity) {
750         mPUKEntryActivity = activity;
751     }
752 
getPUKEntryActivity()753     Activity getPUKEntryActivity() {
754         return mPUKEntryActivity;
755     }
756 
757     /**
758      * Sets the dialog responsible for notifying the user of un-PUK-
759      * blocking - SIM READYing progress, so that we may dismiss it
760      * when we receive a positive result.
761      *
762      * @param dialog indicates the progress dialog informing the user
763      * of the state of the device.  Dismissed upon completion of
764      * READYing process
765      */
setPukEntryProgressDialog(ProgressDialog dialog)766     void setPukEntryProgressDialog(ProgressDialog dialog) {
767         mPUKEntryProgressDialog = dialog;
768     }
769 
getPUKEntryProgressDialog()770     ProgressDialog getPUKEntryProgressDialog() {
771         return mPUKEntryProgressDialog;
772     }
773 
774     /**
775      * Disables the status bar.  This is used by the phone app when in-call UI is active.
776      *
777      * Any call to this method MUST be followed (eventually)
778      * by a corresponding reenableStatusBar() call.
779      */
disableStatusBar()780     /* package */ void disableStatusBar() {
781         if (DBG) Log.d(LOG_TAG, "disable status bar");
782         synchronized (this) {
783             if (mStatusBarDisableCount++ == 0) {
784                if (DBG)  Log.d(LOG_TAG, "StatusBarManager.DISABLE_EXPAND");
785                 mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
786             }
787         }
788     }
789 
790     /**
791      * Re-enables the status bar after a previous disableStatusBar() call.
792      *
793      * Any call to this method MUST correspond to (i.e. be balanced with)
794      * a previous disableStatusBar() call.
795      */
reenableStatusBar()796     /* package */ void reenableStatusBar() {
797         if (DBG) Log.d(LOG_TAG, "re-enable status bar");
798         synchronized (this) {
799             if (mStatusBarDisableCount > 0) {
800                 if (--mStatusBarDisableCount == 0) {
801                     if (DBG) Log.d(LOG_TAG, "StatusBarManager.DISABLE_NONE");
802                     mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
803                 }
804             } else {
805                 Log.e(LOG_TAG, "mStatusBarDisableCount is already zero");
806             }
807         }
808     }
809 
810     /**
811      * Controls how quickly the screen times out.
812      *
813      * The poke lock controls how long it takes before the screen powers
814      * down, and therefore has no immediate effect when the current
815      * WakeState (see {@link PhoneApp#requestWakeState}) is FULL.
816      * If we're in a state where the screen *is* allowed to turn off,
817      * though, the poke lock will determine the timeout interval (long or
818      * short).
819      *
820      * @param shortPokeLock tells the device the timeout duration to use
821      * before going to sleep
822      * {@link com.android.server.PowerManagerService#SHORT_KEYLIGHT_DELAY}.
823      */
setScreenTimeout(ScreenTimeoutDuration duration)824     /* package */ void setScreenTimeout(ScreenTimeoutDuration duration) {
825         if (VDBG) Log.d(LOG_TAG, "setScreenTimeout(" + duration + ")...");
826 
827         // make sure we don't set the poke lock repeatedly so that we
828         // avoid triggering the userActivity calls in
829         // PowerManagerService.setPokeLock().
830         if (duration == mScreenTimeoutDuration) {
831             return;
832         }
833         // stick with default timeout if we are using the proximity sensor
834         if (proximitySensorModeEnabled()) {
835             return;
836         }
837         mScreenTimeoutDuration = duration;
838         updatePokeLock();
839     }
840 
841     /**
842      * Update the state of the poke lock held by the phone app,
843      * based on the current desired screen timeout and the
844      * current "ignore user activity on touch" flag.
845      */
updatePokeLock()846     private void updatePokeLock() {
847         // This is kind of convoluted, but the basic thing to remember is
848         // that the poke lock just sends a message to the screen to tell
849         // it to stay on for a while.
850         // The default is 0, for a long timeout and should be set that way
851         // when we are heading back into a the keyguard / screen off
852         // state, and also when we're trying to keep the screen alive
853         // while ringing.  We'll also want to ignore the cheek events
854         // regardless of the timeout duration.
855         // The short timeout is really used whenever we want to give up
856         // the screen lock, such as when we're in call.
857         int pokeLockSetting = LocalPowerManager.POKE_LOCK_IGNORE_CHEEK_EVENTS;
858         switch (mScreenTimeoutDuration) {
859             case SHORT:
860                 // Set the poke lock to timeout the display after a short
861                 // timeout (5s). This ensures that the screen goes to sleep
862                 // as soon as acceptably possible after we the wake lock
863                 // has been released.
864                 pokeLockSetting |= LocalPowerManager.POKE_LOCK_SHORT_TIMEOUT;
865                 break;
866 
867             case MEDIUM:
868                 // Set the poke lock to timeout the display after a medium
869                 // timeout (15s). This ensures that the screen goes to sleep
870                 // as soon as acceptably possible after we the wake lock
871                 // has been released.
872                 pokeLockSetting |= LocalPowerManager.POKE_LOCK_MEDIUM_TIMEOUT;
873                 break;
874 
875             case DEFAULT:
876             default:
877                 // set the poke lock to timeout the display after a long
878                 // delay by default.
879                 // TODO: it may be nice to be able to disable cheek presses
880                 // for long poke locks (emergency dialer, for instance).
881                 break;
882         }
883 
884         if (mIgnoreTouchUserActivity) {
885             pokeLockSetting |= LocalPowerManager.POKE_LOCK_IGNORE_TOUCH_AND_CHEEK_EVENTS;
886         }
887 
888         // Send the request
889         try {
890             mPowerManagerService.setPokeLock(pokeLockSetting, mPokeLockToken, LOG_TAG);
891         } catch (RemoteException e) {
892             Log.w(LOG_TAG, "mPowerManagerService.setPokeLock() failed: " + e);
893         }
894     }
895 
896     /**
897      * Controls whether or not the screen is allowed to sleep.
898      *
899      * Once sleep is allowed (WakeState is SLEEP), it will rely on the
900      * settings for the poke lock to determine when to timeout and let
901      * the device sleep {@link PhoneApp#setScreenTimeout}.
902      *
903      * @param ws tells the device to how to wake.
904      */
requestWakeState(WakeState ws)905     /* package */ void requestWakeState(WakeState ws) {
906         if (VDBG) Log.d(LOG_TAG, "requestWakeState(" + ws + ")...");
907         synchronized (this) {
908             if (mWakeState != ws) {
909                 switch (ws) {
910                     case PARTIAL:
911                         // acquire the processor wake lock, and release the FULL
912                         // lock if it is being held.
913                         mPartialWakeLock.acquire();
914                         if (mWakeLock.isHeld()) {
915                             mWakeLock.release();
916                         }
917                         break;
918                     case FULL:
919                         // acquire the full wake lock, and release the PARTIAL
920                         // lock if it is being held.
921                         mWakeLock.acquire();
922                         if (mPartialWakeLock.isHeld()) {
923                             mPartialWakeLock.release();
924                         }
925                         break;
926                     case SLEEP:
927                     default:
928                         // release both the PARTIAL and FULL locks.
929                         if (mWakeLock.isHeld()) {
930                             mWakeLock.release();
931                         }
932                         if (mPartialWakeLock.isHeld()) {
933                             mPartialWakeLock.release();
934                         }
935                         break;
936                 }
937                 mWakeState = ws;
938             }
939         }
940     }
941 
942     /**
943      * If we are not currently keeping the screen on, then poke the power
944      * manager to wake up the screen for the user activity timeout duration.
945      */
wakeUpScreen()946     /* package */ void wakeUpScreen() {
947         synchronized (this) {
948             if (mWakeState == WakeState.SLEEP) {
949                 if (DBG) Log.d(LOG_TAG, "pulse screen lock");
950                 try {
951                     mPowerManagerService.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
952                 } catch (RemoteException ex) {
953                     // Ignore -- the system process is dead.
954                 }
955             }
956         }
957     }
958 
959     /**
960      * Sets the wake state and screen timeout based on the current state
961      * of the phone, and the current state of the in-call UI.
962      *
963      * This method is a "UI Policy" wrapper around
964      * {@link PhoneApp#requestWakeState} and {@link PhoneApp#setScreenTimeout}.
965      *
966      * It's safe to call this method regardless of the state of the Phone
967      * (e.g. whether or not it's idle), and regardless of the state of the
968      * Phone UI (e.g. whether or not the InCallScreen is active.)
969      */
updateWakeState()970     /* package */ void updateWakeState() {
971         Phone.State state = mCM.getState();
972 
973         // True if the in-call UI is the foreground activity.
974         // (Note this will be false if the screen is currently off,
975         // since in that case *no* activity is in the foreground.)
976         boolean isShowingCallScreen = isShowingCallScreen();
977 
978         // True if the InCallScreen's DTMF dialer is currently opened.
979         // (Note this does NOT imply whether or not the InCallScreen
980         // itself is visible.)
981         boolean isDialerOpened = (mInCallScreen != null) && mInCallScreen.isDialerOpened();
982 
983         // True if the speakerphone is in use.  (If so, we *always* use
984         // the default timeout.  Since the user is obviously not holding
985         // the phone up to his/her face, we don't need to worry about
986         // false touches, and thus don't need to turn the screen off so
987         // aggressively.)
988         // Note that we need to make a fresh call to this method any
989         // time the speaker state changes.  (That happens in
990         // PhoneUtils.turnOnSpeaker().)
991         boolean isSpeakerInUse = (state == Phone.State.OFFHOOK) && PhoneUtils.isSpeakerOn(this);
992 
993         // TODO (bug 1440854): The screen timeout *might* also need to
994         // depend on the bluetooth state, but this isn't as clear-cut as
995         // the speaker state (since while using BT it's common for the
996         // user to put the phone straight into a pocket, in which case the
997         // timeout should probably still be short.)
998 
999         if (DBG) Log.d(LOG_TAG, "updateWakeState: callscreen " + isShowingCallScreen
1000                        + ", dialer " + isDialerOpened
1001                        + ", speaker " + isSpeakerInUse + "...");
1002 
1003         //
1004         // (1) Set the screen timeout.
1005         //
1006         // Note that the "screen timeout" value we determine here is
1007         // meaningless if the screen is forced on (see (2) below.)
1008         //
1009         if (!isShowingCallScreen || isSpeakerInUse) {
1010             // Use the system-wide default timeout.
1011             setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
1012         } else {
1013             // We're on the in-call screen, and *not* using the speakerphone.
1014             if (isDialerOpened) {
1015                 // The DTMF dialpad is up.  This case is special because
1016                 // the in-call UI has its own "touch lock" mechanism to
1017                 // disable the dialpad after a very short amount of idle
1018                 // time (to avoid false touches from the user's face while
1019                 // in-call.)
1020                 //
1021                 // In this case the *physical* screen just uses the
1022                 // system-wide default timeout.
1023                 setScreenTimeout(ScreenTimeoutDuration.DEFAULT);
1024             } else {
1025                 // We're on the in-call screen, and not using the DTMF dialpad.
1026                 // There's actually no touchable UI onscreen at all in
1027                 // this state.  Also, the user is (most likely) not
1028                 // looking at the screen at all, since they're probably
1029                 // holding the phone up to their face.  Here we use a
1030                 // special screen timeout value specific to the in-call
1031                 // screen, purely to save battery life.
1032                 setScreenTimeout(ScreenTimeoutDuration.MEDIUM);
1033             }
1034         }
1035 
1036         //
1037         // (2) Decide whether to force the screen on or not.
1038         //
1039         // Force the screen to be on if the phone is ringing or dialing,
1040         // or if we're displaying the "Call ended" UI for a connection in
1041         // the "disconnected" state.
1042         //
1043         boolean isRinging = (state == Phone.State.RINGING);
1044         boolean isDialing = (phone.getForegroundCall().getState() == Call.State.DIALING);
1045         boolean showingDisconnectedConnection =
1046                 PhoneUtils.hasDisconnectedConnections(phone) && isShowingCallScreen;
1047         boolean keepScreenOn = isRinging || isDialing || showingDisconnectedConnection;
1048         if (DBG) Log.d(LOG_TAG, "updateWakeState: keepScreenOn = " + keepScreenOn
1049                        + " (isRinging " + isRinging
1050                        + ", isDialing " + isDialing
1051                        + ", showingDisc " + showingDisconnectedConnection + ")");
1052         // keepScreenOn == true means we'll hold a full wake lock:
1053         requestWakeState(keepScreenOn ? WakeState.FULL : WakeState.SLEEP);
1054     }
1055 
1056     /**
1057      * Wrapper around the PowerManagerService.preventScreenOn() API.
1058      * This allows the in-call UI to prevent the screen from turning on
1059      * even if a subsequent call to updateWakeState() causes us to acquire
1060      * a full wake lock.
1061      */
preventScreenOn(boolean prevent)1062     /* package */ void preventScreenOn(boolean prevent) {
1063         if (VDBG) Log.d(LOG_TAG, "- preventScreenOn(" + prevent + ")...");
1064         try {
1065             mPowerManagerService.preventScreenOn(prevent);
1066         } catch (RemoteException e) {
1067             Log.w(LOG_TAG, "mPowerManagerService.preventScreenOn() failed: " + e);
1068         }
1069     }
1070 
1071     /**
1072      * Sets or clears the flag that tells the PowerManager that touch
1073      * (and cheek) events should NOT be considered "user activity".
1074      *
1075      * Since the in-call UI is totally insensitive to touch in most
1076      * states, we set this flag whenever the InCallScreen is in the
1077      * foreground.  (Otherwise, repeated unintentional touches could
1078      * prevent the device from going to sleep.)
1079      *
1080      * There *are* some some touch events that really do count as user
1081      * activity, though.  For those, we need to manually poke the
1082      * PowerManager's userActivity method; see pokeUserActivity().
1083      */
setIgnoreTouchUserActivity(boolean ignore)1084     /* package */ void setIgnoreTouchUserActivity(boolean ignore) {
1085         if (VDBG) Log.d(LOG_TAG, "setIgnoreTouchUserActivity(" + ignore + ")...");
1086         mIgnoreTouchUserActivity = ignore;
1087         updatePokeLock();
1088     }
1089 
1090     /**
1091      * Manually pokes the PowerManager's userActivity method.  Since we
1092      * hold the POKE_LOCK_IGNORE_TOUCH_AND_CHEEK_EVENTS poke lock while
1093      * the InCallScreen is active, we need to do this for touch events
1094      * that really do count as user activity (like DTMF key presses, or
1095      * unlocking the "touch lock" overlay.)
1096      */
pokeUserActivity()1097     /* package */ void pokeUserActivity() {
1098         if (VDBG) Log.d(LOG_TAG, "pokeUserActivity()...");
1099         try {
1100             mPowerManagerService.userActivity(SystemClock.uptimeMillis(), false);
1101         } catch (RemoteException e) {
1102             Log.w(LOG_TAG, "mPowerManagerService.userActivity() failed: " + e);
1103         }
1104     }
1105 
1106     /**
1107      * Set when a new outgoing call is beginning, so we can update
1108      * the proximity sensor state.
1109      * Cleared when the InCallScreen is no longer in the foreground,
1110      * in case the call fails without changing the telephony state.
1111      */
setBeginningCall(boolean beginning)1112     /* package */ void setBeginningCall(boolean beginning) {
1113         // Note that we are beginning a new call, for proximity sensor support
1114         mBeginningCall = beginning;
1115         // Update the Proximity sensor based on mBeginningCall state
1116         updateProximitySensorMode(mCM.getState());
1117     }
1118 
1119     /**
1120      * Updates the wake lock used to control proximity sensor behavior,
1121      * based on the current state of the phone.  This method is called
1122      * from the CallNotifier on any phone state change.
1123      *
1124      * On devices that have a proximity sensor, to avoid false touches
1125      * during a call, we hold a PROXIMITY_SCREEN_OFF_WAKE_LOCK wake lock
1126      * whenever the phone is off hook.  (When held, that wake lock causes
1127      * the screen to turn off automatically when the sensor detects an
1128      * object close to the screen.)
1129      *
1130      * This method is a no-op for devices that don't have a proximity
1131      * sensor.
1132      *
1133      * Note this method doesn't care if the InCallScreen is the foreground
1134      * activity or not.  That's because we want the proximity sensor to be
1135      * enabled any time the phone is in use, to avoid false cheek events
1136      * for whatever app you happen to be running.
1137      *
1138      * Proximity wake lock will *not* be held if any one of the
1139      * conditions is true while on a call:
1140      * 1) If the audio is routed via Bluetooth
1141      * 2) If a wired headset is connected
1142      * 3) if the speaker is ON
1143      * 4) If the slider is open(i.e. the hardkeyboard is *not* hidden)
1144      *
1145      * @param state current state of the phone (see {@link Phone#State})
1146      */
updateProximitySensorMode(Phone.State state)1147     /* package */ void updateProximitySensorMode(Phone.State state) {
1148         if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state);
1149 
1150         if (proximitySensorModeEnabled()) {
1151             synchronized (mProximityWakeLock) {
1152                 // turn proximity sensor off and turn screen on immediately if
1153                 // we are using a headset, the keyboard is open, or the device
1154                 // is being held in a horizontal position.
1155                 boolean screenOnImmediately = (isHeadsetPlugged()
1156                             || PhoneUtils.isSpeakerOn(this)
1157                             || ((mBtHandsfree != null) && mBtHandsfree.isAudioOn())
1158                             || mIsHardKeyboardOpen);
1159                 // We do not keep the screen off when we are horizontal, but we do not force it
1160                 // on when we become horizontal until the proximity sensor goes negative.
1161                 boolean horizontal = (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
1162 
1163                 if (((state == Phone.State.OFFHOOK) || mBeginningCall) &&
1164                         !screenOnImmediately && !horizontal) {
1165                     // Phone is in use!  Arrange for the screen to turn off
1166                     // automatically when the sensor detects a close object.
1167                     if (!mProximityWakeLock.isHeld()) {
1168                         if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");
1169                         mProximityWakeLock.acquire();
1170                     } else {
1171                         if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");
1172                     }
1173                 } else {
1174                     // Phone is either idle, or ringing.  We don't want any
1175                     // special proximity sensor behavior in either case.
1176                     if (mProximityWakeLock.isHeld()) {
1177                         if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing...");
1178                         // Wait until user has moved the phone away from his head if we are
1179                         // releasing due to the phone call ending.
1180                         // Qtherwise, turn screen on immediately
1181                         int flags =
1182                             (screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);
1183                         mProximityWakeLock.release(flags);
1184                     } else {
1185                         if (VDBG) {
1186                             Log.d(LOG_TAG, "updateProximitySensorMode: lock already released.");
1187                         }
1188                     }
1189                 }
1190             }
1191         }
1192     }
1193 
orientationChanged(int orientation)1194     public void orientationChanged(int orientation) {
1195         mOrientation = orientation;
1196         updateProximitySensorMode(mCM.getState());
1197     }
1198 
1199     /**
1200      * Notifies the phone app when the phone state changes.
1201      * Currently used only for proximity sensor support.
1202      */
updatePhoneState(Phone.State state)1203     /* package */ void updatePhoneState(Phone.State state) {
1204         if (state != mLastPhoneState) {
1205             mLastPhoneState = state;
1206             updateProximitySensorMode(state);
1207             if (mAccelerometerListener != null) {
1208                 // use accelerometer to augment proximity sensor when in call
1209                 mOrientation = AccelerometerListener.ORIENTATION_UNKNOWN;
1210                 mAccelerometerListener.enable(state == Phone.State.OFFHOOK);
1211             }
1212             // clear our beginning call flag
1213             mBeginningCall = false;
1214             // While we are in call, the in-call screen should dismiss the keyguard.
1215             // This allows the user to press Home to go directly home without going through
1216             // an insecure lock screen.
1217             // But we do not want to do this if there is no active call so we do not
1218             // bypass the keyguard if the call is not answered or declined.
1219             if (mInCallScreen != null) {
1220                 mInCallScreen.updateKeyguardPolicy(state == Phone.State.OFFHOOK);
1221             }
1222         }
1223     }
1224 
getPhoneState()1225     /* package */ Phone.State getPhoneState() {
1226         return mLastPhoneState;
1227     }
1228 
1229     /**
1230      * @return true if this device supports the "proximity sensor
1231      * auto-lock" feature while in-call (see updateProximitySensorMode()).
1232      */
proximitySensorModeEnabled()1233     /* package */ boolean proximitySensorModeEnabled() {
1234         return (mProximityWakeLock != null);
1235     }
1236 
getKeyguardManager()1237     KeyguardManager getKeyguardManager() {
1238         return mKeyguardManager;
1239     }
1240 
onMMIComplete(AsyncResult r)1241     private void onMMIComplete(AsyncResult r) {
1242         if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
1243         MmiCode mmiCode = (MmiCode) r.result;
1244         PhoneUtils.displayMMIComplete(phone, getInstance(), mmiCode, null, null);
1245     }
1246 
initForNewRadioTechnology()1247     private void initForNewRadioTechnology() {
1248         if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
1249 
1250         if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
1251             // Create an instance of CdmaPhoneCallState and initialize it to IDLE
1252             cdmaPhoneCallState = new CdmaPhoneCallState();
1253             cdmaPhoneCallState.CdmaPhoneCallStateInit();
1254 
1255             //create instances of CDMA OTA data classes
1256             if (cdmaOtaProvisionData == null) {
1257                 cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
1258             }
1259             if (cdmaOtaConfigData == null) {
1260                 cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
1261             }
1262             if (cdmaOtaScreenState == null) {
1263                 cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
1264             }
1265             if (cdmaOtaInCallScreenUiState == null) {
1266                 cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
1267             }
1268         } else {
1269             //Clean up OTA data in GSM/UMTS. It is valid only for CDMA
1270             clearOtaState();
1271         }
1272 
1273         ringer.updateRingerContextAfterRadioTechnologyChange(this.phone);
1274         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
1275         if (mBtHandsfree != null) {
1276             mBtHandsfree.updateBtHandsfreeAfterRadioTechnologyChange();
1277         }
1278         if (mInCallScreen != null) {
1279             mInCallScreen.updateAfterRadioTechnologyChange();
1280         }
1281 
1282         // Update registration for ICC status after radio technology change
1283         IccCard sim = phone.getIccCard();
1284         if (sim != null) {
1285             if (DBG) Log.d(LOG_TAG, "Update registration for ICC status...");
1286 
1287             //Register all events new to the new active phone
1288             sim.registerForNetworkLocked(mHandler, EVENT_SIM_NETWORK_LOCKED, null);
1289         }
1290     }
1291 
1292 
1293     /**
1294      * @return true if a wired headset is currently plugged in.
1295      *
1296      * @see Intent.ACTION_HEADSET_PLUG (which we listen for in mReceiver.onReceive())
1297      */
isHeadsetPlugged()1298     boolean isHeadsetPlugged() {
1299         return mIsHeadsetPlugged;
1300     }
1301 
1302     /**
1303      * @return true if the onscreen UI should currently be showing the
1304      * special "bluetooth is active" indication in a couple of places (in
1305      * which UI elements turn blue and/or show the bluetooth logo.)
1306      *
1307      * This depends on the BluetoothHeadset state *and* the current
1308      * telephony state; see shouldShowBluetoothIndication().
1309      *
1310      * @see CallCard
1311      * @see NotificationMgr.updateInCallNotification
1312      */
showBluetoothIndication()1313     /* package */ boolean showBluetoothIndication() {
1314         return mShowBluetoothIndication;
1315     }
1316 
1317     /**
1318      * Recomputes the mShowBluetoothIndication flag based on the current
1319      * bluetooth state and current telephony state.
1320      *
1321      * This needs to be called any time the bluetooth headset state or the
1322      * telephony state changes.
1323      *
1324      * @param forceUiUpdate if true, force the UI elements that care
1325      *                      about this flag to update themselves.
1326      */
updateBluetoothIndication(boolean forceUiUpdate)1327     /* package */ void updateBluetoothIndication(boolean forceUiUpdate) {
1328         mShowBluetoothIndication = shouldShowBluetoothIndication(mBluetoothHeadsetState,
1329                                                                  mBluetoothHeadsetAudioState,
1330                                                                  mCM);
1331         if (forceUiUpdate) {
1332             // Post Handler messages to the various components that might
1333             // need to be refreshed based on the new state.
1334             if (isShowingCallScreen()) mInCallScreen.requestUpdateBluetoothIndication();
1335             if (DBG) Log.d (LOG_TAG, "- updating in-call notification for BT state change...");
1336             mHandler.sendEmptyMessage(EVENT_UPDATE_INCALL_NOTIFICATION);
1337         }
1338 
1339         // Update the Proximity sensor based on Bluetooth audio state
1340         updateProximitySensorMode(mCM.getState());
1341     }
1342 
1343     /**
1344      * UI policy helper function for the couple of places in the UI that
1345      * have some way of indicating that "bluetooth is in use."
1346      *
1347      * @return true if the onscreen UI should indicate that "bluetooth is in use",
1348      *         based on the specified bluetooth headset state, and the
1349      *         current state of the phone.
1350      * @see showBluetoothIndication()
1351      */
shouldShowBluetoothIndication(int bluetoothState, int bluetoothAudioState, CallManager cm)1352     private static boolean shouldShowBluetoothIndication(int bluetoothState,
1353                                                          int bluetoothAudioState,
1354                                                          CallManager cm) {
1355         // We want the UI to indicate that "bluetooth is in use" in two
1356         // slightly different cases:
1357         //
1358         // (a) The obvious case: if a bluetooth headset is currently in
1359         //     use for an ongoing call.
1360         //
1361         // (b) The not-so-obvious case: if an incoming call is ringing,
1362         //     and we expect that audio *will* be routed to a bluetooth
1363         //     headset once the call is answered.
1364 
1365         switch (cm.getState()) {
1366             case OFFHOOK:
1367                 // This covers normal active calls, and also the case if
1368                 // the foreground call is DIALING or ALERTING.  In this
1369                 // case, bluetooth is considered "active" if a headset
1370                 // is connected *and* audio is being routed to it.
1371                 return ((bluetoothState == BluetoothHeadset.STATE_CONNECTED)
1372                         && (bluetoothAudioState == BluetoothHeadset.AUDIO_STATE_CONNECTED));
1373 
1374             case RINGING:
1375                 // If an incoming call is ringing, we're *not* yet routing
1376                 // audio to the headset (since there's no in-call audio
1377                 // yet!)  In this case, if a bluetooth headset is
1378                 // connected at all, we assume that it'll become active
1379                 // once the user answers the phone.
1380                 return (bluetoothState == BluetoothHeadset.STATE_CONNECTED);
1381 
1382             default:  // Presumably IDLE
1383                 return false;
1384         }
1385     }
1386 
1387 
1388     /**
1389      * Receiver for misc intent broadcasts the Phone app cares about.
1390      */
1391     private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
1392         @Override
onReceive(Context context, Intent intent)1393         public void onReceive(Context context, Intent intent) {
1394             String action = intent.getAction();
1395             if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
1396                 boolean enabled = System.getInt(getContentResolver(),
1397                         System.AIRPLANE_MODE_ON, 0) == 0;
1398                 phone.setRadioPower(enabled);
1399             } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
1400                 mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
1401                                                             BluetoothHeadset.STATE_ERROR);
1402                 if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_STATE_CHANGED_ACTION");
1403                 if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetState);
1404                 updateBluetoothIndication(true);  // Also update any visible UI if necessary
1405             } else if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
1406                 mBluetoothHeadsetAudioState =
1407                         intent.getIntExtra(BluetoothHeadset.EXTRA_AUDIO_STATE,
1408                                            BluetoothHeadset.STATE_ERROR);
1409                 if (VDBG) Log.d(LOG_TAG, "mReceiver: HEADSET_AUDIO_STATE_CHANGED_ACTION");
1410                 if (VDBG) Log.d(LOG_TAG, "==> new state: " + mBluetoothHeadsetAudioState);
1411                 updateBluetoothIndication(true);  // Also update any visible UI if necessary
1412             } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
1413                 if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED");
1414                 if (VDBG) Log.d(LOG_TAG, "- state: " + intent.getStringExtra(Phone.STATE_KEY));
1415                 if (VDBG) Log.d(LOG_TAG, "- reason: "
1416                                 + intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY));
1417 
1418                 // The "data disconnected due to roaming" notification is
1419                 // visible if you've lost data connectivity because you're
1420                 // roaming and you have the "data roaming" feature turned off.
1421                 boolean disconnectedDueToRoaming = false;
1422                 if ("DISCONNECTED".equals(intent.getStringExtra(Phone.STATE_KEY))) {
1423                     String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
1424                     if (Phone.REASON_ROAMING_ON.equals(reason)) {
1425                         // We just lost our data connection, and the reason
1426                         // is that we started roaming.  This implies that
1427                         // the user has data roaming turned off.
1428                         disconnectedDueToRoaming = true;
1429                     }
1430                 }
1431                 mHandler.sendEmptyMessage(disconnectedDueToRoaming
1432                                           ? EVENT_DATA_ROAMING_DISCONNECTED
1433                                           : EVENT_DATA_ROAMING_OK);
1434             } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
1435                 if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_HEADSET_PLUG");
1436                 if (VDBG) Log.d(LOG_TAG, "    state: " + intent.getIntExtra("state", 0));
1437                 if (VDBG) Log.d(LOG_TAG, "    name: " + intent.getStringExtra("name"));
1438                 mIsHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
1439                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_WIRED_HEADSET_PLUG, 0));
1440             } else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
1441                 if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_BATTERY_LOW");
1442                 notifier.sendBatteryLow();  // Play a warning tone if in-call
1443             } else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
1444                     (mPUKEntryActivity != null)) {
1445                 // if an attempt to un-PUK-lock the device was made, while we're
1446                 // receiving this state change notification, notify the handler.
1447                 // NOTE: This is ONLY triggered if an attempt to un-PUK-lock has
1448                 // been attempted.
1449                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
1450                         intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE)));
1451             } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
1452                 String newPhone = intent.getStringExtra(Phone.PHONE_NAME_KEY);
1453                 Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
1454                 initForNewRadioTechnology();
1455             } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
1456                 handleServiceStateChanged(intent);
1457             } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
1458                 if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) {
1459                     Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
1460                     // Start Emergency Callback Mode service
1461                     if (intent.getBooleanExtra("phoneinECMState", false)) {
1462                         context.startService(new Intent(context,
1463                                 EmergencyCallbackModeService.class));
1464                     }
1465                 } else {
1466                     Log.e(LOG_TAG, "Error! Emergency Callback Mode not supported for " +
1467                             phone.getPhoneName() + " phones");
1468                 }
1469             } else if (action.equals(Intent.ACTION_DOCK_EVENT)) {
1470                 mDockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
1471                         Intent.EXTRA_DOCK_STATE_UNDOCKED);
1472                 if (VDBG) Log.d(LOG_TAG, "ACTION_DOCK_EVENT -> mDockState = " + mDockState);
1473                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_DOCK_STATE_CHANGED, 0));
1474             } else if (action.equals(TtyIntent.TTY_PREFERRED_MODE_CHANGE_ACTION)) {
1475                 mPreferredTtyMode = intent.getIntExtra(TtyIntent.TTY_PREFFERED_MODE,
1476                                                        Phone.TTY_MODE_OFF);
1477                 if (VDBG) Log.d(LOG_TAG, "mReceiver: TTY_PREFERRED_MODE_CHANGE_ACTION");
1478                 if (VDBG) Log.d(LOG_TAG, "    mode: " + mPreferredTtyMode);
1479                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_TTY_PREFERRED_MODE_CHANGED, 0));
1480             } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
1481                 int ringerMode = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE,
1482                         AudioManager.RINGER_MODE_NORMAL);
1483                 if(ringerMode == AudioManager.RINGER_MODE_SILENT) {
1484                     notifier.silenceRinger();
1485                 }
1486             }
1487         }
1488     }
1489 
1490     /**
1491      * Broadcast receiver for the ACTION_MEDIA_BUTTON broadcast intent.
1492      *
1493      * This functionality isn't lumped in with the other intents in
1494      * PhoneAppBroadcastReceiver because we instantiate this as a totally
1495      * separate BroadcastReceiver instance, since we need to manually
1496      * adjust its IntentFilter's priority (to make sure we get these
1497      * intents *before* the media player.)
1498      */
1499     private class MediaButtonBroadcastReceiver extends BroadcastReceiver {
1500         @Override
onReceive(Context context, Intent intent)1501         public void onReceive(Context context, Intent intent) {
1502             KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
1503             if (VDBG) Log.d(LOG_TAG,
1504                            "MediaButtonBroadcastReceiver.onReceive()...  event = " + event);
1505             if ((event != null)
1506                 && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
1507                 if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: HEADSETHOOK");
1508                 boolean consumed = PhoneUtils.handleHeadsetHook(phone, event);
1509                 if (VDBG) Log.d(LOG_TAG, "==> handleHeadsetHook(): consumed = " + consumed);
1510                 if (consumed) {
1511                     // If a headset is attached and the press is consumed, also update
1512                     // any UI items (such as an InCallScreen mute button) that may need to
1513                     // be updated if their state changed.
1514                     if (isShowingCallScreen()) {
1515                         updateInCallScreenTouchUi();
1516                     }
1517                     abortBroadcast();
1518                 }
1519             } else {
1520                 if (mCM.getState() != Phone.State.IDLE) {
1521                     // If the phone is anything other than completely idle,
1522                     // then we consume and ignore any media key events,
1523                     // Otherwise it is too easy to accidentally start
1524                     // playing music while a phone call is in progress.
1525                     if (VDBG) Log.d(LOG_TAG, "MediaButtonBroadcastReceiver: consumed");
1526                     abortBroadcast();
1527                 }
1528             }
1529         }
1530     }
1531 
handleServiceStateChanged(Intent intent)1532     private void handleServiceStateChanged(Intent intent) {
1533         /**
1534          * This used to handle updating EriTextWidgetProvider this routine
1535          * and and listening for ACTION_SERVICE_STATE_CHANGED intents could
1536          * be removed. But leaving just in case it might be needed in the near
1537          * future.
1538          */
1539 
1540         // If service just returned, start sending out the queued messages
1541         ServiceState ss = ServiceState.newFromBundle(intent.getExtras());
1542 
1543         boolean hasService = true;
1544         boolean isCdma = false;
1545         String eriText = "";
1546 
1547         if (ss != null) {
1548             int state = ss.getState();
1549             NotificationMgr.getDefault().updateNetworkSelection(state);
1550             switch (state) {
1551                 case ServiceState.STATE_OUT_OF_SERVICE:
1552                 case ServiceState.STATE_POWER_OFF:
1553                     hasService = false;
1554                     break;
1555             }
1556         } else {
1557             hasService = false;
1558         }
1559     }
1560 
isOtaCallInActiveState()1561     public boolean isOtaCallInActiveState() {
1562         boolean otaCallActive = false;
1563         if (mInCallScreen != null) {
1564             otaCallActive = mInCallScreen.isOtaCallInActiveState();
1565         }
1566         if (VDBG) Log.d(LOG_TAG, "- isOtaCallInActiveState " + otaCallActive);
1567         return otaCallActive;
1568     }
1569 
isOtaCallInEndState()1570     public boolean isOtaCallInEndState() {
1571         boolean otaCallEnded = false;
1572         if (mInCallScreen != null) {
1573             otaCallEnded = mInCallScreen.isOtaCallInEndState();
1574         }
1575         if (VDBG) Log.d(LOG_TAG, "- isOtaCallInEndState " + otaCallEnded);
1576         return otaCallEnded;
1577     }
1578 
1579     // it is safe to call clearOtaState() even if the InCallScreen isn't active
clearOtaState()1580     public void clearOtaState() {
1581         if (DBG) Log.d(LOG_TAG, "- clearOtaState ...");
1582         if ((mInCallScreen != null)
1583                 && (mInCallScreen.otaUtils != null)) {
1584             mInCallScreen.otaUtils.cleanOtaScreen(true);
1585             if (DBG) Log.d(LOG_TAG, "  - clearOtaState clears OTA screen");
1586         }
1587     }
1588 
1589     // it is safe to call dismissOtaDialogs() even if the InCallScreen isn't active
dismissOtaDialogs()1590     public void dismissOtaDialogs() {
1591         if (DBG) Log.d(LOG_TAG, "- dismissOtaDialogs ...");
1592         if ((mInCallScreen != null)
1593                 && (mInCallScreen.otaUtils != null)) {
1594             mInCallScreen.otaUtils.dismissAllOtaDialogs();
1595             if (DBG) Log.d(LOG_TAG, "  - dismissOtaDialogs clears OTA dialogs");
1596         }
1597     }
1598 
1599     // it is safe to call clearInCallScreenMode() even if the InCallScreen isn't active
clearInCallScreenMode()1600     public void clearInCallScreenMode() {
1601         if (DBG) Log.d(LOG_TAG, "- clearInCallScreenMode ...");
1602         if (mInCallScreen != null) {
1603             mInCallScreen.resetInCallScreenMode();
1604         }
1605     }
1606 
1607     // Update InCallScreen's touch UI. It is safe to call even if InCallScreen isn't active
updateInCallScreenTouchUi()1608     public void updateInCallScreenTouchUi() {
1609         if (DBG) Log.d(LOG_TAG, "- updateInCallScreenTouchUi ...");
1610         if (mInCallScreen != null) {
1611             mInCallScreen.requestUpdateTouchUi();
1612         }
1613     }
1614 
handleQueryTTYModeResponse(Message msg)1615     private void handleQueryTTYModeResponse(Message msg) {
1616         AsyncResult ar = (AsyncResult) msg.obj;
1617         if (ar.exception != null) {
1618             if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse: Error getting TTY state.");
1619         } else {
1620             if (DBG) Log.d(LOG_TAG,
1621                            "handleQueryTTYModeResponse: TTY enable state successfully queried.");
1622 
1623             int ttymode = ((int[]) ar.result)[0];
1624             if (DBG) Log.d(LOG_TAG, "handleQueryTTYModeResponse:ttymode=" + ttymode);
1625 
1626             Intent ttyModeChanged = new Intent(TtyIntent.TTY_ENABLED_CHANGE_ACTION);
1627             ttyModeChanged.putExtra("ttyEnabled", ttymode != Phone.TTY_MODE_OFF);
1628             sendBroadcast(ttyModeChanged);
1629 
1630             String audioTtyMode;
1631             switch (ttymode) {
1632             case Phone.TTY_MODE_FULL:
1633                 audioTtyMode = "tty_full";
1634                 break;
1635             case Phone.TTY_MODE_VCO:
1636                 audioTtyMode = "tty_vco";
1637                 break;
1638             case Phone.TTY_MODE_HCO:
1639                 audioTtyMode = "tty_hco";
1640                 break;
1641             case Phone.TTY_MODE_OFF:
1642             default:
1643                 audioTtyMode = "tty_off";
1644                 break;
1645             }
1646             AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
1647             audioManager.setParameters("tty_mode="+audioTtyMode);
1648         }
1649     }
1650 
handleSetTTYModeResponse(Message msg)1651     private void handleSetTTYModeResponse(Message msg) {
1652         AsyncResult ar = (AsyncResult) msg.obj;
1653 
1654         if (ar.exception != null) {
1655             if (DBG) Log.d (LOG_TAG,
1656                     "handleSetTTYModeResponse: Error setting TTY mode, ar.exception"
1657                     + ar.exception);
1658         }
1659         phone.queryTTYMode(mHandler.obtainMessage(EVENT_TTY_MODE_GET));
1660     }
1661 
clearUserActivityTimeout()1662     /* package */ void clearUserActivityTimeout() {
1663         try {
1664             mPowerManagerService.clearUserActivityTimeout(SystemClock.uptimeMillis(),
1665                     10*1000 /* 10 sec */);
1666         } catch (RemoteException ex) {
1667             // System process is dead.
1668         }
1669     }
1670 }
1671