CallNotifier.java revision 0b35f04f2e58095d7292468c746d992913965eea
17d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/* 27d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Copyright (C) 2006 The Android Open Source Project 37d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 47d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 57d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * you may not use this file except in compliance with the License. 67d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * You may obtain a copy of the License at 77d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 87d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 97d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Unless required by applicable law or agreed to in writing, software 117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * See the License for the specific language governing permissions and 147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * limitations under the License. 157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpackage com.android.phone; 187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Call; 207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.CallManager; 217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.CallerInfo; 227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.CallerInfoAsyncQuery; 237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Connection; 247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.Phone; 257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneConstants; 267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.PhoneBase; 277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.TelephonyCapabilities; 287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.CdmaCallWaitingNotification; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.SignalToneUtil; 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.ActivityManagerNative; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothAdapter; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothHeadset; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothProfile; 377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.media.AudioManager; 397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.media.ToneGenerator; 407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.net.Uri; 417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.AsyncResult; 427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Handler; 437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Message; 447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.SystemProperties; 457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.SystemVibrator; 467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.os.Vibrator; 477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.provider.CallLog.Calls; 487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.provider.Settings; 490b35f04f2e58095d7292468c746d992913965eeaAnders Kristensenimport android.telephony.DisconnectCause; 507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.PhoneNumberUtils; 517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.PhoneStateListener; 527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.telephony.TelephonyManager; 537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.EventLog; 547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.util.Log; 557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon/** 577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Phone app module that listens for phone state changes and various other 587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * events from the telephony layer, and triggers any resulting UI behavior 597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (like starting the Ringer and Incoming Call UI, playing in-call tones, 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * updating notifications, writing call log entries, etc.) 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonpublic class CallNotifier extends Handler 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon implements CallerInfoAsyncQuery.OnQueryCompleteListener { 647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "CallNotifier"; 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1); 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2); 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Maximum time we allow the CallerInfo query to run, 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // before giving up and falling back to the default ringtone. 717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int RINGTONE_QUERY_WAIT_TIME = 500; // msec 727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Timers related to CDMA Call Waiting 747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 1) For displaying Caller Info 757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 2) For disabling "Add Call" menu option once User selects Ignore or CW Timeout occures 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLWAITING_CALLERINFO_DISPLAY_TIME = 20000; // msec 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLWAITING_ADDCALL_DISABLE_TIME = 30000; // msec 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Time to display the DisplayInfo Record sent by CDMA network 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int DISPLAYINFO_NOTIFICATION_TIME = 2000; // msec 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static CallNotifier sInstance; 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Boolean to keep track of whether or not a CDMA Call Waiting call timed out. 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is CDMA-specific, because with CDMA we *don't* get explicit 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // notification from the telephony layer that a call-waiting call has 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // stopped ringing. Instead, when a call-waiting call first comes in we 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // start a 20-second timer (see CALLWAITING_CALLERINFO_DISPLAY_DONE), and 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if the timer expires we clean up the call and treat it as a missed call. 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If this field is true, that means that the current Call Waiting call 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "timed out" and should be logged in Call Log as a missed call. If it's 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // false when we reach onCdmaCallWaitingReject(), we can assume the user 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // explicitly rejected this call-waiting call. 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This field is reset to false any time a call-waiting call first comes 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // in, and after cleaning up a missed call-waiting call. It's only ever 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // set to true when the CALLWAITING_CALLERINFO_DISPLAY_DONE timer fires. 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: do we really need a member variable for this? Don't we always 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // know at the moment we call onCdmaCallWaitingReject() whether this is an 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // explicit rejection or not? 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (Specifically: when we call onCdmaCallWaitingReject() from 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PhoneUtils.hangupRingingCall() that means the user deliberately rejected 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the call, and if we call onCdmaCallWaitingReject() because of a 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CALLWAITING_CALLERINFO_DISPLAY_DONE event that means that it timed 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // out...) 1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mCallWaitingTimeOut = false; 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // values used to track the query state 1137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLERINFO_QUERY_READY = 0; 1147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLERINFO_QUERYING = -1; 1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the state of the CallerInfo Query. 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mCallerInfoQueryState; 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // object used to synchronize access to mCallerInfoQueryState 1207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object mCallerInfoQueryStateGuard = new Object(); 1217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Event used to indicate a query timeout. 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT = 100; 1247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Events generated internally: 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int PHONE_MWI_CHANGED = 21; 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLWAITING_CALLERINFO_DISPLAY_DONE = 22; 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLWAITING_ADDCALL_DISABLE_TIMEOUT = 23; 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int DISPLAYINFO_NOTIFICATION_DONE = 24; 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CDMA_CALL_WAITING_REJECT = 26; 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int UPDATE_IN_CALL_NOTIFICATION = 27; 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Emergency call related defines: 1347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EMERGENCY_TONE_OFF = 0; 1357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EMERGENCY_TONE_ALERT = 1; 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int EMERGENCY_TONE_VIBRATE = 2; 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private PhoneGlobals mApplication; 1397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private CallManager mCM; 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Ringer mRinger; 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private BluetoothHeadset mBluetoothHeadset; 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private CallLogger mCallLogger; 143a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon private CallModeler mCallModeler; 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mSilentRingerRequested; 1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ToneGenerator instance for playing SignalInfo tones 1477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private ToneGenerator mSignalInfoToneGenerator; 1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone volume relative to other sounds in the stream SignalInfo 1507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int TONE_RELATIVE_VOLUME_SIGNALINFO = 80; 1517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Call.State mPreviousCdmaCallState; 1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mVoicePrivacyState = false; 1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mIsCdmaRedialCall = false; 1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Emergency call tone and vibrate: 1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mIsEmergencyToneOn; 1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mCurrentEmergencyToneState = EMERGENCY_TONE_OFF; 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private EmergencyTonePlayerVibrator mEmergencyTonePlayerVibrator; 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Ringback tone player 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private InCallTonePlayer mInCallRingbackTonePlayer; 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Call waiting tone player 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private InCallTonePlayer mCallWaitingTonePlayer; 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Cached AudioManager 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private AudioManager mAudioManager; 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17027a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon private final BluetoothManager mBluetoothManager; 17127a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton CallNotifier instance. 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, Ringer ringer, 17727a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon CallLogger callLogger, CallStateMonitor callStateMonitor, 178a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon BluetoothManager bluetoothManager, CallModeler callModeler) { 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (CallNotifier.class) { 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 18127a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon sInstance = new CallNotifier(app, phone, ringer, callLogger, callStateMonitor, 182a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon bluetoothManager, callModeler); 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private CallNotifier(PhoneGlobals app, Phone phone, Ringer ringer, CallLogger callLogger, 192a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager, 193a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon CallModeler callModeler) { 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication = app; 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = app.mCM; 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallLogger = callLogger; 19727a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon mBluetoothManager = bluetoothManager; 198a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon mCallModeler = callModeler; 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE); 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callStateMonitor.addListener(this); 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon createSignalInfoToneGenerator(); 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger = ringer; 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (adapter != null) { 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon adapter.getProfileProxy(mApplication.getApplicationContext(), 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothProfileServiceListener, 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon BluetoothProfile.HEADSET); 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon TelephonyManager telephonyManager = (TelephonyManager)app.getSystemService( 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Context.TELEPHONY_SERVICE); 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon telephonyManager.listen(mPhoneStateListener, 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR); 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void createSignalInfoToneGenerator() { 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instantiate the ToneGenerator for SignalInfo and CallWaiting 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: We probably don't need the mSignalInfoToneGenerator instance 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // around forever. Need to change it so as to create a ToneGenerator instance only 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when a tone is being played and releases it after its done playing. 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mSignalInfoToneGenerator == null) { 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon TONE_RELATIVE_VOLUME_SIGNALINFO); 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "CallNotifier: mSignalInfoToneGenerator created when toneplay"); 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "mSignalInfoToneGenerator: " + e); 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator = null; 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "mSignalInfoToneGenerator created already, hence skipping"); 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION: 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("RINGING... (new)"); 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onNewRingingConnection((AsyncResult) msg.obj); 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSilentRingerRequested = false; 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_INCOMING_RING: 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // repeat the ring when requested by the RIL, and when the user has NOT 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // specifically requested silence. 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (msg.obj != null && ((AsyncResult) msg.obj).result != null) { 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneBase pb = (PhoneBase)((AsyncResult)msg.obj).result; 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((pb.getState() == PhoneConstants.State.RINGING) 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mSilentRingerRequested == false)) { 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("RINGING... (PHONE_INCOMING_RING event)"); 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.ring(); 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("RING before NEW_RING, skipping"); 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_CHANGED: 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onPhoneStateChanged((AsyncResult) msg.obj); 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_DISCONNECT: 2717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("DISCONNECT"); 2727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onDisconnect((AsyncResult) msg.obj); 2737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED: 2767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onUnknownConnectionAppeared((AsyncResult) msg.obj); 2777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT: 280fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen onCustomRingtoneQueryTimeout((Connection) msg.obj); 2817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case PHONE_MWI_CHANGED: 2847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onMwiChanged(mApplication.phone.getMessageWaitingIndicator()); 2857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_CDMA_CALL_WAITING: 2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received PHONE_CDMA_CALL_WAITING event"); 2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCdmaCallWaiting((AsyncResult) msg.obj); 2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CDMA_CALL_WAITING_REJECT: 2937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Received CDMA_CALL_WAITING_REJECT event"); 2947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCdmaCallWaitingReject(); 2957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CALLWAITING_CALLERINFO_DISPLAY_DONE: 2987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Received CALLWAITING_CALLERINFO_DISPLAY_DONE event"); 2997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTimeOut = true; 3007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCdmaCallWaitingReject(); 3017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CALLWAITING_ADDCALL_DISABLE_TIMEOUT: 3047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received CALLWAITING_ADDCALL_DISABLE_TIMEOUT event ..."); 3057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Set the mAddCallMenuStateAfterCW state to true 3067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true); 3077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_DISPLAYINFO: 3107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received PHONE_STATE_DISPLAYINFO event"); 3117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onDisplayInfo((AsyncResult) msg.obj); 3127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_SIGNALINFO: 3157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received PHONE_STATE_SIGNALINFO event"); 3167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onSignalInfo((AsyncResult) msg.obj); 3177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case DISPLAYINFO_NOTIFICATION_DONE: 3207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received Display Info notification done event ..."); 3217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfo.dismissDisplayInfoRecord(); 3227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.EVENT_OTA_PROVISION_CHANGE: 3257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("EVENT_OTA_PROVISION_CHANGE..."); 3267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.handleOtaspEvent(msg); 3277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_ENHANCED_VP_ON: 3307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("PHONE_ENHANCED_VP_ON..."); 3317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!mVoicePrivacyState) { 3327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 3337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 3347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = true; 3357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_ENHANCED_VP_OFF: 3397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("PHONE_ENHANCED_VP_OFF..."); 3407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mVoicePrivacyState) { 3417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 3427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 3437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = false; 3447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_RINGBACK_TONE: 3487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onRingbackTone((AsyncResult) msg.obj); 3497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_RESEND_MUTE: 3527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onResendMute(); 3537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 3547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 3567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // super.handleMessage(msg); 3577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 3617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 3627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onMessageWaitingIndicatorChanged(boolean mwi) { 3637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onMwiChanged(mwi); 3647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 3677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onCallForwardingIndicatorChanged(boolean cfi) { 3687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCfiChanged(cfi); 3697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 3717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 3737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Handles a "new ringing connection" event from the telephony layer. 3747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 3757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onNewRingingConnection(AsyncResult r) { 3767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = (Connection) r.result; 3777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("onNewRingingConnection(): state = " + mCM.getState() + ", conn = { " + c + " }"); 3787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call ringing = c.getCall(); 3797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone phone = ringing.getPhone(); 3807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Check for a few cases where we totally ignore incoming calls. 3827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ignoreAllIncomingCalls(phone)) { 3837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Immediately reject the call, without even indicating to the user 3847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // that an incoming call occurred. (This will generally send the 3857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // caller straight to voicemail, just as if we *had* shown the 3867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // incoming-call UI and the user had declined the call.) 3877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.hangupRingingCall(ringing); 3887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 3897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!c.isRinging()) { 3927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "CallNotifier.onNewRingingConnection(): connection not ringing!"); 3937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is a very strange case: an incoming call that stopped 3947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringing almost instantly after the onNewRingingConnection() 3957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event. There's nothing we can do here, so just bail out 3967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // without doing anything. (But presumably we'll log it in 3977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the call log when the disconnect event comes in...) 3987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 3997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signalInfo tone being played on receiving a Call 4027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 4037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call.State state = c.getState(); 4057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // State will be either INCOMING or WAITING. 4067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- connection is ringing! state = " + state); 4077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) PhoneUtils.dumpCallState(mPhone); 4087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No need to do any service state checks here (like for 4107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "emergency mode"), since in those states the SIM won't let 4117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // us get incoming connections in the first place. 4127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: Consider sending out a serialized broadcast Intent here 4147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (maybe "ACTION_NEW_INCOMING_CALL"), *before* starting the 4157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringer and going to the in-call UI. The intent should contain 4167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the caller-id info for the current connection, and say whether 4177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // it would be a "call waiting" call or a regular ringing call. 4187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If anybody consumed the broadcast, we'd bail out without 4197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringing or bringing up the in-call UI. 4207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 4217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This would give 3rd party apps a chance to listen for (and 4227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // intercept) new ringing connections. An app could reject the 4237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // incoming call by consuming the broadcast and doing nothing, or 4247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // it could "pick up" the call (without any action by the user!) 4257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // via some future TelephonyManager API. 4267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 4277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // See bug 1312336 for more details. 4287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We'd need to protect this with a new "intercept incoming calls" 4297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // system permission. 4307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Obtain a partial wake lock to make sure the CPU doesn't go to 4327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // sleep before we finish bringing up the InCallScreen. 4337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (This will be upgraded soon to a full wake lock; see 4347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // showIncomingCall().) 4357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("Holding wake lock on new incoming connection."); 4367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.requestWakeState(PhoneGlobals.WakeState.PARTIAL); 4377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // - don't ring for call waiting connections 4397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // - do this before showing the incoming call panel 440b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen startIncomingCallQuery(c); 441b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen 442312b9c9112948c8ca7f74ea91b5e2585a66482c9Chiao Cheng 4437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Note we *don't* post a status bar notification here, since 4457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we're not necessarily ready to actually show the incoming call 4467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to the user. (For calls in the INCOMING state, at least, we 4477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // still need to run a caller-id query, and we may not even ring 4487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // at all if the "send directly to voicemail" flag is set.) 4497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 4507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instead, we update the notification (and potentially launch the 4517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // InCallScreen) from the showIncomingCall() method, which runs 4527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when the caller-id query completes or times out. 4537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- onNewRingingConnection() done."); 4557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 4587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Determines whether or not we're allowed to present incoming calls to the 4597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * user, based on the capabilities and/or current state of the device. 4607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 4617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If this method returns true, that means we should immediately reject the 4627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * current incoming call, without even indicating to the user that an 4637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * incoming call occurred. 4647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 4657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (We only reject incoming calls in a few cases, like during an OTASP call 4667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * when we can't interrupt the user, or if the device hasn't completed the 4677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * SetupWizard yet. We also don't allow incoming calls on non-voice-capable 4687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * devices. But note that we *always* allow incoming calls while in ECM.) 4697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 4707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if we're *not* allowed to present an incoming call to 4717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the user. 4727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean ignoreAllIncomingCalls(Phone phone) { 4747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored on non-voice-capable devices. 4757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 4767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ...but still log a warning, since we shouldn't have gotten this 4777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event in the first place! (Incoming calls *should* be blocked at 4787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the telephony layer on non-voice-capable capable devices.) 4797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onNewRingingConnection() on non-voice-capable device! Ignoring..."); 4807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 4817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // In ECM (emergency callback mode), we ALWAYS allow incoming calls 4847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to get through to the user. (Note that ECM is applicable only to 4857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // voice-capable CDMA devices). 4867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (PhoneUtils.isPhoneInEcm(phone)) { 4877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Incoming call while in ECM: always allow..."); 4887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 4897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored if the device isn't provisioned yet. 4927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean provisioned = Settings.Global.getInt(mApplication.getContentResolver(), 4937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Settings.Global.DEVICE_PROVISIONED, 0) != 0; 4947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!provisioned) { 4957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Ignoring incoming call: not provisioned"); 4967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 4977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored if an OTASP call is active. 5007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TelephonyCapabilities.supportsOtasp(phone)) { 5017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean activateState = (mApplication.cdmaOtaScreenState.otaScreenState 5027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION); 5037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean dialogState = (mApplication.cdmaOtaScreenState.otaScreenState 5047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG); 5057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean spcState = mApplication.cdmaOtaProvisionData.inOtaSpcState; 5067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (spcState) { 5087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Ignoring incoming call: OTA call is active"); 5097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 5107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (activateState || dialogState) { 5117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We *are* allowed to receive incoming calls at this point. 5127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // But clear out any residual OTASP UI first. 5137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: It's an MVC violation to twiddle the OTA UI state here; 5147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we should instead provide a higher-level API via OtaUtils. 5157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (dialogState) mApplication.dismissOtaDialogs(); 5167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.clearOtaState(); 5177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 5187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Normal case: allow this call to be presented to the user. 5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 5267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper method to manage the start of incoming call queries 5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 5287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void startIncomingCallQuery(Connection c) { 5297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: cache the custom ringer object so that subsequent 5307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // calls will not need to do this query work. We can keep 5317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the MRU ringtones in memory. We'll still need to hit 5327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the database to get the callerinfo to act as a key, 5337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // but at least we can save the time required for the 5347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Media player setup. The only issue with this is that 5357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we may need to keep an eye on the resources the Media 5367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // player uses to keep these ringtones around. 5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // make sure we're in a state where we can be ready to 5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // query a ringtone uri. 5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean shouldStartQuery = false; 5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallerInfoQueryStateGuard) { 5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCallerInfoQueryState == CALLERINFO_QUERY_READY) { 5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallerInfoQueryState = CALLERINFO_QUERYING; 5447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon shouldStartQuery = true; 5457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (shouldStartQuery) { 5487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Reset the ringtone to the default first. 5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.setCustomRingtoneUri(Settings.System.DEFAULT_RINGTONE_URI); 5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // query the callerinfo to try to get the ringer. 5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.CallerInfoToken cit = PhoneUtils.startGetCallerInfo( 553fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen mApplication, c, this, c); 5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if this has already been queried then just ring, otherwise 5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we wait for the alloted time before ringing. 5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (cit.isFinal) { 5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- CallerInfo already up to date, using available data"); 559fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen onQueryComplete(0, c, cit.currentInfo); 5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- Starting query, posting timeout message."); 5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Phone number (via getAddress()) is stored in the message to remember which 5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // number is actually used for the look up. 5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendMessageDelayed( 566fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen Message.obtain(this, RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT, c), 5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon RINGTONE_QUERY_WAIT_TIME); 5687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The call to showIncomingCall() will happen after the 5707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // queries are complete (or time out). 5717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This should never happen; its the case where an incoming call 5737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // arrives at the same time that the query is still being run, 5747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and before the timeout window has closed. 5757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon EventLog.writeEvent(EventLogTags.PHONE_UI_MULTIPLE_QUERY); 5767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 577b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen ringAndNotifyOfIncomingCall(c); 5787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 5827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Performs the final steps of the onNewRingingConnection sequence: 5837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * starts the ringer, and brings up the "incoming call" UI. 5847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 5857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Normally, this is called when the CallerInfo query completes (see 5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * onQueryComplete()). In this case, onQueryComplete() has already 5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * configured the Ringer object to use the custom ringtone (if there 5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * is one) for this caller. So we just tell the Ringer to start, and 5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * proceed to the InCallScreen. 5907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * But this method can *also* be called if the 5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * RINGTONE_QUERY_WAIT_TIME timeout expires, which means that the 5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * CallerInfo query is taking too long. In that case, we log a 5947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * warning but otherwise we behave the same as in the normal case. 5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (We still tell the Ringer to start, but it's going to use the 5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * default ringtone.) 5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 598fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen private void onCustomRingQueryComplete(Connection c) { 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean isQueryExecutionTimeExpired = false; 6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallerInfoQueryStateGuard) { 6017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCallerInfoQueryState == CALLERINFO_QUERYING) { 6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallerInfoQueryState = CALLERINFO_QUERY_READY; 6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon isQueryExecutionTimeExpired = true; 6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isQueryExecutionTimeExpired) { 6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // There may be a problem with the query here, since the 6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // default ringtone is playing instead of the custom one. 6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "CallerInfo query took too long; falling back to default ringtone"); 6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon EventLog.writeEvent(EventLogTags.PHONE_UI_RINGER_QUERY_ELAPSED); 6117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Make sure we still have an incoming call! 6147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 6157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (It's possible for the incoming call to have been disconnected 6167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // while we were running the query. In that case we better not 6177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // start the ringer here, since there won't be any future 6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // DISCONNECT event to stop it!) 6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Note we don't have to worry about the incoming call going away 6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // *after* this check but before we call mRinger.ring() below, 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // since in that case we *will* still get a DISCONNECT message sent 6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to our handler. (And we will correctly stop the ringer when we 6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // process that event.) 6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getState() != PhoneConstants.State.RINGING) { 6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "onCustomRingQueryComplete: No incoming call! Bailing out..."); 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Don't start the ringer *or* bring up the "incoming call" UI. 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Just bail out. 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 632fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // If the ringing call still does not have any connection anymore, do not send the 633fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // notification to the CallModeler. 634fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen final Call ringingCall = mCM.getFirstActiveRingingCall(); 635fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen 636fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (ringingCall != null && ringingCall.getLatestConnection() == c) { 637b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen ringAndNotifyOfIncomingCall(c); 638fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onUnknownConnectionAppeared(AsyncResult r) { 6427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state == PhoneConstants.State.OFFHOOK) { 64554fdb5954e76522b6961b8fd607c2c8bc474d075Santos Cordon if (DBG) log("unknown connection appeared..."); 646312b9c9112948c8ca7f74ea91b5e2585a66482c9Chiao Cheng 64754fdb5954e76522b6961b8fd607c2c8bc474d075Santos Cordon onPhoneStateChanged(r); 6487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 651b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen /** 652b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen * Notifies the Call Modeler that there is a new ringing connection. 653b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen * If it is not a waiting call (there is no other active call in foreground), we will ring the 654b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen * ringtone. Otherwise we will play the call waiting tone instead. 655b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen * @param c The new ringing connection. 656b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen */ 657b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen private void ringAndNotifyOfIncomingCall(Connection c) { 658b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen if (PhoneUtils.isRealIncomingCall(c.getState())) { 659b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen mRinger.ring(); 660b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen } else { 661b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen if (VDBG) log("- starting call waiting tone..."); 662b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen if (mCallWaitingTonePlayer == null) { 663b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING); 664b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen mCallWaitingTonePlayer.start(); 665b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen } 666b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen } 667fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen mCallModeler.onNewRingingConnection(c); 668fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 669fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen 6707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Updates the phone UI in response to phone state changes. 6727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 6737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Watch out: certain state changes are actually handled by their own 6747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * specific methods: 6757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * - see onNewRingingConnection() for new incoming calls 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * - see onDisconnect() for calls being hung up or disconnected 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onPhoneStateChanged(AsyncResult r) { 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 6807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onPhoneStateChanged: state = " + state); 6817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Turn status bar notifications on or off depending upon the state 6837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // of the phone. Notification Alerts (audible or vibrating) should 6847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // be on if and only if the phone is IDLE. 6857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.statusBarHelper 6867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon .enableNotificationAlerts(state == PhoneConstants.State.IDLE); 6877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone fgPhone = mCM.getFgPhone(); 6897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((fgPhone.getForegroundCall().getState() == Call.State.ACTIVE) 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && ((mPreviousCdmaCallState == Call.State.DIALING) 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (mPreviousCdmaCallState == Call.State.ALERTING))) { 6937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mIsCdmaRedialCall) { 6947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_REDIAL; 6957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 6967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signal info tone when call moves to ACTIVE state 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPreviousCdmaCallState = fgPhone.getForegroundCall().getState(); 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Have the PhoneApp recompute its mShowBluetoothIndication 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // flag based on the (new) telephony state. 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // There's no need to force a UI update since we update the 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // in-call notification ourselves (below), and the InCallScreen 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // listens for phone state changes itself. 70891db67da326faa267df40550060a915abdba3eb1Christine Chen // TODO: Have BluetoothManager listen to CallModeler instead of relying on 70927a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon // CallNotifier 71027a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon mBluetoothManager.updateBluetoothIndication(); 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Update the phone state and other sensor/lock. 7147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.updatePhoneState(state); 7157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state == PhoneConstants.State.OFFHOOK) { 7177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // stop call waiting tone if needed when answering 7187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCallWaitingTonePlayer != null) { 7197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTonePlayer.stopTone(); 7207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTonePlayer = null; 7217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onPhoneStateChanged: OFF HOOK"); 7247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // make sure audio is in in-call mode now 7257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setAudioMode(mCM); 7267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Since we're now in-call, the Ringer should definitely *not* 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // be ringing any more. (This is just a sanity-check; we 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // already stopped the ringer explicitly back in 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // PhoneUtils.answerCall(), before the call to phone.acceptCall().) 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: Confirm that this call really *is* unnecessary, and if so, 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // remove it! 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopRing()... (OFFHOOK state)"); 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.stopRing(); 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = fgPhone.getForegroundCall().getLatestConnection(); 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((c != null) && (PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(), 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication))) { 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onPhoneStateChanged: it is an emergency call."); 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call.State callState = fgPhone.getForegroundCall().getState(); 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mEmergencyTonePlayerVibrator == null) { 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmergencyTonePlayerVibrator = new EmergencyTonePlayerVibrator(); 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (callState == Call.State.DIALING || callState == Call.State.ALERTING) { 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsEmergencyToneOn = Settings.Global.getInt( 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.getContentResolver(), 7507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Settings.Global.EMERGENCY_TONE, EMERGENCY_TONE_OFF); 7517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mIsEmergencyToneOn != EMERGENCY_TONE_OFF && 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCurrentEmergencyToneState == EMERGENCY_TONE_OFF) { 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mEmergencyTonePlayerVibrator != null) { 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmergencyTonePlayerVibrator.start(); 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (callState == Call.State.ACTIVE) { 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF) { 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mEmergencyTonePlayerVibrator != null) { 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmergencyTonePlayerVibrator.stop(); 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP)) { 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call.State callState = mCM.getActiveFgCallState(); 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!callState.isDialing()) { 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If call get activated or disconnected before the ringback 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // tone stops, we have to stop it to prevent disturbing. 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mInCallRingbackTonePlayer != null) { 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer.stopTone(); 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer = null; 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon void updateCallNotifierRegistrationsAfterRadioTechnologyChange() { 7827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange..."); 7837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Clear ringback tone player 7857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer = null; 7867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Clear call waiting tone player 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTonePlayer = null; 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instantiate mSignalInfoToneGenerator 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon createSignalInfoToneGenerator(); 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface. 7967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * refreshes the CallCard data when it called. If called with this 7977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * class itself, it is assumed that we have been waiting for the ringtone 7987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and direct to voicemail settings to update. 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onQueryComplete(int token, Object cookie, CallerInfo ci) { 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (cookie instanceof Long) { 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("CallerInfo query complete, posting missed call notification"); 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.notifyMissedCall(ci.name, ci.phoneNumber, 806daf4c1d42c8f10ce902cb536c875b074404b7e4cChristine Chen ci.numberPresentation, ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon, 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ((Long) cookie).longValue()); 808fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } else if (cookie instanceof Connection) { 809fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen final Connection c = (Connection) cookie; 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("CallerInfo query complete (for CallNotifier), " 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + "updating state for incoming call.."); 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // get rid of the timeout messages 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT); 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean isQueryExecutionTimeOK = false; 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (mCallerInfoQueryStateGuard) { 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCallerInfoQueryState == CALLERINFO_QUERYING) { 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallerInfoQueryState = CALLERINFO_QUERY_READY; 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon isQueryExecutionTimeOK = true; 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //if we're in the right state 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isQueryExecutionTimeOK) { 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // send directly to voicemail. 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ci.shouldSendToVoicemail) { 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("send to voicemail flag detected. hanging up."); 829fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen final Call ringingCall = mCM.getFirstActiveRingingCall(); 830fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (ringingCall != null && ringingCall.getLatestConnection() == c) { 831fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen PhoneUtils.hangupRingingCall(ringingCall); 832fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen return; 833fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // set the ringtone uri to prepare for the ring. 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ci.contactRingtoneUri != null) { 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("custom ringtone found, setting up ringer."); 839fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen Ringer r = mRinger; 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon r.setCustomRingtoneUri(ci.contactRingtoneUri); 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ring, and other post-ring actions. 843fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen onCustomRingQueryComplete(c); 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Called when asynchronous CallerInfo query is taking too long (more than 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * {@link #RINGTONE_QUERY_WAIT_TIME} msec), but we cannot wait any more. 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This looks up in-memory fallback cache and use it when available. If not, it just calls 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * {@link #onCustomRingQueryComplete()} with default ringtone ("Send to voicemail" flag will 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * be just ignored). 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @param number The phone number used for the async query. This method will take care of 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * formatting or normalization of the number. 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 859fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen private void onCustomRingtoneQueryTimeout(Connection c) { 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // First of all, this case itself should be rare enough, though we cannot avoid it in 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // some situations (e.g. IPC is slow due to system overload, database is in sync, etc.) 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "CallerInfo query took too long; look up local fallback cache."); 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This method is intentionally verbose for now to detect possible bad side-effect for it. 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: Remove the verbose log when it looks stable and reliable enough. 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 868fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (c != null) { 869fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen final CallerInfoCache.CacheEntry entry = 870fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen mApplication.callerInfoCache.getCacheEntry(c.getAddress()); 871fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (entry != null) { 872fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (entry.sendToVoicemail) { 873fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen log("send to voicemail flag detected (in fallback cache). hanging up."); 874fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (mCM.getFirstActiveRingingCall().getLatestConnection() == c) { 875fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall()); 876fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen return; 877fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 878fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 879fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen 880fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen if (entry.customRingtone != null) { 881fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen log("custom ringtone found (in fallback cache), setting up ringer: " 882fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen + entry.customRingtone); 883fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen this.mRinger.setCustomRingtoneUri(Uri.parse(entry.customRingtone)); 884fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } 885fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen } else { 886fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // In this case we call onCustomRingQueryComplete(), just 887fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // like if the query had completed normally. (But we're 888fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // going to get the default ringtone, since we never got 889fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen // the chance to call Ringer.setCustomRingtoneUri()). 890fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen log("Failed to find fallback cache. Use default ringer tone."); 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 894fb0cc2b8751bc3e680dcb0ad7d346b3c0cc4ef23Christine Chen onCustomRingQueryComplete(c); 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onDisconnect(AsyncResult r) { 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onDisconnect()... CallManager state: " + mCM.getState()); 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = false; 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = (Connection) r.result; 9027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 9030b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen log("onDisconnect: cause = " + DisconnectCause.toString(c.getDisconnectCause()) 9047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + ", incoming = " + c.isIncoming() 9057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + ", date = " + c.getCreateTime()); 9067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "onDisconnect: null connection"); 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int autoretrySetting = 0; 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) { 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon autoretrySetting = android.provider.Settings.Global.getInt(mApplication. 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon getContentResolver(),android.provider.Settings.Global.CALL_AUTO_RETRY, 0); 9147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signalInfo tone being played when a call gets ended 9177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 9187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) { 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Resetting the CdmaPhoneCallState members 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState(); 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Remove Call waiting timers 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT); 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop the ringer if it was ringing (for an incoming call that 9297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // either disconnected by itself, or was rejected by the user.) 9307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 9317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: We technically *shouldn't* stop the ringer if the 9327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // foreground or background call disconnects while an incoming call 9337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is still ringing, but that's a really rare corner case. 9347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // It's safest to just unconditionally stop the ringer here. 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CDMA: For Call collision cases i.e. when the user makes an out going call 9377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and at the same time receives an Incoming Call, the Incoming Call is given 9387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // higher preference. At this time framework sends a disconnect for the Out going 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call connection hence we should *not* be stopping the ringer being played for 9407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the Incoming Call 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call ringingCall = mCM.getFirstActiveRingingCall(); 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ringingCall.getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (PhoneUtils.isRealIncomingCall(ringingCall.getState())) { 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Also we need to take off the "In Call" icon from the Notification 9457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // area as the Out going Call never got connected 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("cancelCallInProgressNotifications()... (onDisconnect)"); 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.cancelCallInProgressNotifications(); 9487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopRing()... (onDisconnect)"); 9507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.stopRing(); 9517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { // GSM 9537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopRing()... (onDisconnect)"); 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.stopRing(); 9557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // stop call waiting tone if needed when disconnecting 9587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCallWaitingTonePlayer != null) { 9597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTonePlayer.stopTone(); 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTonePlayer = null; 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If this is the end of an OTASP call, pass it on to the PhoneApp. 9647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null && TelephonyCapabilities.supportsOtasp(c.getCall().getPhone())) { 9657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final String number = c.getAddress(); 9667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c.getCall().getPhone().isOtaSpNumber(number)) { 9677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onDisconnect: this was an OTASP call!"); 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.handleOtaspDisconnect(); 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Check for the various tones we might need to play (thru the 9737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // earpiece) after a call disconnects. 9747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_NONE; 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The "Busy" or "Congestion" tone is the highest priority: 9777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 9780b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen int cause = c.getDisconnectCause(); 9790b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen if (cause == DisconnectCause.BUSY) { 9807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play BUSY tone!"); 9817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_BUSY; 9820b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.CONGESTION) { 9837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play CONGESTION tone!"); 9847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_CONGESTION; 9850b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (((cause == DisconnectCause.NORMAL) 9860b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen || (cause == DisconnectCause.LOCAL)) 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mApplication.isOtaCallInActiveState())) { 9887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play OTA_CALL_END tone!"); 9897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_OTA_CALL_END; 9900b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.CDMA_REORDER) { 9917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play CDMA_REORDER tone!"); 9927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_REORDER; 9930b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.CDMA_INTERCEPT) { 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play CDMA_INTERCEPT tone!"); 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_INTERCEPT; 9960b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.CDMA_DROP) { 9977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play CDMA_DROP tone!"); 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_CDMA_DROP; 9990b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.OUT_OF_SERVICE) { 10007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play OUT OF SERVICE tone!"); 10017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE; 10020b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.UNOBTAINABLE_NUMBER) { 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- need to play TONE_UNOBTAINABLE_NUMBER tone!"); 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER; 10050b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen } else if (cause == DisconnectCause.ERROR_UNSPECIFIED) { 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- DisconnectCause is ERROR_UNSPECIFIED: play TONE_CALL_ENDED!"); 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; 10087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we don't need to play BUSY or CONGESTION, then play the 10127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "call ended" tone if this was a "regular disconnect" (i.e. a 10137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // normal call where one end or the other hung up) *and* this 10147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // disconnect event caused the phone to become idle. (In other 10157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // words, we *don't* play the sound if one call hangs up but 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // there's still an active call on the other line.) 10177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: We may eventually want to disable this via a preference. 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((toneToPlay == InCallTonePlayer.TONE_NONE) 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mCM.getState() == PhoneConstants.State.IDLE) 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (c != null)) { 10210b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen int cause = c.getDisconnectCause(); 10220b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen if ((cause == DisconnectCause.NORMAL) // remote hangup 10230b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen || (cause == DisconnectCause.LOCAL)) { // local hangup 10247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- need to play CALL_ENDED tone!"); 10257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 10277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // All phone calls are disconnected. 10317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getState() == PhoneConstants.State.IDLE) { 10327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Don't reset the audio mode or bluetooth/speakerphone state 10337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if we still need to let the user hear a tone through the earpiece. 10347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneToPlay == InCallTonePlayer.TONE_NONE) { 10357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon resetAudioStateAfterDisconnect(); 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.cancelCallInProgressNotifications(); 10397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 10427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallLogger.logCall(c); 10437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final String number = c.getAddress(); 10457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final Phone phone = c.getCall().getPhone(); 10467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean isEmergencyNumber = 10477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneNumberUtils.isLocalEmergencyNumber(number, mApplication); 10487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 10507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((isEmergencyNumber) 10517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF)) { 10527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mEmergencyTonePlayerVibrator != null) { 10537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmergencyTonePlayerVibrator.stop(); 10547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final long date = c.getCreateTime(); 10590b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen final int cause = c.getDisconnectCause(); 10607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean missedCall = c.isIncoming() && 10610b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen (cause == DisconnectCause.INCOMING_MISSED); 10627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (missedCall) { 10637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Show the "Missed call" notification. 10647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (Note we *don't* do this if this was an incoming call that 10657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the user deliberately rejected.) 10667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon showMissedCallNotification(c, date); 10677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Possibly play a "post-disconnect tone" thru the earpiece. 10707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We do this here, rather than from the InCallScreen 10717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // activity, since we need to do this even if you're not in 10727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the Phone UI at the moment the connection ends. 10737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneToPlay != InCallTonePlayer.TONE_NONE) { 10747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- starting post-disconnect tone (" + toneToPlay + ")..."); 10757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 10767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: alternatively, we could start an InCallTonePlayer 10787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // here with an "unlimited" tone length, 10797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and manually stop it later when this connection truly goes 10807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // away. (The real connection over the network was closed as soon 10817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // as we got the BUSY message. But our telephony layer keeps the 10827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // connection open for a few extra seconds so we can show the 10837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "busy" indication to the user. We could stop the busy tone 10847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when *that* connection's "disconnect" event comes in.) 10857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (((mPreviousCdmaCallState == Call.State.DIALING) 10887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (mPreviousCdmaCallState == Call.State.ALERTING)) 10897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (!isEmergencyNumber) 10900b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.INCOMING_MISSED ) 10910b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.NORMAL) 10920b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.LOCAL) 10930b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.INCOMING_REJECTED)) { 10947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!mIsCdmaRedialCall) { 10957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) { 10967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: (Moto): The contact reference data may need to be stored and use 10977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // here when redialing a call. For now, pass in NULL as the URI parameter. 1098ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon final int status = 1099ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon PhoneUtils.placeCall(mApplication, phone, number, null, false); 1100ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon if (status != PhoneUtils.CALL_STATUS_FAILED) { 1101ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon mIsCdmaRedialCall = true; 1102ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon } 11037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 11057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 11077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 11087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Resets the audio mode and speaker state when a call ends. 11157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void resetAudioStateAfterDisconnect() { 11177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("resetAudioStateAfterDisconnect()..."); 11187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mBluetoothHeadset != null) { 11207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset.disconnectAudio(); 11217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call turnOnSpeaker() with state=false and store=true even if speaker 11247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is already off to reset user requested speaker state. 11257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.turnOnSpeaker(mApplication, false, true); 11267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setAudioMode(mCM); 11287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onMwiChanged(boolean visible) { 11317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onMwiChanged(): " + visible); 11327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "Voicemail" is meaningless on non-voice-capable devices, 11347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // so ignore MWI events. 11357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 11367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ...but still log a warning, since we shouldn't have gotten this 11377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event in the first place! 11387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR events 11397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // *should* be blocked at the telephony layer on non-voice-capable 11407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // capable devices.) 11417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onMwiChanged() on non-voice-capable device! Ignoring..."); 11427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 11437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.updateMwi(visible); 11467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts a delayed PHONE_MWI_CHANGED event, to schedule a "retry" for a 11507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * failed NotificationMgr.updateMwi() call. 11517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void sendMwiChangedDelayed(long delayMillis) { 11537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message message = Message.obtain(this, PHONE_MWI_CHANGED); 11547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendMessageDelayed(message, delayMillis); 11557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onCfiChanged(boolean visible) { 11587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onCfiChanged(): " + visible); 11597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.updateCfi(visible); 11607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Indicates whether or not this ringer is ringing. 11647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean isRinging() { 11667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mRinger.isRinging(); 11677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Stops the current ring, and tells the notifier that future 11717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * ring requests should be ignored. 11727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon void silenceRinger() { 11747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSilentRingerRequested = true; 11757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopRing()... (silenceRinger)"); 11767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.stopRing(); 11777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 11807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Restarts the ringer after having previously silenced it. 11817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 11827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (This is a no-op if the ringer is actually still ringing, or if the 11837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * incoming ringing call no longer exists.) 11847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 11857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void restartRinger() { 11867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("restartRinger()..."); 11877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Already ringing or Silent requested; no need to restart. 11887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isRinging() || mSilentRingerRequested) return; 11897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final Call ringingCall = mCM.getFirstActiveRingingCall(); 11917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Don't check ringingCall.isRinging() here, since that'll be true 11927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // for the WAITING state also. We only allow the ringer for 11937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // regular INCOMING calls. 11947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- ringingCall state: " + ringingCall.getState()); 11957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ringingCall.getState() == Call.State.INCOMING) { 11967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mRinger.ring(); 11977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 11997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 12017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper class to play tones through the earpiece (or speaker / BT) 12027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * during a call, using the ToneGenerator. 12037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 12047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * To use, just instantiate a new InCallTonePlayer 12057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (passing in the TONE_* constant for the tone you want) 12067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and start() it. 12077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 12087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * When we're done playing the tone, if the phone is idle at that 12097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * point, we'll reset the audio routing and speaker state. 12107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (That means that for tones that get played *after* a call 12117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * disconnects, like "busy" or "congestion" or "call ended", you 12127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * should NOT call resetAudioStateAfterDisconnect() yourself. 12137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Instead, just start the InCallTonePlayer, which will automatically 12147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * defer the resetAudioStateAfterDisconnect() call until the tone 12157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * finishes playing.) 12167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 12177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private class InCallTonePlayer extends Thread { 12187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mToneId; 12197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mState; 12207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The possible tones we can play. 12217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_NONE = 0; 12227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CALL_WAITING = 1; 12237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_BUSY = 2; 12247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CONGESTION = 3; 12257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CALL_ENDED = 4; 12267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_VOICE_PRIVACY = 5; 12277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_REORDER = 6; 12287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_INTERCEPT = 7; 12297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CDMA_DROP = 8; 12307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_OUT_OF_SERVICE = 9; 12317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_REDIAL = 10; 12327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_OTA_CALL_END = 11; 12337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_RING_BACK = 12; 12347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_UNOBTAINABLE_NUMBER = 13; 12357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone volume relative to other sounds in the stream 12377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_EMERGENCY = 100; 12387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_HIPRI = 80; 12397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_LOPRI = 50; 12407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Buffer time (in msec) to add on to tone timeout value. 12427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Needed mainly when the timeout value for a tone is the 12437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // exact duration of the tone itself. 12447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_TIMEOUT_BUFFER = 20; 12457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone state 12477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_OFF = 0; 12487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_ON = 1; 12497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_STOPPED = 2; 12507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon InCallTonePlayer(int toneId) { 12527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon super(); 12537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneId = toneId; 12547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_OFF; 12557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 12587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 12597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("InCallTonePlayer.run(toneId = " + mToneId + ")..."); 12607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneType = 0; // passed to ToneGenerator.startTone() 12627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneVolume; // passed to the ToneGenerator constructor 12637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneLengthMillis; 12647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mCM.getFgPhone().getPhoneType(); 12657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (mToneId) { 12677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CALL_WAITING: 12687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 12697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 12707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Call waiting tone is stopped by stopTone() method 12717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; 12727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 12737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_BUSY: 12747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 12757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT; 12767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 12777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 1000; 12787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((phoneType == PhoneConstants.PHONE_TYPE_GSM) 12797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (phoneType == PhoneConstants.PHONE_TYPE_SIP)) { 12807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_BUSY; 12817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 12827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 12837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 12847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 12857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 12867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 12877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CONGESTION: 12887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_CONGESTION; 12897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 12907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 12917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 12927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 12937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CALL_ENDED: 12947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 12957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 12967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 200; 12977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 12987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_OTA_CALL_END: 12997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone == 13007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon OtaUtils.OTA_PLAY_SUCCESS_FAILURE_TONE_ON) { 13017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD; 13027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 750; 13047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 13057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 13067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 200; 13087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_VOICE_PRIVACY: 13117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE; 13127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 5000; 13147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_REORDER: 13167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_REORDER; 13177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 13197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_INTERCEPT: 13217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT; 13227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 13237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 500; 13247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CDMA_DROP: 13267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_OUT_OF_SERVICE: 13277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 13287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 13297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 375; 13307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_REDIAL: 13327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE; 13337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 13347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 5000; 13357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_RING_BACK: 13377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_RINGTONE; 13387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Call ring back tone is stopped by stopTone() method 13407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; 13417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_UNOBTAINABLE_NUMBER: 13437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_ERROR; 13447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 13457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 13467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 13477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 13487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalArgumentException("Bad toneId: " + mToneId); 13497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If the mToneGenerator creation fails, just continue without it. It is 13527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // a local audio signal, and is not as important. 13537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ToneGenerator toneGenerator; 13547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 13557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int stream; 13567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mBluetoothHeadset != null) { 13577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stream = mBluetoothHeadset.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO: 13587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AudioManager.STREAM_VOICE_CALL; 13597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 13607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stream = AudioManager.STREAM_VOICE_CALL; 13617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator = new ToneGenerator(stream, toneVolume); 13637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) log("- created toneGenerator: " + toneGenerator); 13647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 13657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, 13667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "InCallTonePlayer: Exception caught while creating ToneGenerator: " + e); 13677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator = null; 13687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Using the ToneGenerator (with the CALL_WAITING / BUSY / 13717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CONGESTION tones at least), the ToneGenerator itself knows 13727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the right pattern of tones to play; we do NOT need to 13737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // manually start/stop each individual tone, or manually 13747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // insert the correct delay between tones. (We just start it 13757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and let it run for however long we want the tone pattern to 13767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // continue.) 13777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 13787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: When we stop the ToneGenerator in the middle of a 13797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "tone pattern", it sounds bad if we cut if off while the 13807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // tone is actually playing. Consider adding API to the 13817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ToneGenerator to say "stop at the next silent part of the 13827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // pattern", or simply "play the pattern N times and then 13837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // stop." 13847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean needToStopTone = true; 13857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean okToPlayTone = false; 13867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 13877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneGenerator != null) { 13887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int ringerMode = mAudioManager.getRingerMode(); 13897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 13907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneType == ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD) { 13917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 13927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 13937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- InCallTonePlayer: start playing call tone=" + toneType); 13947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 13957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 13967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 13977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((toneType == ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT) || 13987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_REORDER) || 13997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ABBR_REORDER) || 14007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ABBR_INTERCEPT) || 14017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_CALLDROP_LITE)) { 14027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ringerMode != AudioManager.RINGER_MODE_SILENT) { 14037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("InCallTonePlayer:playing call fail tone:" + toneType); 14047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 14057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 14067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((toneType == ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE) || 14087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE)) { 14097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 14107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 14117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("InCallTonePlayer:playing tone for toneType=" + toneType); 14127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 14137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 14147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { // For the rest of the tones, always OK to play. 14167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 14177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { // Not "CDMA" 14197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 14207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (this) { 14237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (okToPlayTone && mState != TONE_STOPPED) { 14247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_ON; 14257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.startTone(toneType); 14267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 14277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(toneLengthMillis + TONE_TIMEOUT_BUFFER); 14287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 14297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, 14307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "InCallTonePlayer stopped: " + e); 14317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (needToStopTone) { 14337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.stopTone(); 14347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) log("- InCallTonePlayer: done playing."); 14377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.release(); 14387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_OFF; 14397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Finally, do the same cleanup we otherwise would have done 14437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // in onDisconnect(). 14447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 14457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (But watch out: do NOT do this if the phone is in use, 14467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // since some of our tones get played *during* a call (like 14477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CALL_WAITING) and we definitely *don't* 14487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // want to reset the audio mode / speaker / bluetooth after 14497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // playing those! 14507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This call is really here for use with tones that get played 14517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // *after* a call disconnects, like "busy" or "congestion" or 14527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "call ended", where the phone has already become idle but 14537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we need to defer the resetAudioStateAfterDisconnect() call 14547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // till the tone finishes playing.) 14557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getState() == PhoneConstants.State.IDLE) { 14567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon resetAudioStateAfterDisconnect(); 14577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void stopTone() { 14617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (this) { 14627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mState == TONE_ON) { 14637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon notify(); 14647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_STOPPED; 14667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Displays a notification when the phone receives a DisplayInfo record. 14727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onDisplayInfo(AsyncResult r) { 14747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Extract the DisplayInfo String from the message 14757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfoRec displayInfoRec = (CdmaDisplayInfoRec)(r.result); 14767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (displayInfoRec != null) { 14787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String displayInfo = displayInfoRec.alpha; 14797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onDisplayInfo: displayInfo=" + displayInfo); 14807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfo.displayInfoRecord(mApplication, displayInfo); 14817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // start a 2 second timer 14837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendEmptyMessageDelayed(DISPLAYINFO_NOTIFICATION_DONE, 14847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon DISPLAYINFO_NOTIFICATION_TIME); 14857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 14877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 14897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper class to play SignalInfo tones using the ToneGenerator. 14907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 14917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * To use, just instantiate a new SignalInfoTonePlayer 14927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (passing in the ToneID constant for the tone you want) 14937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and start() it. 14947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 14957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private class SignalInfoTonePlayer extends Thread { 14967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mToneId; 14977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 14987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon SignalInfoTonePlayer(int toneId) { 14997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon super(); 15007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneId = toneId; 15017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 15047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 15057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")..."); 15067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mSignalInfoToneGenerator != null) { 15087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //First stop any ongoing SignalInfo tone 15097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator.stopTone(); 15107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Start playing the new tone if its a valid tone 15127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator.startTone(mToneId); 15137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Plays a tone when the phone receives a SignalInfo record. 15197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onSignalInfo(AsyncResult r) { 15217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Signal Info are totally ignored on non-voice-capable devices. 15227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 15237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onSignalInfo() on non-voice-capable device! Ignoring..."); 15247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 15257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (PhoneUtils.isRealIncomingCall(mCM.getFirstActiveRingingCall().getState())) { 15287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do not start any new SignalInfo tone when Call state is INCOMING 15297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and stop any previous SignalInfo tone which is being played 15307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 15317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 15327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Extract the SignalInfo String from the message 15337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaSignalInfoRec signalInfoRec = (CdmaSignalInfoRec)(r.result); 15347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Only proceed if a Signal info is present. 15357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (signalInfoRec != null) { 15367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean isPresent = signalInfoRec.isPresent; 15377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onSignalInfo: isPresent=" + isPresent); 15387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isPresent) {// if tone is valid 15397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignalType = signalInfoRec.signalType; 15407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uAlertPitch = signalInfoRec.alertPitch; 15417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignal = signalInfoRec.signal; 15427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onSignalInfo: uSignalType=" + uSignalType + ", uAlertPitch=" + 15447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon uAlertPitch + ", uSignal=" + uSignal); 15457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Map the Signal to a ToneGenerator ToneID only if Signal info is present 15467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneID = SignalToneUtil.getAudioToneFromSignalInfo 15477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (uSignalType, uAlertPitch, uSignal); 15487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Create the SignalInfo tone player and pass the ToneID 15507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new SignalInfoTonePlayer(toneID).start(); 15517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Stops a SignalInfo tone in the following condition 15587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - On receiving a New Ringing Call 15597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 2 - On disconnecting a call 15607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3 - On answering a Call Waiting Call 15617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void stopSignalInfoTone() { 15637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopSignalInfoTone: Stopping SignalInfo tone player"); 15647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new SignalInfoTonePlayer(ToneGenerator.TONE_CDMA_SIGNAL_OFF).start(); 15657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 15667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 15687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Plays a Call waiting tone if it is present in the second incoming call. 15697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 15707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onCdmaCallWaiting(AsyncResult r) { 15717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Remove any previous Call waiting timers in the queue 15727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 15737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT); 15747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Set the Phone Call State to SINGLE_ACTIVE as there is only one connection 15767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // else we would not have received Call waiting 15777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.cdmaPhoneCallState.setCurrentCallState( 15787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE); 15797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Start timer for CW display 15817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTimeOut = false; 15827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendEmptyMessageDelayed(CALLWAITING_CALLERINFO_DISPLAY_DONE, 15837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CALLWAITING_CALLERINFO_DISPLAY_TIME); 15847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Set the mAddCallMenuStateAfterCW state to false 15867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(false); 15877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Start the timer for disabling "Add Call" menu option 15897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendEmptyMessageDelayed(CALLWAITING_ADDCALL_DISABLE_TIMEOUT, 15907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CALLWAITING_ADDCALL_DISABLE_TIME); 15917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 15927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Extract the Call waiting information 15937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaCallWaitingNotification infoCW = (CdmaCallWaitingNotification) r.result; 15947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int isPresent = infoCW.isPresent; 15957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onCdmaCallWaiting: isPresent=" + isPresent); 15967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isPresent == 1 ) {//'1' if tone is valid 15977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignalType = infoCW.signalType; 15987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uAlertPitch = infoCW.alertPitch; 15997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignal = infoCW.signal; 16007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onCdmaCallWaiting: uSignalType=" + uSignalType + ", uAlertPitch=" 16017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + uAlertPitch + ", uSignal=" + uSignal); 16027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Map the Signal to a ToneGenerator ToneID only if Signal info is present 16037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneID = 16047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon SignalToneUtil.getAudioToneFromSignalInfo(uSignalType, uAlertPitch, uSignal); 16057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Create the SignalInfo tone player and pass the ToneID 16077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new SignalInfoTonePlayer(toneID).start(); 16087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1609a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon 1610a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon mCallModeler.onCdmaCallWaiting(infoCW); 16117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts a event causing us to clean up after rejecting (or timing-out) a 16157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * CDMA call-waiting call. 16167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 16177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This method is safe to call from any thread. 16187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #onCdmaCallWaitingReject() 16197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void sendCdmaCallWaitingReject() { 16217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendEmptyMessage(CDMA_CALL_WAITING_REJECT); 16227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Performs Call logging based on Timeout or Ignore Call Waiting Call for CDMA, 16267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and finally calls Hangup on the Call Waiting connection. 16277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 16287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This method should be called only from the UI thread. 16297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @see #sendCdmaCallWaitingReject() 16307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onCdmaCallWaitingReject() { 16327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final Call ringingCall = mCM.getFirstActiveRingingCall(); 16337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Call waiting timeout scenario 16357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ringingCall.getState() == Call.State.WAITING) { 16367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Code for perform Call logging and missed call notification 16377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = ringingCall.getLatestConnection(); 16387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 16407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final int callLogType = mCallWaitingTimeOut ? 16417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Calls.MISSED_TYPE : Calls.INCOMING_TYPE; 16427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: This callLogType override is not ideal. Connection should be astracted away 16447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // at a telephony-phone layer that can understand and edit the callTypes within 16457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the abstraction for CDMA devices. 16467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallLogger.logCall(c, callLogType); 16477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final long date = c.getCreateTime(); 16497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (callLogType == Calls.MISSED_TYPE) { 16507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Add missed call notification 16517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon showMissedCallNotification(c, date); 16527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 16537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Remove Call waiting 20 second display timer in the queue 16547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 16557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Hangup the RingingCall connection for CW 16587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.hangup(c); 16597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Reset the mCallWaitingTimeOut boolean 16627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallWaitingTimeOut = false; 16637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1664a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon 1665a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon // Call modeler needs to know about this event regardless of the 1666a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon // state conditionals in the previous code. 1667a5d5db8bae082681b9d76bc3f0f7cd16e47908abSantos Cordon mCallModeler.onCdmaCallWaitingReject(); 16687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mPreviousCdmaCallState. 16727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ Call.State getPreviousCdmaCallState() { 16747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPreviousCdmaCallState; 16757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mVoicePrivacyState. 16797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ boolean getVoicePrivacyState() { 16817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mVoicePrivacyState; 16827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mIsCdmaRedialCall. 16867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ boolean getIsCdmaRedialCall() { 16887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mIsCdmaRedialCall; 16897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 16907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 16917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 16927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper function used to show a missed call notification. 16937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 16947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void showMissedCallNotification(Connection c, final long date) { 16957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.CallerInfoToken info = 16967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date)); 16977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (info != null) { 16987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // at this point, we've requested to start a query, but it makes no 16997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // sense to log this missed call until the query comes back. 17007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("showMissedCallNotification: Querying for CallerInfo on missed call..."); 17017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (info.isFinal) { 17027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // it seems that the query we have actually is up to date. 17037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // send the notification then. 17047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CallerInfo ci = info.currentInfo; 17057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Check number presentation value; if we have a non-allowed presentation, 17077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // then display an appropriate presentation string instead as the missed 17087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call. 17097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String name = ci.name; 17107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String number = ci.phoneNumber; 17117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ci.numberPresentation == PhoneConstants.PRESENTATION_RESTRICTED) { 17127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon name = mApplication.getString(R.string.private_num); 17137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (ci.numberPresentation != PhoneConstants.PRESENTATION_ALLOWED) { 17147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon name = mApplication.getString(R.string.unknown); 17157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 17167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon number = PhoneUtils.modifyForSpecialCnapCases(mApplication, 17177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ci, number, ci.numberPresentation); 17187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1719daf4c1d42c8f10ce902cb536c875b074404b7e4cChristine Chen mApplication.notificationMgr.notifyMissedCall(name, number, ci.numberPresentation, 17207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ci.phoneLabel, ci.cachedPhoto, ci.cachedPhotoIcon, date); 17217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 17237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // getCallerInfo() can return null in rare cases, like if we weren't 17247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // able to get a valid phone number out of the specified Connection. 17257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "showMissedCallNotification: got null CallerInfo for Connection " + c); 17267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 17307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Inner class to handle emergency call tone and vibrator 17317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private class EmergencyTonePlayerVibrator { 17337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final int EMG_VIBRATE_LENGTH = 1000; // ms. 17347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final int EMG_VIBRATE_PAUSE = 1000; // ms. 17357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private final long[] mVibratePattern = 17367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new long[] { EMG_VIBRATE_LENGTH, EMG_VIBRATE_PAUSE }; 17377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private ToneGenerator mToneGenerator; 17397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this vibrator 17407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // object will be isolated from others. 17417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Vibrator mEmgVibrator = new SystemVibrator(); 17427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mInCallVolume; 17437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 17457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * constructor 17467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public EmergencyTonePlayerVibrator() { 17487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 17517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Start the emergency tone or vibrator. 17527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void start() { 17547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("call startEmergencyToneOrVibrate."); 17557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int ringerMode = mAudioManager.getRingerMode(); 17567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mIsEmergencyToneOn == EMERGENCY_TONE_ALERT) && 17587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ringerMode == AudioManager.RINGER_MODE_NORMAL)) { 17597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("EmergencyTonePlayerVibrator.start(): emergency tone..."); 17607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneGenerator = new ToneGenerator (AudioManager.STREAM_VOICE_CALL, 17617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon InCallTonePlayer.TONE_RELATIVE_VOLUME_EMERGENCY); 17627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mToneGenerator != null) { 17637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 17647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 17657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 17667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 0); 17677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneGenerator.startTone(ToneGenerator.TONE_CDMA_EMERGENCY_RINGBACK); 17687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCurrentEmergencyToneState = EMERGENCY_TONE_ALERT; 17697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (mIsEmergencyToneOn == EMERGENCY_TONE_VIBRATE) { 17717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("EmergencyTonePlayerVibrator.start(): emergency vibrate..."); 17727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mEmgVibrator != null) { 17737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmgVibrator.vibrate(mVibratePattern, 0); 17747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCurrentEmergencyToneState = EMERGENCY_TONE_VIBRATE; 17757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 17807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If the emergency tone is active, stop the tone or vibrator accordingly. 17817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 17827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void stop() { 17837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("call stopEmergencyToneOrVibrate."); 17847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 17857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((mCurrentEmergencyToneState == EMERGENCY_TONE_ALERT) 17867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mToneGenerator != null)) { 17877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneGenerator.stopTone(); 17887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneGenerator.release(); 17897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 17907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallVolume, 17917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 0); 17927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((mCurrentEmergencyToneState == EMERGENCY_TONE_VIBRATE) 17937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mEmgVibrator != null)) { 17947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mEmgVibrator.cancel(); 17957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCurrentEmergencyToneState = EMERGENCY_TONE_OFF; 17977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 17997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 18017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new BluetoothProfile.ServiceListener() { 18027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onServiceConnected(int profile, BluetoothProfile proxy) { 18037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset = (BluetoothHeadset) proxy; 18047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset); 18057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onServiceDisconnected(int profile) { 18087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset = null; 18097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 18117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onRingbackTone(AsyncResult r) { 18137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean playTone = (Boolean)(r.result); 18147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (playTone == true) { 18167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Only play when foreground call is in DIALING or ALERTING. 18177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to prevent a late coming playtone after ALERTING. 18187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Don't play ringback tone if it is in play, otherwise it will cut 18197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the current tone and replay it 18207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getActiveFgCallState().isDialing() && 18217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer == null) { 18227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_RING_BACK); 18237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer.start(); 18247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 18267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mInCallRingbackTonePlayer != null) { 18277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer.stopTone(); 18287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mInCallRingbackTonePlayer = null; 18297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 18347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Toggle mute and unmute requests while keeping the same mute state 18357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 18367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onResendMute() { 18377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean muteState = PhoneUtils.getMute(); 18387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setMute(!muteState); 18397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setMute(muteState); 18407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 18427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void log(String msg) { 18437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, msg); 18447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 18457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 1846