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.CdmaInformationRecords.CdmaDisplayInfoRec; 297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec; 307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport com.android.internal.telephony.cdma.SignalToneUtil; 317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.app.ActivityManagerNative; 337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothAdapter; 347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothHeadset; 357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.bluetooth.BluetoothProfile; 367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordonimport android.content.Context; 376ee06d073a352f267008d913e50bd946707c5beaJohn Spurlockimport android.media.AudioAttributes; 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 595422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon * (like starting the Incoming Call UI, playing in-call tones, 607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * updating notifications, writing call log entries, etc.) 617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 625422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordonpublic class CallNotifier extends Handler { 637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final String LOG_TAG = "CallNotifier"; 647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean DBG = 657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1); 667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2); 677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Time to display the DisplayInfo Record sent by CDMA network 697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int DISPLAYINFO_NOTIFICATION_TIME = 2000; // msec 707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 716ee06d073a352f267008d913e50bd946707c5beaJohn Spurlock private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() 726ee06d073a352f267008d913e50bd946707c5beaJohn Spurlock .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 736ee06d073a352f267008d913e50bd946707c5beaJohn Spurlock .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) 746ee06d073a352f267008d913e50bd946707c5beaJohn Spurlock .build(); 756ee06d073a352f267008d913e50bd946707c5beaJohn Spurlock 767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** The singleton instance. */ 777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static CallNotifier sInstance; 787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // values used to track the query state 807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLERINFO_QUERY_READY = 0; 817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int CALLERINFO_QUERYING = -1; 827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the state of the CallerInfo Query. 847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mCallerInfoQueryState; 857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // object used to synchronize access to mCallerInfoQueryState 877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Object mCallerInfoQueryStateGuard = new Object(); 887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Events generated internally: 907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int PHONE_MWI_CHANGED = 21; 917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int DISPLAYINFO_NOTIFICATION_DONE = 24; 927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int UPDATE_IN_CALL_NOTIFICATION = 27; 937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private PhoneGlobals mApplication; 967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private CallManager mCM; 977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private BluetoothHeadset mBluetoothHeadset; 987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private CallLogger mCallLogger; 997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ToneGenerator instance for playing SignalInfo tones 1017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private ToneGenerator mSignalInfoToneGenerator; 1027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone volume relative to other sounds in the stream SignalInfo 1047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private static final int TONE_RELATIVE_VOLUME_SIGNALINFO = 80; 1057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private Call.State mPreviousCdmaCallState; 1077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mVoicePrivacyState = false; 1087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean mIsCdmaRedialCall = false; 1097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Cached AudioManager 1117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private AudioManager mAudioManager; 1127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 11327a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon private final BluetoothManager mBluetoothManager; 11427a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon 1157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 1167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Initialize the singleton CallNotifier instance. 1177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * This is only done once, at startup, from PhoneApp.onCreate(). 1187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 1195422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon /* package */ static CallNotifier init(PhoneGlobals app, Phone phone, 12027a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon CallLogger callLogger, CallStateMonitor callStateMonitor, 12123d9ed758fbe78e4afd4067e6845bcaf3387bca7Sailesh Nepal BluetoothManager bluetoothManager) { 1227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (CallNotifier.class) { 1237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (sInstance == null) { 1245422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon sInstance = new CallNotifier(app, phone, callLogger, callStateMonitor, 12523d9ed758fbe78e4afd4067e6845bcaf3387bca7Sailesh Nepal bluetoothManager); 1267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 1277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 1287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return sInstance; 1307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** Private constructor; @see init() */ 1345422a8deb513e4466ec6cc1e640895a6b536fee0Santos Cordon private CallNotifier(PhoneGlobals app, Phone phone, CallLogger callLogger, 13523d9ed758fbe78e4afd4067e6845bcaf3387bca7Sailesh Nepal CallStateMonitor callStateMonitor, BluetoothManager bluetoothManager) { 1367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication = app; 1377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCM = app.mCM; 1387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallLogger = callLogger; 13927a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon mBluetoothManager = bluetoothManager; 1407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE); 1427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon callStateMonitor.addListener(this); 1447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 1467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (adapter != null) { 1477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon adapter.getProfileProxy(mApplication.getApplicationContext(), 1487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothProfileServiceListener, 1497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon BluetoothProfile.HEADSET); 1507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon TelephonyManager telephonyManager = (TelephonyManager)app.getSystemService( 1537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Context.TELEPHONY_SERVICE); 1547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon telephonyManager.listen(mPhoneStateListener, 1557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR 1567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR); 1577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void createSignalInfoToneGenerator() { 1607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instantiate the ToneGenerator for SignalInfo and CallWaiting 1617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: We probably don't need the mSignalInfoToneGenerator instance 1627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // around forever. Need to change it so as to create a ToneGenerator instance only 1637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when a tone is being played and releases it after its done playing. 1647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mSignalInfoToneGenerator == null) { 1657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 1667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, 1677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon TONE_RELATIVE_VOLUME_SIGNALINFO); 1687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "CallNotifier: mSignalInfoToneGenerator created when toneplay"); 1697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 1707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + 1717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "mSignalInfoToneGenerator: " + e); 1727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator = null; 1737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 1757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, "mSignalInfoToneGenerator created already, hence skipping"); 1767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 1787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 1807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void handleMessage(Message msg) { 1817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (msg.what) { 1827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_NEW_RINGING_CONNECTION: 1837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("RINGING... (new)"); 1847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onNewRingingConnection((AsyncResult) msg.obj); 1857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_CHANGED: 1887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onPhoneStateChanged((AsyncResult) msg.obj); 1897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_DISCONNECT: 1927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("DISCONNECT"); 1937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onDisconnect((AsyncResult) msg.obj); 1947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 1967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_UNKNOWN_CONNECTION_APPEARED: 1977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onUnknownConnectionAppeared((AsyncResult) msg.obj); 1987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 1997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case PHONE_MWI_CHANGED: 2017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onMwiChanged(mApplication.phone.getMessageWaitingIndicator()); 2027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_DISPLAYINFO: 2057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received PHONE_STATE_DISPLAYINFO event"); 2067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onDisplayInfo((AsyncResult) msg.obj); 2077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_STATE_SIGNALINFO: 2107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received PHONE_STATE_SIGNALINFO event"); 2117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onSignalInfo((AsyncResult) msg.obj); 2127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case DISPLAYINFO_NOTIFICATION_DONE: 2157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Received Display Info notification done event ..."); 2167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfo.dismissDisplayInfoRecord(); 2177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.EVENT_OTA_PROVISION_CHANGE: 2207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("EVENT_OTA_PROVISION_CHANGE..."); 2217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.handleOtaspEvent(msg); 2227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_ENHANCED_VP_ON: 2257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("PHONE_ENHANCED_VP_ON..."); 2267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!mVoicePrivacyState) { 2277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 2287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 2297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = true; 2307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case CallStateMonitor.PHONE_ENHANCED_VP_OFF: 2347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("PHONE_ENHANCED_VP_OFF..."); 2357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mVoicePrivacyState) { 2367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 2377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 2387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = false; 2397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 2417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 2437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // super.handleMessage(msg); 2447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 2487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onMessageWaitingIndicatorChanged(boolean mwi) { 2507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onMwiChanged(mwi); 2517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 2547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onCallForwardingIndicatorChanged(boolean cfi) { 2557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon onCfiChanged(cfi); 2567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 2587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 2607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Handles a "new ringing connection" event from the telephony layer. 2617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 2627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onNewRingingConnection(AsyncResult r) { 2637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = (Connection) r.result; 2647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("onNewRingingConnection(): state = " + mCM.getState() + ", conn = { " + c + " }"); 2657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call ringing = c.getCall(); 2667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone phone = ringing.getPhone(); 2677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Check for a few cases where we totally ignore incoming calls. 2697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ignoreAllIncomingCalls(phone)) { 2707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Immediately reject the call, without even indicating to the user 2717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // that an incoming call occurred. (This will generally send the 2727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // caller straight to voicemail, just as if we *had* shown the 2737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // incoming-call UI and the user had declined the call.) 2747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.hangupRingingCall(ringing); 2757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 2767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!c.isRinging()) { 2797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "CallNotifier.onNewRingingConnection(): connection not ringing!"); 2807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This is a very strange case: an incoming call that stopped 2817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringing almost instantly after the onNewRingingConnection() 2827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event. There's nothing we can do here, so just bail out 2837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // without doing anything. (But presumably we'll log it in 2847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the call log when the disconnect event comes in...) 2857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 2867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 2877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signalInfo tone being played on receiving a Call 2897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 2907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Call.State state = c.getState(); 2927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // State will be either INCOMING or WAITING. 2937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- connection is ringing! state = " + state); 2947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) PhoneUtils.dumpCallState(mPhone); 2957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 2967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // No need to do any service state checks here (like for 2977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "emergency mode"), since in those states the SIM won't let 2987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // us get incoming connections in the first place. 2997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: Consider sending out a serialized broadcast Intent here 3017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (maybe "ACTION_NEW_INCOMING_CALL"), *before* starting the 3027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringer and going to the in-call UI. The intent should contain 3037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the caller-id info for the current connection, and say whether 3047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // it would be a "call waiting" call or a regular ringing call. 3057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If anybody consumed the broadcast, we'd bail out without 3067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ringing or bringing up the in-call UI. 3077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 3087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This would give 3rd party apps a chance to listen for (and 3097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // intercept) new ringing connections. An app could reject the 3107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // incoming call by consuming the broadcast and doing nothing, or 3117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // it could "pick up" the call (without any action by the user!) 3127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // via some future TelephonyManager API. 3137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 3147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // See bug 1312336 for more details. 3157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We'd need to protect this with a new "intercept incoming calls" 3167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // system permission. 3177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Obtain a partial wake lock to make sure the CPU doesn't go to 3197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // sleep before we finish bringing up the InCallScreen. 3207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (This will be upgraded soon to a full wake lock; see 3217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // showIncomingCall().) 3227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("Holding wake lock on new incoming connection."); 3237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.requestWakeState(PhoneGlobals.WakeState.PARTIAL); 3247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Note we *don't* post a status bar notification here, since 3267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we're not necessarily ready to actually show the incoming call 3277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to the user. (For calls in the INCOMING state, at least, we 3287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // still need to run a caller-id query, and we may not even ring 3297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // at all if the "send directly to voicemail" flag is set.) 3307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 3317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instead, we update the notification (and potentially launch the 3327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // InCallScreen) from the showIncomingCall() method, which runs 3337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when the caller-id query completes or times out. 3347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- onNewRingingConnection() done."); 3367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 3397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Determines whether or not we're allowed to present incoming calls to the 3407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * user, based on the capabilities and/or current state of the device. 3417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * If this method returns true, that means we should immediately reject the 3437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * current incoming call, without even indicating to the user that an 3447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * incoming call occurred. 3457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (We only reject incoming calls in a few cases, like during an OTASP call 3477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * when we can't interrupt the user, or if the device hasn't completed the 3487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * SetupWizard yet. We also don't allow incoming calls on non-voice-capable 3497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * devices. But note that we *always* allow incoming calls while in ECM.) 3507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * @return true if we're *not* allowed to present an incoming call to 3527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * the user. 3537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 3547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private boolean ignoreAllIncomingCalls(Phone phone) { 3557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored on non-voice-capable devices. 3567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 3577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ...but still log a warning, since we shouldn't have gotten this 3587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event in the first place! (Incoming calls *should* be blocked at 3597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the telephony layer on non-voice-capable capable devices.) 3607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onNewRingingConnection() on non-voice-capable device! Ignoring..."); 3617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 3627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // In ECM (emergency callback mode), we ALWAYS allow incoming calls 3657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // to get through to the user. (Note that ECM is applicable only to 3667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // voice-capable CDMA devices). 3677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (PhoneUtils.isPhoneInEcm(phone)) { 3687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("Incoming call while in ECM: always allow..."); 3697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 3707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored if the device isn't provisioned yet. 3737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean provisioned = Settings.Global.getInt(mApplication.getContentResolver(), 3747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Settings.Global.DEVICE_PROVISIONED, 0) != 0; 3757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!provisioned) { 3767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Ignoring incoming call: not provisioned"); 3777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 3787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 3797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Incoming calls are totally ignored if an OTASP call is active. 3817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (TelephonyCapabilities.supportsOtasp(phone)) { 3827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean activateState = (mApplication.cdmaOtaScreenState.otaScreenState 3837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION); 3847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean dialogState = (mApplication.cdmaOtaScreenState.otaScreenState 3857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG); 3867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean spcState = mApplication.cdmaOtaProvisionData.inOtaSpcState; 3877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 3887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (spcState) { 3897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.i(LOG_TAG, "Ignoring incoming call: OTA call is active"); 3907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return true; 3917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if (activateState || dialogState) { 3927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We *are* allowed to receive incoming calls at this point. 3937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // But clear out any residual OTASP UI first. 3947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: It's an MVC violation to twiddle the OTA UI state here; 3957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we should instead provide a higher-level API via OtaUtils. 3967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (dialogState) mApplication.dismissOtaDialogs(); 3977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.clearOtaState(); 3987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 3997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Normal case: allow this call to be presented to the user. 4037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return false; 4047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onUnknownConnectionAppeared(AsyncResult r) { 4077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 4087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state == PhoneConstants.State.OFFHOOK) { 41054fdb5954e76522b6961b8fd607c2c8bc474d075Santos Cordon if (DBG) log("unknown connection appeared..."); 411312b9c9112948c8ca7f74ea91b5e2585a66482c9Chiao Cheng 41254fdb5954e76522b6961b8fd607c2c8bc474d075Santos Cordon onPhoneStateChanged(r); 4137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 416b5e4b65a460e2c920c7de20eaa19608d65fe8687Christine Chen /** 4177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Updates the phone UI in response to phone state changes. 4187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 4197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Watch out: certain state changes are actually handled by their own 4207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * specific methods: 4217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * - see onNewRingingConnection() for new incoming calls 4227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * - see onDisconnect() for calls being hung up or disconnected 4237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 4247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onPhoneStateChanged(AsyncResult r) { 4257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneConstants.State state = mCM.getState(); 4267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onPhoneStateChanged: state = " + state); 4277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Turn status bar notifications on or off depending upon the state 4297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // of the phone. Notification Alerts (audible or vibrating) should 4307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // be on if and only if the phone is IDLE. 4317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.statusBarHelper 4327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon .enableNotificationAlerts(state == PhoneConstants.State.IDLE); 4337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Phone fgPhone = mCM.getFgPhone(); 4357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (fgPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 4367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((fgPhone.getForegroundCall().getState() == Call.State.ACTIVE) 4377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && ((mPreviousCdmaCallState == Call.State.DIALING) 4387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (mPreviousCdmaCallState == Call.State.ALERTING))) { 4397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mIsCdmaRedialCall) { 4407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_REDIAL; 4417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 4427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signal info tone when call moves to ACTIVE state 4447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 4457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mPreviousCdmaCallState = fgPhone.getForegroundCall().getState(); 4477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Have the PhoneApp recompute its mShowBluetoothIndication 4507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // flag based on the (new) telephony state. 4517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // There's no need to force a UI update since we update the 4527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // in-call notification ourselves (below), and the InCallScreen 4537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // listens for phone state changes itself. 45427a3c1f96fab43970e56a5eaa39551a4a248994fSantos Cordon mBluetoothManager.updateBluetoothIndication(); 4557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Update the phone state and other sensor/lock. 4577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.updatePhoneState(state); 4587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (state == PhoneConstants.State.OFFHOOK) { 4607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onPhoneStateChanged: OFF HOOK"); 4627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // make sure audio is in in-call mode now 4637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setAudioMode(mCM); 4647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon void updateCallNotifierRegistrationsAfterRadioTechnologyChange() { 4687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange..."); 4697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Instantiate mSignalInfoToneGenerator 4717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon createSignalInfoToneGenerator(); 4727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onDisconnect(AsyncResult r) { 4757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onDisconnect()... CallManager state: " + mCM.getState()); 4767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mVoicePrivacyState = false; 4787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Connection c = (Connection) r.result; 4797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 4800b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen log("onDisconnect: cause = " + DisconnectCause.toString(c.getDisconnectCause()) 4817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + ", incoming = " + c.isIncoming() 4827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon + ", date = " + c.getCreateTime()); 4837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 4847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "onDisconnect: null connection"); 4857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int autoretrySetting = 0; 4887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) { 4897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon autoretrySetting = android.provider.Settings.Global.getInt(mApplication. 4907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon getContentResolver(),android.provider.Settings.Global.CALL_AUTO_RETRY, 0); 4917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 4927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Stop any signalInfo tone being played when a call gets ended 4947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 4957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 4967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) { 4977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Resetting the CdmaPhoneCallState members 4987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState(); 4997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If this is the end of an OTASP call, pass it on to the PhoneApp. 5027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null && TelephonyCapabilities.supportsOtasp(c.getCall().getPhone())) { 5037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final String number = c.getAddress(); 5047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c.getCall().getPhone().isOtaSpNumber(number)) { 5057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onDisconnect: this was an OTASP call!"); 5067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.handleOtaspDisconnect(); 5077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Check for the various tones we might need to play (thru the 5117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // earpiece) after a call disconnects. 5127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneToPlay = InCallTonePlayer.TONE_NONE; 5137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If we don't need to play BUSY or CONGESTION, then play the 5157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "call ended" tone if this was a "regular disconnect" (i.e. a 5167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // normal call where one end or the other hung up) *and* this 5177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // disconnect event caused the phone to become idle. (In other 5187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // words, we *don't* play the sound if one call hangs up but 5197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // there's still an active call on the other line.) 5207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: We may eventually want to disable this via a preference. 5217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((toneToPlay == InCallTonePlayer.TONE_NONE) 5227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (mCM.getState() == PhoneConstants.State.IDLE) 5237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (c != null)) { 5240b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen int cause = c.getDisconnectCause(); 5250b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen if ((cause == DisconnectCause.NORMAL) // remote hangup 5260b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen || (cause == DisconnectCause.LOCAL)) { // local hangup 5277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- need to play CALL_ENDED tone!"); 5287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; 5297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 5307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // All phone calls are disconnected. 5347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getState() == PhoneConstants.State.IDLE) { 5357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Don't reset the audio mode or bluetooth/speakerphone state 5367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if we still need to let the user hear a tone through the earpiece. 5377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneToPlay == InCallTonePlayer.TONE_NONE) { 5387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon resetAudioStateAfterDisconnect(); 5397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (c != null) { 5437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mCallLogger.logCall(c); 5447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final String number = c.getAddress(); 5467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final Phone phone = c.getCall().getPhone(); 5477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon final boolean isEmergencyNumber = 54836bb2546cbc86a4e6d338c3c31bbd02c4602b5e2Yorke Lee PhoneNumberUtils.isLocalEmergencyNumber(mApplication, number); 5497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Possibly play a "post-disconnect tone" thru the earpiece. 5517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // We do this here, rather than from the InCallScreen 5527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // activity, since we need to do this even if you're not in 5537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the Phone UI at the moment the connection ends. 5547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneToPlay != InCallTonePlayer.TONE_NONE) { 5557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- starting post-disconnect tone (" + toneToPlay + ")..."); 5567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new InCallTonePlayer(toneToPlay).start(); 5577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: alternatively, we could start an InCallTonePlayer 5597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // here with an "unlimited" tone length, 5607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and manually stop it later when this connection truly goes 5617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // away. (The real connection over the network was closed as soon 5627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // as we got the BUSY message. But our telephony layer keeps the 5637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // connection open for a few extra seconds so we can show the 5647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "busy" indication to the user. We could stop the busy tone 5657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // when *that* connection's "disconnect" event comes in.) 5667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 568f68db2ef27f3bdf14f0053c46d73df910bd394f2Santos Cordon final int cause = c.getDisconnectCause(); 5697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (((mPreviousCdmaCallState == Call.State.DIALING) 5707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon || (mPreviousCdmaCallState == Call.State.ALERTING)) 5717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon && (!isEmergencyNumber) 5720b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.INCOMING_MISSED ) 5730b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.NORMAL) 5740b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.LOCAL) 5750b35f04f2e58095d7292468c746d992913965eeaAnders Kristensen && (cause != DisconnectCause.INCOMING_REJECTED)) { 5767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!mIsCdmaRedialCall) { 5777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) { 5787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: (Moto): The contact reference data may need to be stored and use 5797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // here when redialing a call. For now, pass in NULL as the URI parameter. 580ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon final int status = 581ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon PhoneUtils.placeCall(mApplication, phone, number, null, false); 582ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon if (status != PhoneUtils.CALL_STATUS_FAILED) { 583ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon mIsCdmaRedialCall = true; 584ce02f3a2f1bb13c7d0c4db523e6b4408ce2a8446Santos Cordon } 5857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 5877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 5897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mIsCdmaRedialCall = false; 5907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 5947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 5957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 5967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Resets the audio mode and speaker state when a call ends. 5977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 5987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void resetAudioStateAfterDisconnect() { 5997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("resetAudioStateAfterDisconnect()..."); 6007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mBluetoothHeadset != null) { 6027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset.disconnectAudio(); 6037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // call turnOnSpeaker() with state=false and store=true even if speaker 6067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // is already off to reset user requested speaker state. 6077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.turnOnSpeaker(mApplication, false, true); 6087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon PhoneUtils.setAudioMode(mCM); 6107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onMwiChanged(boolean visible) { 6137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onMwiChanged(): " + visible); 6147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "Voicemail" is meaningless on non-voice-capable devices, 6167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // so ignore MWI events. 6177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 6187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ...but still log a warning, since we shouldn't have gotten this 6197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // event in the first place! 6207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR events 6217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // *should* be blocked at the telephony layer on non-voice-capable 6227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // capable devices.) 6237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onMwiChanged() on non-voice-capable device! Ignoring..."); 6247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 6257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.updateMwi(visible); 6287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Posts a delayed PHONE_MWI_CHANGED event, to schedule a "retry" for a 6327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * failed NotificationMgr.updateMwi() call. 6337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void sendMwiChangedDelayed(long delayMillis) { 6357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Message message = Message.obtain(this, PHONE_MWI_CHANGED); 6367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendMessageDelayed(message, delayMillis); 6377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onCfiChanged(boolean visible) { 6407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("onCfiChanged(): " + visible); 6417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mApplication.notificationMgr.updateCfi(visible); 6427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 6457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper class to play tones through the earpiece (or speaker / BT) 6467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * during a call, using the ToneGenerator. 6477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 6487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * To use, just instantiate a new InCallTonePlayer 6497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (passing in the TONE_* constant for the tone you want) 6507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and start() it. 6517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 6527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * When we're done playing the tone, if the phone is idle at that 6537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * point, we'll reset the audio routing and speaker state. 6547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (That means that for tones that get played *after* a call 6557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * disconnects, like "busy" or "congestion" or "call ended", you 6567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * should NOT call resetAudioStateAfterDisconnect() yourself. 6577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Instead, just start the InCallTonePlayer, which will automatically 6587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * defer the resetAudioStateAfterDisconnect() call until the tone 6597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * finishes playing.) 6607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 6617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private class InCallTonePlayer extends Thread { 6627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mToneId; 6637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mState; 6647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The possible tones we can play. 6657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_NONE = 0; 6667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CALL_WAITING = 1; 6677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_BUSY = 2; 6687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CONGESTION = 3; 6697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CALL_ENDED = 4; 6707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_VOICE_PRIVACY = 5; 6717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_REORDER = 6; 6727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_INTERCEPT = 7; 6737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_CDMA_DROP = 8; 6747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_OUT_OF_SERVICE = 9; 6757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_REDIAL = 10; 6767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_OTA_CALL_END = 11; 6777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public static final int TONE_UNOBTAINABLE_NUMBER = 13; 6787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone volume relative to other sounds in the stream 6807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_EMERGENCY = 100; 6817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_HIPRI = 80; 6827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_RELATIVE_VOLUME_LOPRI = 50; 6837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Buffer time (in msec) to add on to tone timeout value. 6857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Needed mainly when the timeout value for a tone is the 6867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // exact duration of the tone itself. 6877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_TIMEOUT_BUFFER = 20; 6887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // The tone state 6907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_OFF = 0; 6917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_ON = 1; 6927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon static final int TONE_STOPPED = 2; 6937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 6947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon InCallTonePlayer(int toneId) { 6957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon super(); 6967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneId = toneId; 6977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_OFF; 6987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 6997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 7017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 7027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("InCallTonePlayer.run(toneId = " + mToneId + ")..."); 7037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneType = 0; // passed to ToneGenerator.startTone() 7057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneVolume; // passed to the ToneGenerator constructor 7067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneLengthMillis; 7077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int phoneType = mCM.getFgPhone().getPhoneType(); 7087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon switch (mToneId) { 7107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CALL_WAITING: 7117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 7127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Call waiting tone is stopped by stopTone() method 7147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; 7157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_BUSY: 7177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 7187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT; 7197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 7207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 1000; 721cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM 722cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal || phoneType == PhoneConstants.PHONE_TYPE_SIP 7230ca1c80f1ca60966a16169b109e96ac19fa69743Etan Cohen || phoneType == PhoneConstants.PHONE_TYPE_IMS 724cc0375f8f26f868a55c36616921f4c572347062bSailesh Nepal || phoneType == PhoneConstants.PHONE_TYPE_THIRD_PARTY) { 7257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_BUSY; 7267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 7287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalStateException("Unexpected phone type: " + phoneType); 7307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CONGESTION: 7337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_CONGESTION; 7347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 7367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CALL_ENDED: 7397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 7407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 200; 7427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_OTA_CALL_END: 7447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone == 7457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon OtaUtils.OTA_PLAY_SUCCESS_FAILURE_TONE_ON) { 7467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD; 7477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 750; 7497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_PROP_PROMPT; 7517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 200; 7537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_VOICE_PRIVACY: 7567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE; 7577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 5000; 7597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_REORDER: 7617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_REORDER; 7627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 7647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_INTERCEPT: 7667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT; 7677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 7687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 500; 7697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_CDMA_DROP: 7717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_OUT_OF_SERVICE: 7727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 7737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 7747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 375; 7757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_REDIAL: 7777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE; 7787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 7797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 5000; 7807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon case TONE_UNOBTAINABLE_NUMBER: 7827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneType = ToneGenerator.TONE_SUP_ERROR; 7837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 7847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneLengthMillis = 4000; 7857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon break; 7867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon default: 7877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon throw new IllegalArgumentException("Bad toneId: " + mToneId); 7887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 7897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 7907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // If the mToneGenerator creation fails, just continue without it. It is 7917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // a local audio signal, and is not as important. 7927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon ToneGenerator toneGenerator; 7937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 7947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int stream; 7957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mBluetoothHeadset != null) { 7967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stream = mBluetoothHeadset.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO: 7977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon AudioManager.STREAM_VOICE_CALL; 7987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 7997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stream = AudioManager.STREAM_VOICE_CALL; 8007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator = new ToneGenerator(stream, toneVolume); 8027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) log("- created toneGenerator: " + toneGenerator); 8037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (RuntimeException e) { 8047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, 8057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "InCallTonePlayer: Exception caught while creating ToneGenerator: " + e); 8067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator = null; 8077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Using the ToneGenerator (with the CALL_WAITING / BUSY / 8107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CONGESTION tones at least), the ToneGenerator itself knows 8117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // the right pattern of tones to play; we do NOT need to 8127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // manually start/stop each individual tone, or manually 8137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // insert the correct delay between tones. (We just start it 8147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and let it run for however long we want the tone pattern to 8157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // continue.) 8167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // TODO: When we stop the ToneGenerator in the middle of a 8187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "tone pattern", it sounds bad if we cut if off while the 8197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // tone is actually playing. Consider adding API to the 8207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // ToneGenerator to say "stop at the next silent part of the 8217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // pattern", or simply "play the pattern N times and then 8227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // stop." 8237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean needToStopTone = true; 8247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean okToPlayTone = false; 8257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneGenerator != null) { 8277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int ringerMode = mAudioManager.getRingerMode(); 8287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 8297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (toneType == ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD) { 8307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 8317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 8327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("- InCallTonePlayer: start playing call tone=" + toneType); 8337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 8347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 8357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((toneType == ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT) || 8377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_REORDER) || 8387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ABBR_REORDER) || 8397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ABBR_INTERCEPT) || 8407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_CALLDROP_LITE)) { 8417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (ringerMode != AudioManager.RINGER_MODE_SILENT) { 8427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("InCallTonePlayer:playing call fail tone:" + toneType); 8437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 8447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 8457d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else if ((toneType == ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE) || 8477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (toneType == ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE)) { 8487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 8497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 8507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("InCallTonePlayer:playing tone for toneType=" + toneType); 8517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 8527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon needToStopTone = false; 8537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { // For the rest of the tones, always OK to play. 8557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 8567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { // Not "CDMA" 8587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon okToPlayTone = true; 8597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (this) { 8627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (okToPlayTone && mState != TONE_STOPPED) { 8637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_ON; 8647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.startTone(toneType); 8657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon try { 8667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon wait(toneLengthMillis + TONE_TIMEOUT_BUFFER); 8677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } catch (InterruptedException e) { 8687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, 8697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon "InCallTonePlayer stopped: " + e); 8707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (needToStopTone) { 8727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.stopTone(); 8737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // if (DBG) log("- InCallTonePlayer: done playing."); 8767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon toneGenerator.release(); 8777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_OFF; 8787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Finally, do the same cleanup we otherwise would have done 8827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // in onDisconnect(). 8837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // 8847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // (But watch out: do NOT do this if the phone is in use, 8857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // since some of our tones get played *during* a call (like 8867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // CALL_WAITING) and we definitely *don't* 8877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // want to reset the audio mode / speaker / bluetooth after 8887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // playing those! 8897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // This call is really here for use with tones that get played 8907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // *after* a call disconnects, like "busy" or "congestion" or 8917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // "call ended", where the phone has already become idle but 8927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // we need to defer the resetAudioStateAfterDisconnect() call 8937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // till the tone finishes playing.) 8947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mCM.getState() == PhoneConstants.State.IDLE) { 8957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon resetAudioStateAfterDisconnect(); 8967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 8987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 8997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void stopTone() { 9007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon synchronized (this) { 9017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mState == TONE_ON) { 9027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon notify(); 9037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mState = TONE_STOPPED; 9057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Displays a notification when the phone receives a DisplayInfo record. 9117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onDisplayInfo(AsyncResult r) { 9137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Extract the DisplayInfo String from the message 9147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfoRec displayInfoRec = (CdmaDisplayInfoRec)(r.result); 9157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (displayInfoRec != null) { 9177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon String displayInfo = displayInfoRec.alpha; 9187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onDisplayInfo: displayInfo=" + displayInfo); 9197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaDisplayInfo.displayInfoRecord(mApplication, displayInfo); 9207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // start a 2 second timer 9227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon sendEmptyMessageDelayed(DISPLAYINFO_NOTIFICATION_DONE, 9237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon DISPLAYINFO_NOTIFICATION_TIME); 9247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9277d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Helper class to play SignalInfo tones using the ToneGenerator. 9297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 9307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * To use, just instantiate a new SignalInfoTonePlayer 9317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * (passing in the ToneID constant for the tone you want) 9327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * and start() it. 9337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private class SignalInfoTonePlayer extends Thread { 9357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private int mToneId; 9367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon SignalInfoTonePlayer(int toneId) { 9387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon super(); 9397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mToneId = toneId; 9407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon @Override 9437d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void run() { 9447d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")..."); 94565cbd16626492166c23be4a851de12a3ebac0786Yorke Lee createSignalInfoToneGenerator(); 9467d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (mSignalInfoToneGenerator != null) { 9477d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //First stop any ongoing SignalInfo tone 9487d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator.stopTone(); 9497d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9507d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Start playing the new tone if its a valid tone 9517d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mSignalInfoToneGenerator.startTone(mToneId); 9527d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9537d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9547d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9557d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9567d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9577d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Plays a tone when the phone receives a SignalInfo record. 9587d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 9597d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void onSignalInfo(AsyncResult r) { 9607d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Signal Info are totally ignored on non-voice-capable devices. 9617d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (!PhoneGlobals.sVoiceCapable) { 9627d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.w(LOG_TAG, "Got onSignalInfo() on non-voice-capable device! Ignoring..."); 9637d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return; 9647d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9657d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9667d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (PhoneUtils.isRealIncomingCall(mCM.getFirstActiveRingingCall().getState())) { 9677d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Do not start any new SignalInfo tone when Call state is INCOMING 9687d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // and stop any previous SignalInfo tone which is being played 9697d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon stopSignalInfoTone(); 9707d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } else { 9717d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Extract the SignalInfo String from the message 9727d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon CdmaSignalInfoRec signalInfoRec = (CdmaSignalInfoRec)(r.result); 9737d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon // Only proceed if a Signal info is present. 9747d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (signalInfoRec != null) { 9757d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon boolean isPresent = signalInfoRec.isPresent; 9767d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onSignalInfo: isPresent=" + isPresent); 9777d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (isPresent) {// if tone is valid 9787d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignalType = signalInfoRec.signalType; 9797d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uAlertPitch = signalInfoRec.alertPitch; 9807d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int uSignal = signalInfoRec.signal; 9817d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9827d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("onSignalInfo: uSignalType=" + uSignalType + ", uAlertPitch=" + 9837d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon uAlertPitch + ", uSignal=" + uSignal); 9847d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Map the Signal to a ToneGenerator ToneID only if Signal info is present 9857d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon int toneID = SignalToneUtil.getAudioToneFromSignalInfo 9867d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon (uSignalType, uAlertPitch, uSignal); 9877d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9887d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon //Create the SignalInfo tone player and pass the ToneID 9897d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new SignalInfoTonePlayer(toneID).start(); 9907d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9917d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9927d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9937d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 9947d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 9957d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 9967d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Stops a SignalInfo tone in the following condition 9977d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 1 - On receiving a New Ringing Call 9987d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 2 - On disconnecting a call 9997d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * 3 - On answering a Call Waiting Call 10007d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10017d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ void stopSignalInfoTone() { 10027d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (DBG) log("stopSignalInfoTone: Stopping SignalInfo tone player"); 10037d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new SignalInfoTonePlayer(ToneGenerator.TONE_CDMA_SIGNAL_OFF).start(); 10047d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10057d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10067d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10077d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mPreviousCdmaCallState. 10087d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10097d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ Call.State getPreviousCdmaCallState() { 10107d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mPreviousCdmaCallState; 10117d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10127d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10137d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10147d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mVoicePrivacyState. 10157d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10167d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ boolean getVoicePrivacyState() { 10177d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mVoicePrivacyState; 10187d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10197d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10207d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /** 10217d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon * Return the private variable mIsCdmaRedialCall. 10227d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon */ 10237d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon /* package */ boolean getIsCdmaRedialCall() { 10247d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon return mIsCdmaRedialCall; 10257d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10267d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10275c046727927b8cb766ad937bc89687fd1dfd1b4fSantos Cordon private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 10287d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon new BluetoothProfile.ServiceListener() { 10297d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onServiceConnected(int profile, BluetoothProfile proxy) { 10307d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset = (BluetoothHeadset) proxy; 10317d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon if (VDBG) log("- Got BluetoothHeadset: " + mBluetoothHeadset); 10327d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10337d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10347d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon public void onServiceDisconnected(int profile) { 10357d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon mBluetoothHeadset = null; 10367d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10377d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon }; 10387d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon 10397d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon private void log(String msg) { 10407d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon Log.d(LOG_TAG, msg); 10417d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon } 10427d4ddf6dc0d7c8158bac3a5dec7936e837e95bddSantos Cordon} 1043