1b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/* 2b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 4b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * you may not use this file except in compliance with the License. 6b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * You may obtain a copy of the License at 7b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 8b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 10b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * See the License for the specific language governing permissions and 14b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * limitations under the License. 15b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 16b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 17b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpackage com.android.phone; 18b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 19b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Call; 20b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfo; 21b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.CallerInfoAsyncQuery; 220fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport com.android.internal.telephony.cdma.CdmaCallWaitingNotification; 230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport com.android.internal.telephony.cdma.SignalToneUtil; 240fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec; 250fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Savilleimport com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec; 26b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Connection; 27b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport com.android.internal.telephony.Phone; 286f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Savilleimport com.android.internal.telephony.PhoneBase; 29170160f6550b2933ff5a6c96c879d074a3ca2f16John Wangimport com.android.internal.telephony.CallManager; 30b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 317f63f08c5c88d604abba447032ed42f4f972f3efDavid Brownimport android.app.ActivityManagerNative; 32b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.content.Context; 33b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.AudioManager; 34b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.media.ToneGenerator; 35b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.AsyncResult; 36b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Handler; 37b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.Message; 387f63f08c5c88d604abba447032ed42f4f972f3efDavid Brownimport android.os.RemoteException; 39b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.os.SystemProperties; 40678d72446de9c185c767206338f5fb199e0cd845Peng Zhuimport android.os.Vibrator; 41b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.CallLog.Calls; 42b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.provider.Settings; 433800ac871d6548790ac6119bb68b9be0640af261David Krauseimport android.telephony.PhoneNumberUtils; 44b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.telephony.PhoneStateListener; 45b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.telephony.TelephonyManager; 4640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Cataniaimport android.text.TextUtils; 47cd89106dcd1038666f992cea3cc79e067245187fDan Egnorimport android.util.EventLog; 48b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectimport android.util.Log; 49b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 50b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 51b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project/** 52325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * Phone app module that listens for phone state changes and various other 53325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * events from the telephony layer, and triggers any resulting UI behavior 54325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * (like starting the Ringer and Incoming Call UI, playing in-call tones, 55325cc2ced6f1ff5fb1708abfcc5e9c73ac0cd962David Brown * updating notifications, writing call log entries, etc.) 56b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 57b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Projectpublic class CallNotifier extends Handler 58b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project implements CallerInfoAsyncQuery.OnQueryCompleteListener { 59796c70c99bc39295bf685061056f06ab8949c742David Brown private static final String LOG_TAG = "CallNotifier"; 60b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final boolean DBG = 61796c70c99bc39295bf685061056f06ab8949c742David Brown (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1); 62796c70c99bc39295bf685061056f06ab8949c742David Brown private static final boolean VDBG = (PhoneApp.DBG_LEVEL >= 2); 63b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 64b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Maximum time we allow the CallerInfo query to run, 65b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // before giving up and falling back to the default ringtone. 66b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int RINGTONE_QUERY_WAIT_TIME = 500; // msec 67b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Timers related to CDMA Call Waiting 690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // 1) For displaying Caller Info 700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // 2) For disabling "Add Call" menu option once User selects Ignore or CW Timeout occures 710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int CALLWAITING_CALLERINFO_DISPLAY_TIME = 20000; // msec 7239a84144262f12df44861d746788b9de92259e4fAbhishek Pillai private static final int CALLWAITING_ADDCALL_DISABLE_TIME = 30000; // msec 730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Time to display the DisplayInfo Record sent by CDMA network 750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int DISPLAYINFO_NOTIFICATION_TIME = 2000; // msec 760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 77f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown /** The singleton instance. */ 78f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown private static CallNotifier sInstance; 79f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown 8077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // Boolean to keep track of whether or not a CDMA Call Waiting call timed out. 8177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // 8277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // This is CDMA-specific, because with CDMA we *don't* get explicit 8377350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // notification from the telephony layer that a call-waiting call has 8477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // stopped ringing. Instead, when a call-waiting call first comes in we 8577350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // start a 20-second timer (see CALLWAITING_CALLERINFO_DISPLAY_DONE), and 8677350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // if the timer expires we clean up the call and treat it as a missed call. 8777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // 8877350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // If this field is true, that means that the current Call Waiting call 8977350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // "timed out" and should be logged in Call Log as a missed call. If it's 9077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // false when we reach onCdmaCallWaitingReject(), we can assume the user 9177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // explicitly rejected this call-waiting call. 9277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // 9377350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // This field is reset to false any time a call-waiting call first comes 9477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // in, and after cleaning up a missed call-waiting call. It's only ever 9577350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // set to true when the CALLWAITING_CALLERINFO_DISPLAY_DONE timer fires. 9677350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // 9777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // TODO: do we really need a member variable for this? Don't we always 9877350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // know at the moment we call onCdmaCallWaitingReject() whether this is an 9977350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // explicit rejection or not? 10077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // (Specifically: when we call onCdmaCallWaitingReject() from 10177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // PhoneUtils.hangupRingingCall() that means the user deliberately rejected 10277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // the call, and if we call onCdmaCallWaitingReject() because of a 10377350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // CALLWAITING_CALLERINFO_DISPLAY_DONE event that means that it timed 10477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown // out...) 1050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private boolean mCallWaitingTimeOut = false; 1060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // values used to track the query state 108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int CALLERINFO_QUERY_READY = 0; 109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int CALLERINFO_QUERYING = -1; 110b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the state of the CallerInfo Query. 112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mCallerInfoQueryState; 113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // object used to synchronize access to mCallerInfoQueryState 115b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Object mCallerInfoQueryStateGuard = new Object(); 116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 117b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Event used to indicate a query timeout. 118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT = 100; 119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Events from the Phone object: 121b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_STATE_CHANGED = 1; 122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_NEW_RINGING_CONNECTION = 2; 123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_DISCONNECT = 3; 124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_UNKNOWN_CONNECTION_APPEARED = 4; 125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int PHONE_INCOMING_RING = 5; 1260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int PHONE_STATE_DISPLAYINFO = 6; 1270fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int PHONE_STATE_SIGNALINFO = 7; 1280fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private static final int PHONE_CDMA_CALL_WAITING = 8; 1293800ac871d6548790ac6119bb68b9be0640af261David Krause private static final int PHONE_ENHANCED_VP_ON = 9; 1303800ac871d6548790ac6119bb68b9be0640af261David Krause private static final int PHONE_ENHANCED_VP_OFF = 10; 13177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int PHONE_RINGBACK_TONE = 11; 13277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int PHONE_RESEND_MUTE = 12; 1333800ac871d6548790ac6119bb68b9be0640af261David Krause 134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Events generated internally: 13577350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int PHONE_MWI_CHANGED = 21; 13677350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int PHONE_BATTERY_LOW = 22; 13777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int CALLWAITING_CALLERINFO_DISPLAY_DONE = 23; 13877350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int CALLWAITING_ADDCALL_DISABLE_TIMEOUT = 24; 13977350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int DISPLAYINFO_NOTIFICATION_DONE = 25; 14077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int EVENT_OTA_PROVISION_CHANGE = 26; 14177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private static final int CDMA_CALL_WAITING_REJECT = 27; 142e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown private static final int UPDATE_IN_CALL_NOTIFICATION = 28; 143eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 144678d72446de9c185c767206338f5fb199e0cd845Peng Zhu // Emergency call related defines: 145678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private static final int EMERGENCY_TONE_OFF = 0; 146678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private static final int EMERGENCY_TONE_ALERT = 1; 147678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private static final int EMERGENCY_TONE_VIBRATE = 2; 148678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 149b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private PhoneApp mApplication; 150170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang private CallManager mCM; 151b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private Ringer mRinger; 152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private BluetoothHandsfree mBluetoothHandsfree; 15311aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania private CallLogAsync mCallLog; 154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private boolean mSilentRingerRequested; 155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1560fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // ToneGenerator instance for playing SignalInfo tones 1570fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private ToneGenerator mSignalInfoToneGenerator; 1580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // The tone volume relative to other sounds in the stream SignalInfo 160ed1d155825eb32990fde95eef9d89a7260e4c3f1w private static final int TONE_RELATIVE_VOLUME_SIGNALINFO = 80; 1610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1623800ac871d6548790ac6119bb68b9be0640af261David Krause private Call.State mPreviousCdmaCallState; 16324f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon private boolean mVoicePrivacyState = false; 1643800ac871d6548790ac6119bb68b9be0640af261David Krause private boolean mIsCdmaRedialCall = false; 1653800ac871d6548790ac6119bb68b9be0640af261David Krause 166678d72446de9c185c767206338f5fb199e0cd845Peng Zhu // Emergency call tone and vibrate: 167678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private int mIsEmergencyToneOn; 168678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private int mCurrentEmergencyToneState = EMERGENCY_TONE_OFF; 169678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private EmergencyTonePlayerVibrator mEmergencyTonePlayerVibrator; 170678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 171eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // Ringback tone player 17203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private InCallTonePlayer mInCallRingbackTonePlayer; 17303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 17403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // Call waiting tone player 17503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private InCallTonePlayer mCallWaitingTonePlayer; 17603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 17703d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // Cached AudioManager 17803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private AudioManager mAudioManager; 179eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 180f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown /** 181f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown * Initialize the singleton CallNotifier instance. 182f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown * This is only done once, at startup, from PhoneApp.onCreate(). 183f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown */ 184f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown /* package */ static CallNotifier init(PhoneApp app, Phone phone, Ringer ringer, 185f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown BluetoothHandsfree btMgr, CallLogAsync callLog) { 186f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown synchronized (CallNotifier.class) { 187f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown if (sInstance == null) { 188f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown sInstance = new CallNotifier(app, phone, ringer, btMgr, callLog); 189f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown } else { 190f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 191f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown } 192f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown return sInstance; 193f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown } 194f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown } 195f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown 196f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown /** Private constructor; @see init() */ 197f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown private CallNotifier(PhoneApp app, Phone phone, Ringer ringer, 198f0c4d0e94b7fa915bcfacd28ee432f8b3846511aDavid Brown BluetoothHandsfree btMgr, CallLogAsync callLog) { 199b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication = app; 200170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM = app.mCM; 20111aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania mCallLog = callLog; 20279b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink 203872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mAudioManager = (AudioManager) mApplication.getSystemService(Context.AUDIO_SERVICE); 20403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 20524f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon registerForNotifications(); 20624f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon 20724f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon // Instantiate the ToneGenerator for SignalInfo and CallWaiting 20824f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon // TODO: We probably don't need the mSignalInfoToneGenerator instance 20924f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon // around forever. Need to change it so as to create a ToneGenerator instance only 21024f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon // when a tone is being played and releases it after its done playing. 21124f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon try { 21224f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon mSignalInfoToneGenerator = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, 21324f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon TONE_RELATIVE_VOLUME_SIGNALINFO); 21424f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon } catch (RuntimeException e) { 21524f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon Log.w(LOG_TAG, "CallNotifier: Exception caught while creating " + 21624f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon "mSignalInfoToneGenerator: " + e); 21724f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon mSignalInfoToneGenerator = null; 218eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 219eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger = ringer; 221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothHandsfree = btMgr; 222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project TelephonyManager telephonyManager = (TelephonyManager)app.getSystemService( 224b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Context.TELEPHONY_SERVICE); 225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project telephonyManager.listen(mPhoneStateListener, 226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR 227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project | PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR); 228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void handleMessage(Message msg) { 232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (msg.what) { 233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_NEW_RINGING_CONNECTION: 2344158ed3e7bdff5212a5542e662240ea0063664b2David Brown log("RINGING... (new)"); 235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onNewRingingConnection((AsyncResult) msg.obj); 236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSilentRingerRequested = false; 237b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_INCOMING_RING: 240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // repeat the ring when requested by the RIL, and when the user has NOT 241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // specifically requested silence. 2426f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville if (msg.obj != null && ((AsyncResult) msg.obj).result != null) { 2436f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville PhoneBase pb = (PhoneBase)((AsyncResult)msg.obj).result; 2446f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville 2456f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville if ((pb.getState() == Phone.State.RINGING) 2466f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville && (mSilentRingerRequested == false)) { 2476f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville if (DBG) log("RINGING... (PHONE_INCOMING_RING event)"); 2486f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville mRinger.ring(); 2496f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville } else { 2506f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville if (DBG) log("RING before NEW_RING, skipping"); 2516f9f8d7224cd9c66513f987fc71edb61a30a2c2eWink Saville } 252b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 253b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 2540fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 255b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_STATE_CHANGED: 256b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onPhoneStateChanged((AsyncResult) msg.obj); 257b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 258b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 259b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_DISCONNECT: 260b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("DISCONNECT"); 261b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onDisconnect((AsyncResult) msg.obj); 262b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 263b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 264b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_UNKNOWN_CONNECTION_APPEARED: 265b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onUnknownConnectionAppeared((AsyncResult) msg.obj); 266b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 267b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 268b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT: 269b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CallerInfo query is taking too long! But we can't wait 270b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // any more, so start ringing NOW even if it means we won't 271b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // use the correct custom ringtone. 272796c70c99bc39295bf685061056f06ab8949c742David Brown Log.w(LOG_TAG, "CallerInfo query took too long; manually starting ringer"); 273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In this case we call onCustomRingQueryComplete(), just 275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // like if the query had completed normally. (But we're 276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // going to get the default ringtone, since we never got 277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the chance to call Ringer.setCustomRingtoneUri()). 278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onCustomRingQueryComplete(); 279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 280b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_MWI_CHANGED: 282872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan onMwiChanged(mApplication.phone.getMessageWaitingIndicator()); 283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case PHONE_BATTERY_LOW: 286b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onBatteryLow(); 287b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 288b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 2890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case PHONE_CDMA_CALL_WAITING: 2900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received PHONE_CDMA_CALL_WAITING event"); 2910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville onCdmaCallWaiting((AsyncResult) msg.obj); 2920fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 2930fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 29477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown case CDMA_CALL_WAITING_REJECT: 29577350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown Log.i(LOG_TAG, "Received CDMA_CALL_WAITING_REJECT event"); 29677350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown onCdmaCallWaitingReject(); 29777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown break; 29877350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown 2990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case CALLWAITING_CALLERINFO_DISPLAY_DONE: 30077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown Log.i(LOG_TAG, "Received CALLWAITING_CALLERINFO_DISPLAY_DONE event"); 3010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mCallWaitingTimeOut = true; 3020fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville onCdmaCallWaitingReject(); 3030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 3040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case CALLWAITING_ADDCALL_DISABLE_TIMEOUT: 3060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received CALLWAITING_ADDCALL_DISABLE_TIMEOUT event ..."); 3070fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Set the mAddCallMenuStateAfterCW state to true 3080fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true); 30975e3711d82d0c98444f6c438437cad41d862fca6David Brown mApplication.updateInCallScreen(); 3100fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 3110fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3120fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case PHONE_STATE_DISPLAYINFO: 3130fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received PHONE_STATE_DISPLAYINFO event"); 3140fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville onDisplayInfo((AsyncResult) msg.obj); 3150fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 3160fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3170fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case PHONE_STATE_SIGNALINFO: 3180fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received PHONE_STATE_SIGNALINFO event"); 3190fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville onSignalInfo((AsyncResult) msg.obj); 3200fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 3210fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 3220fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville case DISPLAYINFO_NOTIFICATION_DONE: 3230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("Received Display Info notification done event ..."); 3240fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CdmaDisplayInfo.dismissDisplayInfoRecord(); 3250fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville break; 3260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 327af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville case EVENT_OTA_PROVISION_CHANGE: 328211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown if (DBG) log("EVENT_OTA_PROVISION_CHANGE..."); 329211ff4c5c95f63f845b953f0020dfb516c01fcadDavid Brown mApplication.handleOtaspEvent(msg); 330af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville break; 331af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville 3323800ac871d6548790ac6119bb68b9be0640af261David Krause case PHONE_ENHANCED_VP_ON: 3333800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("PHONE_ENHANCED_VP_ON..."); 33424f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon if (!mVoicePrivacyState) { 3353800ac871d6548790ac6119bb68b9be0640af261David Krause int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 3363800ac871d6548790ac6119bb68b9be0640af261David Krause new InCallTonePlayer(toneToPlay).start(); 33724f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon mVoicePrivacyState = true; 338b3e1e0012986738034dab1e0625cde8095c61542Peng Zhu // Update the VP icon: 33949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- updating notification for VP state..."); 340df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateInCallNotification(); 3413800ac871d6548790ac6119bb68b9be0640af261David Krause } 3423800ac871d6548790ac6119bb68b9be0640af261David Krause break; 3433800ac871d6548790ac6119bb68b9be0640af261David Krause 3443800ac871d6548790ac6119bb68b9be0640af261David Krause case PHONE_ENHANCED_VP_OFF: 3453800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("PHONE_ENHANCED_VP_OFF..."); 34624f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon if (mVoicePrivacyState) { 3473800ac871d6548790ac6119bb68b9be0640af261David Krause int toneToPlay = InCallTonePlayer.TONE_VOICE_PRIVACY; 3483800ac871d6548790ac6119bb68b9be0640af261David Krause new InCallTonePlayer(toneToPlay).start(); 34924f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon mVoicePrivacyState = false; 350b3e1e0012986738034dab1e0625cde8095c61542Peng Zhu // Update the VP icon: 35149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- updating notification for VP state..."); 352df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateInCallNotification(); 3533800ac871d6548790ac6119bb68b9be0640af261David Krause } 3543800ac871d6548790ac6119bb68b9be0640af261David Krause break; 3553800ac871d6548790ac6119bb68b9be0640af261David Krause 356eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang case PHONE_RINGBACK_TONE: 357eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang onRingbackTone((AsyncResult) msg.obj); 358eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang break; 359eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 3605bf2817fb998e6d7c7b50103733bfe8710d63916John Wang case PHONE_RESEND_MUTE: 3615bf2817fb998e6d7c7b50103733bfe8710d63916John Wang onResendMute(); 3625bf2817fb998e6d7c7b50103733bfe8710d63916John Wang break; 3635bf2817fb998e6d7c7b50103733bfe8710d63916John Wang 364e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown case UPDATE_IN_CALL_NOTIFICATION: 365df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateInCallNotification(); 366e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown break; 367e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown 368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // super.handleMessage(msg); 370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 374b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 375b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onMessageWaitingIndicatorChanged(boolean mwi) { 376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onMwiChanged(mwi); 377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void onCallForwardingIndicatorChanged(boolean cfi) { 381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onCfiChanged(cfi); 382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project }; 384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 385d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown /** 386d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * Handles a "new ringing connection" event from the telephony layer. 387d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown */ 388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onNewRingingConnection(AsyncResult r) { 389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection c = (Connection) r.result; 3904158ed3e7bdff5212a5542e662240ea0063664b2David Brown log("onNewRingingConnection(): state = " + mCM.getState() + ", conn = { " + c + " }"); 3918343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Call ringing = c.getCall(); 3928343169cc89621d46dce86449f5ee1ff5d3a4919John Wang Phone phone = ringing.getPhone(); 393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 394d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Check for a few cases where we totally ignore incoming calls. 395d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (ignoreAllIncomingCalls(phone)) { 396d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Immediately reject the call, without even indicating to the user 397d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // that an incoming call occurred. (This will generally send the 398d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // caller straight to voicemail, just as if we *had* shown the 399d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // incoming-call UI and the user had declined the call.) 4008343169cc89621d46dce86449f5ee1ff5d3a4919John Wang PhoneUtils.hangupRingingCall(ringing); 401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 40449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (c == null) { 40549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown Log.w(LOG_TAG, "CallNotifier.onNewRingingConnection(): null connection!"); 40649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // Should never happen, but if it does just bail out and do nothing. 40749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown return; 40849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown } 40905fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu 41049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (!c.isRinging()) { 41149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown Log.i(LOG_TAG, "CallNotifier.onNewRingingConnection(): connection not ringing!"); 41249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // This is a very strange case: an incoming call that stopped 41349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // ringing almost instantly after the onNewRingingConnection() 41449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // event. There's nothing we can do here, so just bail out 41549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // without doing anything. (But presumably we'll log it in 41649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // the call log when the disconnect event comes in...) 41749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown return; 41849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown } 41949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 42049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // Stop any signalInfo tone being played on receiving a Call 4219537852545bf97d9e4d903c1eb2b528adc22dbc8David Brown stopSignalInfoTone(); 42249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 42349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown Call.State state = c.getState(); 42449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // State will be either INCOMING or WAITING. 42549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (VDBG) log("- connection is ringing! state = " + state); 42649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // if (DBG) PhoneUtils.dumpCallState(mPhone); 42749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 42849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // No need to do any service state checks here (like for 42949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // "emergency mode"), since in those states the SIM won't let 43049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // us get incoming connections in the first place. 43149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 43249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // TODO: Consider sending out a serialized broadcast Intent here 43349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // (maybe "ACTION_NEW_INCOMING_CALL"), *before* starting the 43449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // ringer and going to the in-call UI. The intent should contain 43549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // the caller-id info for the current connection, and say whether 43649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // it would be a "call waiting" call or a regular ringing call. 43749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // If anybody consumed the broadcast, we'd bail out without 43849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // ringing or bringing up the in-call UI. 43949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // 44049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // This would give 3rd party apps a chance to listen for (and 44149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // intercept) new ringing connections. An app could reject the 44249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // incoming call by consuming the broadcast and doing nothing, or 44349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // it could "pick up" the call (without any action by the user!) 44475e3711d82d0c98444f6c438437cad41d862fca6David Brown // via some future TelephonyManager API. 44549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // 44675e3711d82d0c98444f6c438437cad41d862fca6David Brown // See bug 1312336 for more details. 44749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // We'd need to protect this with a new "intercept incoming calls" 44849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // system permission. 44949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 45049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // Obtain a partial wake lock to make sure the CPU doesn't go to 45149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // sleep before we finish bringing up the InCallScreen. 45249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // (This will be upgraded soon to a full wake lock; see 45349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // showIncomingCall().) 45449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (VDBG) log("Holding wake lock on new incoming connection."); 45549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown mApplication.requestWakeState(PhoneApp.WakeState.PARTIAL); 45649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown 45749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // - don't ring for call waiting connections 45849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // - do this before showing the incoming call panel 4598343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (PhoneUtils.isRealIncomingCall(state)) { 46049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown startIncomingCallQuery(c); 46149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown } else { 46249c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (VDBG) log("- starting call waiting tone..."); 46349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (mCallWaitingTonePlayer == null) { 46449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING); 46549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown mCallWaitingTonePlayer.start(); 466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 46749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // in this case, just fall through like before, and call 46849c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // showIncomingCall(). 46949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- showing incoming call (this is a WAITING call)..."); 47049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown showIncomingCall(); 471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 47349c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // Note we *don't* post a status bar notification here, since 47449c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // we're not necessarily ready to actually show the incoming call 47549c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // to the user. (For calls in the INCOMING state, at least, we 47649c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // still need to run a caller-id query, and we may not even ring 47749c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // at all if the "send directly to voicemail" flag is set.) 4784f76ebacc88f5c69608a7a4f258887fe2036c55dDavid Brown // 47949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // Instead, we update the notification (and potentially launch the 48049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // InCallScreen) from the showIncomingCall() method, which runs 48149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown // when the caller-id query completes or times out. 4824f76ebacc88f5c69608a7a4f258887fe2036c55dDavid Brown 483796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- onNewRingingConnection() done."); 484b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 486b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 487d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * Determines whether or not we're allowed to present incoming calls to the 488d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * user, based on the capabilities and/or current state of the device. 489d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * 490d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * If this method returns true, that means we should immediately reject the 491d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * current incoming call, without even indicating to the user that an 492d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * incoming call occurred. 493d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * 494d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * (We only reject incoming calls in a few cases, like during an OTASP call 495d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * when we can't interrupt the user, or if the device hasn't completed the 496d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * SetupWizard yet. We also don't allow incoming calls on non-voice-capable 497d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * devices. But note that we *always* allow incoming calls while in ECM.) 498d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * 499d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * @return true if we're *not* allowed to present an incoming call to 500d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown * the user. 501d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown */ 502d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown private boolean ignoreAllIncomingCalls(Phone phone) { 503d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Incoming calls are totally ignored on non-voice-capable devices. 504d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (!PhoneApp.sVoiceCapable) { 505d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // ...but still log a warning, since we shouldn't have gotten this 506d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // event in the first place! (Incoming calls *should* be blocked at 507d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // the telephony layer on non-voice-capable capable devices.) 508d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown Log.w(LOG_TAG, "Got onNewRingingConnection() on non-voice-capable device! Ignoring..."); 509d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return true; 510d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 511d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 512d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // In ECM (emergency callback mode), we ALWAYS allow incoming calls 513d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // to get through to the user. (Note that ECM is applicable only to 514d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // voice-capable CDMA devices). 515d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (PhoneUtils.isPhoneInEcm(phone)) { 516d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (DBG) log("Incoming call while in ECM: always allow..."); 517d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return false; 518d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 519d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 520d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Incoming calls are totally ignored if the device isn't provisioned yet. 521d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown boolean provisioned = Settings.Secure.getInt(mApplication.getContentResolver(), 522d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown Settings.Secure.DEVICE_PROVISIONED, 0) != 0; 523d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (!provisioned) { 524d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown Log.i(LOG_TAG, "Ignoring incoming call: not provisioned"); 525d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return true; 526d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 527d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 528d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Incoming calls are totally ignored if an OTASP call is active. 529d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (TelephonyCapabilities.supportsOtasp(phone)) { 530d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown boolean activateState = (mApplication.cdmaOtaScreenState.otaScreenState 531d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_ACTIVATION); 532d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown boolean dialogState = (mApplication.cdmaOtaScreenState.otaScreenState 533d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown == OtaUtils.CdmaOtaScreenState.OtaScreenState.OTA_STATUS_SUCCESS_FAILURE_DLG); 534d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown boolean spcState = mApplication.cdmaOtaProvisionData.inOtaSpcState; 535d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 536d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (spcState) { 537d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown Log.i(LOG_TAG, "Ignoring incoming call: OTA call is active"); 538d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return true; 539d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } else if (activateState || dialogState) { 540d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // We *are* allowed to receive incoming calls at this point. 541d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // But clear out any residual OTASP UI first. 542d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // TODO: It's an MVC violation to twiddle the OTA UI state here; 543d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // we should instead provide a higher-level API via OtaUtils. 544d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown if (dialogState) mApplication.dismissOtaDialogs(); 545d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown mApplication.clearOtaState(); 546d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown mApplication.clearInCallScreenMode(); 547d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return false; 548d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 549d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 550d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 551d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown // Normal case: allow this call to be presented to the user. 552d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown return false; 553d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown } 554d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown 555d250d5b223cfc053702b6ec06d90c79abd8ae8ffDavid Brown /** 556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Helper method to manage the start of incoming call queries 557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void startIncomingCallQuery(Connection c) { 559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: cache the custom ringer object so that subsequent 560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // calls will not need to do this query work. We can keep 561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the MRU ringtones in memory. We'll still need to hit 562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the database to get the callerinfo to act as a key, 563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // but at least we can save the time required for the 564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Media player setup. The only issue with this is that 565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we may need to keep an eye on the resources the Media 566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // player uses to keep these ringtones around. 567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // make sure we're in a state where we can be ready to 569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // query a ringtone uri. 570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean shouldStartQuery = false; 571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mCallerInfoQueryStateGuard) { 572b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mCallerInfoQueryState == CALLERINFO_QUERY_READY) { 573b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallerInfoQueryState = CALLERINFO_QUERYING; 574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project shouldStartQuery = true; 575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 576b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 577b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (shouldStartQuery) { 578b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // create a custom ringer using the default ringer first 579b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger.setCustomRingtoneUri(Settings.System.DEFAULT_RINGTONE_URI); 580b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 581b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // query the callerinfo to try to get the ringer. 582b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project PhoneUtils.CallerInfoToken cit = PhoneUtils.startGetCallerInfo( 583872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mApplication, c, this, this); 584b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 585b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if this has already been queried then just ring, otherwise 586b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we wait for the alloted time before ringing. 587b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cit.isFinal) { 588796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- CallerInfo already up to date, using available data"); 589b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onQueryComplete(0, this, cit.currentInfo); 590b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 591796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- Starting query, posting timeout message."); 592b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project sendEmptyMessageDelayed(RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT, 593b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project RINGTONE_QUERY_WAIT_TIME); 594b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 5957f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // The call to showIncomingCall() will happen after the 5967f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // queries are complete (or time out). 597b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 598b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This should never happen; its the case where an incoming call 599b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // arrives at the same time that the query is still being run, 600b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and before the timeout window has closed. 601cd89106dcd1038666f992cea3cc79e067245187fDan Egnor EventLog.writeEvent(EventLogTags.PHONE_UI_MULTIPLE_QUERY); 602b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 603b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // In this case, just log the request and ring. 604796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("RINGING... (request to ring arrived while query is running)"); 605b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger.ring(); 606b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 607b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in this case, just fall through like before, and call 6087f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // showIncomingCall(). 60949c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- showing incoming call (couldn't start query)..."); 6107f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown showIncomingCall(); 611b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 612b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 613b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 614b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 615b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Performs the final steps of the onNewRingingConnection sequence: 6167f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * starts the ringer, and brings up the "incoming call" UI. 617b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 618b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Normally, this is called when the CallerInfo query completes (see 619b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * onQueryComplete()). In this case, onQueryComplete() has already 620b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * configured the Ringer object to use the custom ringtone (if there 621b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * is one) for this caller. So we just tell the Ringer to start, and 622b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * proceed to the InCallScreen. 623b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 624b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * But this method can *also* be called if the 625b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * RINGTONE_QUERY_WAIT_TIME timeout expires, which means that the 626b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * CallerInfo query is taking too long. In that case, we log a 627b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * warning but otherwise we behave the same as in the normal case. 628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (We still tell the Ringer to start, but it's going to use the 629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * default ringtone.) 630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onCustomRingQueryComplete() { 632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isQueryExecutionTimeExpired = false; 633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mCallerInfoQueryStateGuard) { 634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mCallerInfoQueryState == CALLERINFO_QUERYING) { 635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallerInfoQueryState = CALLERINFO_QUERY_READY; 636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project isQueryExecutionTimeExpired = true; 637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isQueryExecutionTimeExpired) { 640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // There may be a problem with the query here, since the 641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // default ringtone is playing instead of the custom one. 642796c70c99bc39295bf685061056f06ab8949c742David Brown Log.w(LOG_TAG, "CallerInfo query took too long; falling back to default ringtone"); 643cd89106dcd1038666f992cea3cc79e067245187fDan Egnor EventLog.writeEvent(EventLogTags.PHONE_UI_RINGER_QUERY_ELAPSED); 644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Make sure we still have an incoming call! 647b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 648b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (It's possible for the incoming call to have been disconnected 649b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // while we were running the query. In that case we better not 650b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // start the ringer here, since there won't be any future 651b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // DISCONNECT event to stop it!) 652b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 653b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Note we don't have to worry about the incoming call going away 654b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // *after* this check but before we call mRinger.ring() below, 655b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // since in that case we *will* still get a DISCONNECT message sent 656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // to our handler. (And we will correctly stop the ringer when we 657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // process that event.) 658170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (mCM.getState() != Phone.State.RINGING) { 659796c70c99bc39295bf685061056f06ab8949c742David Brown Log.i(LOG_TAG, "onCustomRingQueryComplete: No incoming call! Bailing out..."); 660b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Don't start the ringer *or* bring up the "incoming call" UI. 661b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Just bail out. 662b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 663b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 664b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 665b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Ring, either with the queried ringtone or default one. 666796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("RINGING... (onCustomRingQueryComplete)"); 667b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger.ring(); 668b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6697f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // ...and display the incoming call to the user: 67049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- showing incoming call (custom ring query complete)..."); 6717f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown showIncomingCall(); 672b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 673b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 674b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onUnknownConnectionAppeared(AsyncResult r) { 675170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang Phone.State state = mCM.getState(); 676b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 677b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (state == Phone.State.OFFHOOK) { 6787f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // basically do onPhoneStateChanged + display the incoming call UI 679b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onPhoneStateChanged(r); 68049c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- showing incoming call (unknown connection appeared)..."); 6817f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown showIncomingCall(); 682b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 683b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 684b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 6857f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown /** 6867f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * Informs the user about a new incoming call. 6877f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * 6887f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * In most cases this means "bring up the full-screen incoming call 6897f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * UI". However, if an immersive activity is running, the system 6907f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * NotificationManager will instead pop up a small notification window 6917f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * on top of the activity. 6927f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * 6937f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * Watch out: be sure to call this method only once per incoming call, 6947f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * or otherwise we may end up launching the InCallScreen multiple 6957f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * times (which can lead to slow responsiveness and/or visible 6967f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * glitches.) 6977f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * 6987f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * Note this method handles only the onscreen UI for incoming calls; 6997f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * the ringer and/or vibrator are started separately (see the various 7007f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * calls to Ringer.ring() in this class.) 7017f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * 7020fcb3901bf032e722385489bd6488fef49371f16David Brown * @see NotificationMgr.updateNotificationAndLaunchIncomingCallUi() 7037f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown */ 7047f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown private void showIncomingCall() { 7054158ed3e7bdff5212a5542e662240ea0063664b2David Brown log("showIncomingCall()... phone state = " + mCM.getState()); 7067f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7077f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // Before bringing up the "incoming call" UI, force any system 7087f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // dialogs (like "recent tasks" or the power dialog) to close first. 7097f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown try { 7107f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown ActivityManagerNative.getDefault().closeSystemDialogs("call"); 7117f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown } catch (RemoteException e) { 7127f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown } 7137f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7147f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // Go directly to the in-call screen. 7157f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // (No need to do anything special if we're already on the in-call 7167f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // screen; it'll notice the phone state change and update itself.) 7177f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7187f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // But first, grab a full wake lock. We do this here, before we 7197f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // even fire off the InCallScreen intent, to make sure the 7207f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // ActivityManager doesn't try to pause the InCallScreen as soon 7217f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // as it comes up. (See bug 1648751.) 7227f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // 7237f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // And since the InCallScreen isn't visible yet (we haven't even 7247f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // fired off the intent yet), we DON'T want the screen to actually 7257f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // come on right now. So *before* acquiring the wake lock we need 7267f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // to call preventScreenOn(), which tells the PowerManager that 7277f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // the screen should stay off even if someone's holding a full 7287f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // wake lock. (This prevents any flicker during the "incoming 7297f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // call" sequence. The corresponding preventScreenOn(false) call 7307f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // will come from the InCallScreen when it's finally ready to be 7317f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // displayed.) 7327f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // 7337f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // TODO: this is all a temporary workaround. The real fix is to add 7347f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // an Activity attribute saying "this Activity wants to wake up the 7357f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // phone when it's displayed"; that way the ActivityManager could 7367f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // manage the wake locks *and* arrange for the screen to come on at 7377f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // the exact moment that the InCallScreen is ready to be displayed. 7387f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // (See bug 1648751.) 7397f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // 7407f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // TODO: also, we should probably *not* do any of this if the 7417f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // screen is already on(!) 7427f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7437f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown mApplication.preventScreenOn(true); 7447f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown mApplication.requestWakeState(PhoneApp.WakeState.FULL); 7457f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7460fcb3901bf032e722385489bd6488fef49371f16David Brown // Post the "incoming call" notification *and* include the 7470fcb3901bf032e722385489bd6488fef49371f16David Brown // fullScreenIntent that'll launch the incoming-call UI. 7480fcb3901bf032e722385489bd6488fef49371f16David Brown // (This will usually take us straight to the incoming call 7490fcb3901bf032e722385489bd6488fef49371f16David Brown // screen, but if an immersive activity is running it'll just 7500fcb3901bf032e722385489bd6488fef49371f16David Brown // appear as a notification.) 75149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- updating notification from showIncomingCall()..."); 752df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateNotificationAndLaunchIncomingCallUi(); 7537f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown } 7547f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown 7557f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown /** 7567f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * Updates the phone UI in response to phone state changes. 7577f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * 7587f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * Watch out: certain state changes are actually handled by their own 7597f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * specific methods: 7607f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * - see onNewRingingConnection() for new incoming calls 7617f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown * - see onDisconnect() for calls being hung up or disconnected 7627f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown */ 763b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onPhoneStateChanged(AsyncResult r) { 764170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang Phone.State state = mCM.getState(); 765f0f6d973992a988c0fc801ba80f826c8edf02c03David Brown if (VDBG) log("onPhoneStateChanged: state = " + state); 766b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 767b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Turn status bar notifications on or off depending upon the state 768b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // of the phone. Notification Alerts (audible or vibrating) should 769b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // be on if and only if the phone is IDLE. 770df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.statusBarHelper 771b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project .enableNotificationAlerts(state == Phone.State.IDLE); 772b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 773872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan Phone fgPhone = mCM.getFgPhone(); 774872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (fgPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 775872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if ((fgPhone.getForegroundCall().getState() == Call.State.ACTIVE) 7763800ac871d6548790ac6119bb68b9be0640af261David Krause && ((mPreviousCdmaCallState == Call.State.DIALING) 7773800ac871d6548790ac6119bb68b9be0640af261David Krause || (mPreviousCdmaCallState == Call.State.ALERTING))) { 7783800ac871d6548790ac6119bb68b9be0640af261David Krause if (mIsCdmaRedialCall) { 7793800ac871d6548790ac6119bb68b9be0640af261David Krause int toneToPlay = InCallTonePlayer.TONE_REDIAL; 7803800ac871d6548790ac6119bb68b9be0640af261David Krause new InCallTonePlayer(toneToPlay).start(); 7813800ac871d6548790ac6119bb68b9be0640af261David Krause } 7823bd6c8e98772c43c237e9752b33e54f3ce13fb85BinaPatel // Stop any signal info tone when call moves to ACTIVE state 7833bd6c8e98772c43c237e9752b33e54f3ce13fb85BinaPatel stopSignalInfoTone(); 7843800ac871d6548790ac6119bb68b9be0640af261David Krause } 785872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mPreviousCdmaCallState = fgPhone.getForegroundCall().getState(); 7863800ac871d6548790ac6119bb68b9be0640af261David Krause } 7873800ac871d6548790ac6119bb68b9be0640af261David Krause 7888bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // Have the PhoneApp recompute its mShowBluetoothIndication 7898bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project // flag based on the (new) telephony state. 7904b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project // There's no need to force a UI update since we update the 7914b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project // in-call notification ourselves (below), and the InCallScreen 7924b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project // listens for phone state changes itself. 7934b8337277ec2e375c3536b97c40e6617a7b12990The Android Open Source Project mApplication.updateBluetoothIndication(false); 7948bb467d9a1106dedd79e42166c7b6e9fc9a897a7The Android Open Source Project 79558de0c5d10bbf48f6316a12495cd1c176a11a6feDavid Brown // Update the proximity sensor mode (on devices that have a 79658de0c5d10bbf48f6316a12495cd1c176a11a6feDavid Brown // proximity sensor). 797445c9030dc93750a8209ace086ea3820ee33f0b1Mike Lockwood mApplication.updatePhoneState(state); 79858de0c5d10bbf48f6316a12495cd1c176a11a6feDavid Brown 799b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (state == Phone.State.OFFHOOK) { 80003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // stop call waiting tone if needed when answering 80103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (mCallWaitingTonePlayer != null) { 80203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mCallWaitingTonePlayer.stopTone(); 80303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mCallWaitingTonePlayer = null; 80403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 80503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 806796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onPhoneStateChanged: OFF HOOK"); 807a4b443115c1442c9d65ba58fcb667b0e025993deHung-ying Tyan // make sure audio is in in-call mode now 808a4b443115c1442c9d65ba58fcb667b0e025993deHung-ying Tyan PhoneUtils.setAudioMode(mCM); 809b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 810b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if the call screen is showing, let it handle the event, 811b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // otherwise handle it here. 812b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mApplication.isShowingCallScreen()) { 813b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication.setScreenTimeout(PhoneApp.ScreenTimeoutDuration.DEFAULT); 814b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication.requestWakeState(PhoneApp.WakeState.SLEEP); 815b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 816b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 817b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Since we're now in-call, the Ringer should definitely *not* 818b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // be ringing any more. (This is just a sanity-check; we 819b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // already stopped the ringer explicitly back in 820b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // PhoneUtils.answerCall(), before the call to phone.acceptCall().) 821b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: Confirm that this call really *is* unnecessary, and if so, 822b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // remove it! 823b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("stopRing()... (OFFHOOK state)"); 824b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger.stopRing(); 825b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 826e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // Post a request to update the "in-call" status bar icon. 827e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // 828e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // We don't call NotificationMgr.updateInCallNotification() 829e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // directly here, for two reasons: 830e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // (1) a single phone state change might actually trigger multiple 831e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // onPhoneStateChanged() callbacks, so this prevents redundant 832e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // updates of the notification. 833e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // (2) we suppress the status bar icon while the in-call UI is 834e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // visible (see updateInCallNotification()). But when launching 835e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // an outgoing call the phone actually goes OFFHOOK slightly 836e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // *before* the InCallScreen comes up, so the delay here avoids a 837e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // brief flicker of the icon at that point. 838e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown 839e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown if (DBG) log("- posting UPDATE_IN_CALL_NOTIFICATION request..."); 840e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown // Remove any previous requests in the queue 841e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown removeMessages(UPDATE_IN_CALL_NOTIFICATION); 842e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown final int IN_CALL_NOTIFICATION_UPDATE_DELAY = 1000; // msec 843e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown sendEmptyMessageDelayed(UPDATE_IN_CALL_NOTIFICATION, 844e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown IN_CALL_NOTIFICATION_UPDATE_DELAY); 845b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 846678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 847872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (fgPhone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 848872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan Connection c = fgPhone.getForegroundCall().getLatestConnection(); 8491ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia if ((c != null) && (PhoneNumberUtils.isLocalEmergencyNumber(c.getAddress(), 8501ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia mApplication))) { 851678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (VDBG) log("onPhoneStateChanged: it is an emergency call."); 852872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan Call.State callState = fgPhone.getForegroundCall().getState(); 853678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mEmergencyTonePlayerVibrator == null) { 854678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmergencyTonePlayerVibrator = new EmergencyTonePlayerVibrator(); 855678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 856678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 857678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (callState == Call.State.DIALING || callState == Call.State.ALERTING) { 858678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mIsEmergencyToneOn = Settings.System.getInt( 859872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mApplication.getContentResolver(), 860678d72446de9c185c767206338f5fb199e0cd845Peng Zhu Settings.System.EMERGENCY_TONE, EMERGENCY_TONE_OFF); 861678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mIsEmergencyToneOn != EMERGENCY_TONE_OFF && 862678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mCurrentEmergencyToneState == EMERGENCY_TONE_OFF) { 863678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mEmergencyTonePlayerVibrator != null) { 864678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmergencyTonePlayerVibrator.start(); 865678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 866678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 867678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } else if (callState == Call.State.ACTIVE) { 868678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF) { 869678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mEmergencyTonePlayerVibrator != null) { 870678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmergencyTonePlayerVibrator.stop(); 871678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 872678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 873678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 874678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 875678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 876eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 877872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if ((fgPhone.getPhoneType() == Phone.PHONE_TYPE_GSM) 878872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (fgPhone.getPhoneType() == Phone.PHONE_TYPE_SIP)) { 879170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang Call.State callState = mCM.getActiveFgCallState(); 880eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang if (!callState.isDialing()) { 881eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // If call get activated or disconnected before the ringback 882eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // tone stops, we have to stop it to prevent disturbing. 88303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (mInCallRingbackTonePlayer != null) { 88403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer.stopTone(); 88503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer = null; 886eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 887eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 888eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 889b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 890b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 891a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville void updateCallNotifierRegistrationsAfterRadioTechnologyChange() { 89287258b2b589c3afea4b89b840251012378e0d3b4David Brown if (DBG) Log.d(LOG_TAG, "updateCallNotifierRegistrationsAfterRadioTechnologyChange..."); 89387258b2b589c3afea4b89b840251012378e0d3b4David Brown // Unregister all events from the old obsolete phone 894170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForNewRingingConnection(this); 895170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForPreciseCallStateChanged(this); 896170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForDisconnect(this); 897170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForUnknownConnection(this); 898170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForIncomingRing(this); 899170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForCallWaiting(this); 900170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForDisplayInfo(this); 901170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForSignalInfo(this); 902170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForCdmaOtaStatusChange(this); 903170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForRingbackTone(this); 904170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForResendIncallMute(this); 9050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 90687258b2b589c3afea4b89b840251012378e0d3b4David Brown // Release the ToneGenerator used for playing SignalInfo and CallWaiting 9070fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (mSignalInfoToneGenerator != null) { 9080fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mSignalInfoToneGenerator.release(); 9090fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 910a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville 911eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // Clear ringback tone player 912eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang mInCallRingbackTonePlayer = null; 913eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 91403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // Clear call waiting tone player 91503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mCallWaitingTonePlayer = null; 91603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 917170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForInCallVoicePrivacyOn(this); 918170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.unregisterForInCallVoicePrivacyOff(this); 9193800ac871d6548790ac6119bb68b9be0640af261David Krause 92087258b2b589c3afea4b89b840251012378e0d3b4David Brown // Register all events new to the new active phone 92124f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon registerForNotifications(); 92224f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon } 92324f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon 92424f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon private void registerForNotifications() { 925170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null); 926170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForPreciseCallStateChanged(this, PHONE_STATE_CHANGED, null); 927170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForDisconnect(this, PHONE_DISCONNECT, null); 928170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForUnknownConnection(this, PHONE_UNKNOWN_CONNECTION_APPEARED, null); 929170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForIncomingRing(this, PHONE_INCOMING_RING, null); 93034b17481486fc41e99627d68dda9b5c075b4cc8eJohn Wang mCM.registerForCdmaOtaStatusChange(this, EVENT_OTA_PROVISION_CHANGE, null); 931170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForCallWaiting(this, PHONE_CDMA_CALL_WAITING, null); 932170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForDisplayInfo(this, PHONE_STATE_DISPLAYINFO, null); 933170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForSignalInfo(this, PHONE_STATE_SIGNALINFO, null); 934170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForInCallVoicePrivacyOn(this, PHONE_ENHANCED_VP_ON, null); 935170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForInCallVoicePrivacyOff(this, PHONE_ENHANCED_VP_OFF, null); 936170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForRingbackTone(this, PHONE_RINGBACK_TONE, null); 937170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang mCM.registerForResendIncallMute(this, PHONE_RESEND_MUTE, null); 938a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville } 939a69de9f9a2e99fe08f0009bb218b95ed7985c575Wink Saville 940b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 941b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Implemented for CallerInfoAsyncQuery.OnQueryCompleteListener interface. 942b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * refreshes the CallCard data when it called. If called with this 943b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * class itself, it is assumed that we have been waiting for the ringtone 944b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * and direct to voicemail settings to update. 945b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 94605fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu public void onQueryComplete(int token, Object cookie, CallerInfo ci) { 947b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cookie instanceof Long) { 948796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("CallerInfo query complete, posting missed call notification"); 949b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 950df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.notifyMissedCall(ci.name, ci.phoneNumber, 951b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ci.phoneLabel, ((Long) cookie).longValue()); 95205fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu } else if (cookie instanceof CallNotifier) { 9534f76ebacc88f5c69608a7a4f258887fe2036c55dDavid Brown if (VDBG) log("CallerInfo query complete (for CallNotifier), " 9544f76ebacc88f5c69608a7a4f258887fe2036c55dDavid Brown + "updating state for incoming call.."); 955b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 956b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // get rid of the timeout messages 957b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project removeMessages(RINGER_CUSTOM_RINGTONE_QUERY_TIMEOUT); 958b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 959b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isQueryExecutionTimeOK = false; 960b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project synchronized (mCallerInfoQueryStateGuard) { 961b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mCallerInfoQueryState == CALLERINFO_QUERYING) { 962b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mCallerInfoQueryState = CALLERINFO_QUERY_READY; 963b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project isQueryExecutionTimeOK = true; 964b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 965b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 966b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project //if we're in the right state 967b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (isQueryExecutionTimeOK) { 968b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 969b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // send directly to voicemail. 970b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci.shouldSendToVoicemail) { 971b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("send to voicemail flag detected. hanging up."); 972872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall()); 973b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return; 974b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 975b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 976b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // set the ringtone uri to prepare for the ring. 977b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (ci.contactRingtoneUri != null) { 978b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("custom ringtone found, setting up ringer."); 979b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Ringer r = ((CallNotifier) cookie).mRinger; 980b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project r.setCustomRingtoneUri(ci.contactRingtoneUri); 981b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 982b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ring, and other post-ring actions. 983b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project onCustomRingQueryComplete(); 984b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 985b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 986b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 987b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 988b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onDisconnect(AsyncResult r) { 989170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (VDBG) log("onDisconnect()... CallManager state: " + mCM.getState()); 9903800ac871d6548790ac6119bb68b9be0640af261David Krause 99124f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon mVoicePrivacyState = false; 992872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan Connection c = (Connection) r.result; 993cf8455a03fe74cc46b2b5d1cc2ceb0c7a48d28e7David Brown if (c != null) { 9944158ed3e7bdff5212a5542e662240ea0063664b2David Brown log("onDisconnect: cause = " + c.getDisconnectCause() 995cf8455a03fe74cc46b2b5d1cc2ceb0c7a48d28e7David Brown + ", incoming = " + c.isIncoming() 996cf8455a03fe74cc46b2b5d1cc2ceb0c7a48d28e7David Brown + ", date = " + c.getCreateTime()); 997cf8455a03fe74cc46b2b5d1cc2ceb0c7a48d28e7David Brown } else { 998cf8455a03fe74cc46b2b5d1cc2ceb0c7a48d28e7David Brown Log.w(LOG_TAG, "onDisconnect: null connection"); 999872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } 1000872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan 10013800ac871d6548790ac6119bb68b9be0640af261David Krause int autoretrySetting = 0; 1002872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if ((c != null) && (c.getCall().getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA)) { 1003872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan autoretrySetting = android.provider.Settings.System.getInt(mApplication. 10043800ac871d6548790ac6119bb68b9be0640af261David Krause getContentResolver(),android.provider.Settings.System.CALL_AUTO_RETRY, 0); 10053800ac871d6548790ac6119bb68b9be0640af261David Krause } 10063800ac871d6548790ac6119bb68b9be0640af261David Krause 100724f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon // Stop any signalInfo tone being played when a call gets ended 100824f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon stopSignalInfoTone(); 100991fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai 1010feac731f603c89ca88c294814f067dfe4b9b5f79David Brown if ((c != null) && (c.getCall().getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA)) { 101191fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai // Resetting the CdmaPhoneCallState members 101291fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState(); 101391fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai 101491fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai // Remove Call waiting timers 101591fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 101691fc9257191eadb9f2d0a7792ad78cf51f2f36dfAbhishek Pillai removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT); 10170fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 10180fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1019b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Stop the ringer if it was ringing (for an incoming call that 1020b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // either disconnected by itself, or was rejected by the user.) 1021b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1022b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: We technically *shouldn't* stop the ringer if the 1023b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // foreground or background call disconnects while an incoming call 1024b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // is still ringing, but that's a really rare corner case. 1025b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // It's safest to just unconditionally stop the ringer here. 1026cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai 1027cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // CDMA: For Call collision cases i.e. when the user makes an out going call 1028cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // and at the same time receives an Incoming Call, the Incoming Call is given 1029cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // higher preference. At this time framework sends a disconnect for the Out going 1030cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // call connection hence we should *not* be stopping the ringer being played for 1031cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // the Incoming Call 1032872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan Call ringingCall = mCM.getFirstActiveRingingCall(); 1033872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (ringingCall.getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA) { 1034872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (PhoneUtils.isRealIncomingCall(ringingCall.getState())) { 1035cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // Also we need to take off the "In Call" icon from the Notification 1036cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai // area as the Out going Call never got connected 1037e08c8e4cbee3b2434f9222394ac0dafd13009effDavid Brown if (DBG) log("cancelCallInProgressNotifications()... (onDisconnect)"); 1038df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.cancelCallInProgressNotifications(); 1039cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } else { 1040cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai if (DBG) log("stopRing()... (onDisconnect)"); 1041cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai mRinger.stopRing(); 1042cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } 1043cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } else { // GSM 1044cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai if (DBG) log("stopRing()... (onDisconnect)"); 1045cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai mRinger.stopRing(); 1046cbab175f33bad5c132c14c6f5a10d4cdd7111d70Abhishek Pillai } 1047b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 104803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // stop call waiting tone if needed when disconnecting 104903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (mCallWaitingTonePlayer != null) { 105003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mCallWaitingTonePlayer.stopTone(); 105103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mCallWaitingTonePlayer = null; 105203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 105303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 1054b154630235935e1aab2a41eff9ed794d40084a02David Brown // If this is the end of an OTASP call, pass it on to the PhoneApp. 105502a86291ed297ab1700daf004f515ee9614689abHung-ying Tyan if (c != null && TelephonyCapabilities.supportsOtasp(c.getCall().getPhone())) { 1056b154630235935e1aab2a41eff9ed794d40084a02David Brown final String number = c.getAddress(); 105702a86291ed297ab1700daf004f515ee9614689abHung-ying Tyan if (c.getCall().getPhone().isOtaSpNumber(number)) { 1058b154630235935e1aab2a41eff9ed794d40084a02David Brown if (DBG) log("onDisconnect: this was an OTASP call!"); 1059b154630235935e1aab2a41eff9ed794d40084a02David Brown mApplication.handleOtaspDisconnect(); 1060b154630235935e1aab2a41eff9ed794d40084a02David Brown } 1061b154630235935e1aab2a41eff9ed794d40084a02David Brown } 1062b154630235935e1aab2a41eff9ed794d40084a02David Brown 1063b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Check for the various tones we might need to play (thru the 1064b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // earpiece) after a call disconnects. 1065b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int toneToPlay = InCallTonePlayer.TONE_NONE; 1066b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1067b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The "Busy" or "Congestion" tone is the highest priority: 1068b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 1069b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 1070b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (cause == Connection.DisconnectCause.BUSY) { 1071b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- need to play BUSY tone!"); 1072b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneToPlay = InCallTonePlayer.TONE_BUSY; 1073b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else if (cause == Connection.DisconnectCause.CONGESTION) { 1074b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("- need to play CONGESTION tone!"); 1075b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneToPlay = InCallTonePlayer.TONE_CONGESTION; 1076af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } else if (((cause == Connection.DisconnectCause.NORMAL) 1077af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville || (cause == Connection.DisconnectCause.LOCAL)) 1078af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville && (mApplication.isOtaCallInActiveState())) { 1079af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (DBG) log("- need to play OTA_CALL_END tone!"); 1080af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville toneToPlay = InCallTonePlayer.TONE_OTA_CALL_END; 10813800ac871d6548790ac6119bb68b9be0640af261David Krause } else if (cause == Connection.DisconnectCause.CDMA_REORDER) { 10823800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("- need to play CDMA_REORDER tone!"); 10833800ac871d6548790ac6119bb68b9be0640af261David Krause toneToPlay = InCallTonePlayer.TONE_REORDER; 10843800ac871d6548790ac6119bb68b9be0640af261David Krause } else if (cause == Connection.DisconnectCause.CDMA_INTERCEPT) { 10853800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("- need to play CDMA_INTERCEPT tone!"); 10863800ac871d6548790ac6119bb68b9be0640af261David Krause toneToPlay = InCallTonePlayer.TONE_INTERCEPT; 10873800ac871d6548790ac6119bb68b9be0640af261David Krause } else if (cause == Connection.DisconnectCause.CDMA_DROP) { 10883800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("- need to play CDMA_DROP tone!"); 10893800ac871d6548790ac6119bb68b9be0640af261David Krause toneToPlay = InCallTonePlayer.TONE_CDMA_DROP; 10903800ac871d6548790ac6119bb68b9be0640af261David Krause } else if (cause == Connection.DisconnectCause.OUT_OF_SERVICE) { 10913800ac871d6548790ac6119bb68b9be0640af261David Krause if (DBG) log("- need to play OUT OF SERVICE tone!"); 10923800ac871d6548790ac6119bb68b9be0640af261David Krause toneToPlay = InCallTonePlayer.TONE_OUT_OF_SERVICE; 10939eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla } else if (cause == Connection.DisconnectCause.UNOBTAINABLE_NUMBER) { 10949eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla if (DBG) log("- need to play TONE_UNOBTAINABLE_NUMBER tone!"); 10959eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla toneToPlay = InCallTonePlayer.TONE_UNOBTAINABLE_NUMBER; 1096eae268799f7ca0ad09d5d24093d84bc93c1ab050Peng Zhu } else if (cause == Connection.DisconnectCause.ERROR_UNSPECIFIED) { 1097eae268799f7ca0ad09d5d24093d84bc93c1ab050Peng Zhu if (DBG) log("- DisconnectCause is ERROR_UNSPECIFIED: play TONE_CALL_ENDED!"); 1098eae268799f7ca0ad09d5d24093d84bc93c1ab050Peng Zhu toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; 1099b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1100b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1101b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1102b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If we don't need to play BUSY or CONGESTION, then play the 1103b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "call ended" tone if this was a "regular disconnect" (i.e. a 1104b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // normal call where one end or the other hung up) *and* this 1105b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // disconnect event caused the phone to become idle. (In other 1106b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // words, we *don't* play the sound if one call hangs up but 1107b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // there's still an active call on the other line.) 1108b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: We may eventually want to disable this via a preference. 1109b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((toneToPlay == InCallTonePlayer.TONE_NONE) 1110170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang && (mCM.getState() == Phone.State.IDLE) 1111b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project && (c != null)) { 1112b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Connection.DisconnectCause cause = c.getDisconnectCause(); 1113b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if ((cause == Connection.DisconnectCause.NORMAL) // remote hangup 1114b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project || (cause == Connection.DisconnectCause.LOCAL)) { // local hangup 1115796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- need to play CALL_ENDED tone!"); 1116b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneToPlay = InCallTonePlayer.TONE_CALL_ENDED; 11173800ac871d6548790ac6119bb68b9be0640af261David Krause mIsCdmaRedialCall = false; 1118b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1119b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1120b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1121170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (mCM.getState() == Phone.State.IDLE) { 1122b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Don't reset the audio mode or bluetooth/speakerphone state 1123b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if we still need to let the user hear a tone through the earpiece. 1124b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (toneToPlay == InCallTonePlayer.TONE_NONE) { 1125b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resetAudioStateAfterDisconnect(); 1126b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1127b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1128df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.cancelCallInProgressNotifications(); 1129b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1130b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the InCallScreen is *not* in the foreground, forcibly 1131b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // dismiss it to make sure it won't still be in the activity 1132b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // history. (But if it *is* in the foreground, don't mess 1133b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // with it; it needs to be visible, displaying the "Call 1134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ended" state.) 1135b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mApplication.isShowingCallScreen()) { 1136796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onDisconnect: force InCallScreen to finish()"); 1137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication.dismissCallScreen(); 11386d6523c51e68ddfd1140713ddd9cb279499e9f4fJoe Onorato } else { 11396d6523c51e68ddfd1140713ddd9cb279499e9f4fJoe Onorato if (VDBG) log("onDisconnect: In call screen. Set short timeout."); 11406d6523c51e68ddfd1140713ddd9cb279499e9f4fJoe Onorato mApplication.clearUserActivityTimeout(); 1141b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1142b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1143b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1144b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c != null) { 114540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania final String number = c.getAddress(); 1146b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final long date = c.getCreateTime(); 1147b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final long duration = c.getDurationMillis(); 1148b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final Connection.DisconnectCause cause = c.getDisconnectCause(); 1149872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan final Phone phone = c.getCall().getPhone(); 11501ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia final boolean isEmergencyNumber = 11511ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia PhoneNumberUtils.isLocalEmergencyNumber(number, mApplication); 1152b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Set the "type" to be displayed in the call log (see constants in CallLog.Calls) 1153b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project final int callLogType; 1154b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (c.isIncoming()) { 1155b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project callLogType = (cause == Connection.DisconnectCause.INCOMING_MISSED ? 115611aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania Calls.MISSED_TYPE : Calls.INCOMING_TYPE); 1157b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 115811aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania callLogType = Calls.OUTGOING_TYPE; 1159b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1160796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- callLogType: " + callLogType + ", UserData: " + c.getUserData()); 1161b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 116240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 1163b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project { 116440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania final CallerInfo ci = getCallerInfoFromConnection(c); // May be null. 116540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania final String logNumber = getLogNumber(c, ci); 116640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 11676323823dec8d1fde89c7450e57a9ffe733a0b053Wink Saville if (DBG) log("- onDisconnect(): logNumber set to: " + /*logNumber*/ "xxxxxxx"); 1168b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 116940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania // TODO: In getLogNumber we use the presentation from 117040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania // the connection for the CNAP. Should we use the one 117140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania // below instead? (comes from caller info) 1172153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman 1173153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman // For international calls, 011 needs to be logged as + 117440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania final int presentation = getPresentation(c, ci); 1175153e79d8d413b1ccd4abf55a8dbe4e266aa92799Paul Berman 1176872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (phone.getPhoneType() == Phone.PHONE_TYPE_CDMA) { 11771ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia if ((isEmergencyNumber) 1178678d72446de9c185c767206338f5fb199e0cd845Peng Zhu && (mCurrentEmergencyToneState != EMERGENCY_TONE_OFF)) { 1179678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mEmergencyTonePlayerVibrator != null) { 1180678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmergencyTonePlayerVibrator.stop(); 1181678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1182678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1183678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 118440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 118535e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // On some devices, to avoid accidental redialing of 118635e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // emergency numbers, we *never* log emergency calls to 118735e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // the Call Log. (This behavior is set on a per-product 118835e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // basis, based on carrier requirements.) 118935e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown final boolean okToLogEmergencyNumber = 119035e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown mApplication.getResources().getBoolean( 119135e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown R.bool.allow_emergency_numbers_in_call_log); 119235e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown 119335e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // Don't call isOtaSpNumber() on phones that don't support OTASP. 11941b4455031a45a9b87cf66b3384ce59287500a448Hung-ying Tyan final boolean isOtaspNumber = TelephonyCapabilities.supportsOtasp(phone) 1195872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan && phone.isOtaSpNumber(number); 119674cae90ddb7fe8ce9bc0bc56e4c1fe4daf98e2d1Nicolas Catania 119735e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // Don't log emergency numbers if the device doesn't allow it, 119835e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown // and never log OTASP calls. 119935e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown final boolean okToLogThisCall = 120035e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown (!isEmergencyNumber || okToLogEmergencyNumber) 120135e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown && !isOtaspNumber; 120235e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown 120335e980f12cef04fc5c72b1ee87556503ceeeb21eDavid Brown if (okToLogThisCall) { 120411aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania CallLogAsync.AddCallArgs args = 120511aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania new CallLogAsync.AddCallArgs( 1206872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mApplication, ci, logNumber, presentation, 120711aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania callLogType, date, duration); 120811aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania mCallLog.addCall(args); 120940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 1210b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1211b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 121211aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania if (callLogType == Calls.MISSED_TYPE) { 1213b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Show the "Missed call" notification. 1214b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (Note we *don't* do this if this was an incoming call that 1215b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the user deliberately rejected.) 1216c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman showMissedCallNotification(c, date); 1217b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1218b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1219b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Possibly play a "post-disconnect tone" thru the earpiece. 1220b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // We do this here, rather than from the InCallScreen 1221b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // activity, since we need to do this even if you're not in 1222b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the Phone UI at the moment the connection ends. 1223b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (toneToPlay != InCallTonePlayer.TONE_NONE) { 1224796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- starting post-disconnect tone (" + toneToPlay + ")..."); 1225b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project new InCallTonePlayer(toneToPlay).start(); 1226b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1227b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: alternatively, we could start an InCallTonePlayer 1228b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // here with an "unlimited" tone length, 1229b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and manually stop it later when this connection truly goes 1230b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // away. (The real connection over the network was closed as soon 1231b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // as we got the BUSY message. But our telephony layer keeps the 1232b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // connection open for a few extra seconds so we can show the 1233b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "busy" indication to the user. We could stop the busy tone 1234b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // when *that* connection's "disconnect" event comes in.) 1235b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1236b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1237170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (mCM.getState() == Phone.State.IDLE) { 1238b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Release screen wake locks if the in-call screen is not 1239b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // showing. Otherwise, let the in-call screen handle this because 1240b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // it needs to show the call ended screen for a couple of 1241b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // seconds. 1242b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (!mApplication.isShowingCallScreen()) { 1243796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- NOT showing in-call screen; releasing wake locks!"); 1244b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication.setScreenTimeout(PhoneApp.ScreenTimeoutDuration.DEFAULT); 1245b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mApplication.requestWakeState(PhoneApp.WakeState.SLEEP); 1246b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1247796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- still showing in-call screen; not releasing wake locks."); 1248b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1249b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1250796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("- phone still in use; not releasing wake locks."); 1251b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 12523800ac871d6548790ac6119bb68b9be0640af261David Krause 12533800ac871d6548790ac6119bb68b9be0640af261David Krause if (((mPreviousCdmaCallState == Call.State.DIALING) 12543800ac871d6548790ac6119bb68b9be0640af261David Krause || (mPreviousCdmaCallState == Call.State.ALERTING)) 12551ca2b2b333a7c22b728d648d3592ee064762dd00Shaopeng Jia && (!isEmergencyNumber) 12563800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.INCOMING_MISSED ) 12573800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.NORMAL) 12583800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.LOCAL) 12593800ac871d6548790ac6119bb68b9be0640af261David Krause && (cause != Connection.DisconnectCause.INCOMING_REJECTED)) { 12603800ac871d6548790ac6119bb68b9be0640af261David Krause if (!mIsCdmaRedialCall) { 12613800ac871d6548790ac6119bb68b9be0640af261David Krause if (autoretrySetting == InCallScreen.AUTO_RETRY_ON) { 12623800ac871d6548790ac6119bb68b9be0640af261David Krause // TODO: (Moto): The contact reference data may need to be stored and use 12633800ac871d6548790ac6119bb68b9be0640af261David Krause // here when redialing a call. For now, pass in NULL as the URI parameter. 12641b4455031a45a9b87cf66b3384ce59287500a448Hung-ying Tyan PhoneUtils.placeCall(mApplication, phone, number, null, false, null); 12653800ac871d6548790ac6119bb68b9be0640af261David Krause mIsCdmaRedialCall = true; 12663800ac871d6548790ac6119bb68b9be0640af261David Krause } else { 12673800ac871d6548790ac6119bb68b9be0640af261David Krause mIsCdmaRedialCall = false; 12683800ac871d6548790ac6119bb68b9be0640af261David Krause } 12693800ac871d6548790ac6119bb68b9be0640af261David Krause } else { 12703800ac871d6548790ac6119bb68b9be0640af261David Krause mIsCdmaRedialCall = false; 12713800ac871d6548790ac6119bb68b9be0640af261David Krause } 12723800ac871d6548790ac6119bb68b9be0640af261David Krause } 1273b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1274b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1275b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1276b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1277b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Resets the audio mode and speaker state when a call ends. 1278b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1279b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void resetAudioStateAfterDisconnect() { 1280796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("resetAudioStateAfterDisconnect()..."); 1281b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1282b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mBluetoothHandsfree != null) { 1283b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mBluetoothHandsfree.audioOff(); 1284b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1285b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 12864a8cbde060e7876a5560346215c11078a9efc90eEric Laurent // call turnOnSpeaker() with state=false and store=true even if speaker 12874a8cbde060e7876a5560346215c11078a9efc90eEric Laurent // is already off to reset user requested speaker state. 1288872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan PhoneUtils.turnOnSpeaker(mApplication, false, true); 1289b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1290a4b443115c1442c9d65ba58fcb667b0e025993deHung-ying Tyan PhoneUtils.setAudioMode(mCM); 1291b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1292b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1293b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onMwiChanged(boolean visible) { 1294796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onMwiChanged(): " + visible); 1295feac731f603c89ca88c294814f067dfe4b9b5f79David Brown 1296feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // "Voicemail" is meaningless on non-voice-capable devices, 1297feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // so ignore MWI events. 1298feac731f603c89ca88c294814f067dfe4b9b5f79David Brown if (!PhoneApp.sVoiceCapable) { 1299feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // ...but still log a warning, since we shouldn't have gotten this 1300feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // event in the first place! 1301feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // (PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR events 1302feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // *should* be blocked at the telephony layer on non-voice-capable 1303feac731f603c89ca88c294814f067dfe4b9b5f79David Brown // capable devices.) 1304feac731f603c89ca88c294814f067dfe4b9b5f79David Brown Log.w(LOG_TAG, "Got onMwiChanged() on non-voice-capable device! Ignoring..."); 1305feac731f603c89ca88c294814f067dfe4b9b5f79David Brown return; 1306feac731f603c89ca88c294814f067dfe4b9b5f79David Brown } 1307feac731f603c89ca88c294814f067dfe4b9b5f79David Brown 1308df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateMwi(visible); 1309b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1310b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1311b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1312b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Posts a delayed PHONE_MWI_CHANGED event, to schedule a "retry" for a 1313b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * failed NotificationMgr.updateMwi() call. 1314b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1315b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void sendMwiChangedDelayed(long delayMillis) { 1316b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Message message = Message.obtain(this, PHONE_MWI_CHANGED); 1317b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project sendMessageDelayed(message, delayMillis); 1318b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1319b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1320b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onCfiChanged(boolean visible) { 1321796c70c99bc39295bf685061056f06ab8949c742David Brown if (VDBG) log("onCfiChanged(): " + visible); 1322df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.updateCfi(visible); 1323b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1324b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1325b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1326b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Indicates whether or not this ringer is ringing. 1327b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1328b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project boolean isRinging() { 1329b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project return mRinger.isRinging(); 1330b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1331b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1332b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1333b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Stops the current ring, and tells the notifier that future 1334b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * ring requests should be ignored. 1335b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1336b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project void silenceRinger() { 1337b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mSilentRingerRequested = true; 1338b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("stopRing()... (silenceRinger)"); 1339b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mRinger.stopRing(); 1340b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1341b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1342b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 134311544975bb29ede282333209e945a75430b221a8David Brown * Restarts the ringer after having previously silenced it. 134411544975bb29ede282333209e945a75430b221a8David Brown * 134511544975bb29ede282333209e945a75430b221a8David Brown * (This is a no-op if the ringer is actually still ringing, or if the 134611544975bb29ede282333209e945a75430b221a8David Brown * incoming ringing call no longer exists.) 134711544975bb29ede282333209e945a75430b221a8David Brown */ 134811544975bb29ede282333209e945a75430b221a8David Brown /* package */ void restartRinger() { 134911544975bb29ede282333209e945a75430b221a8David Brown if (DBG) log("restartRinger()..."); 135011544975bb29ede282333209e945a75430b221a8David Brown if (isRinging()) return; // Already ringing; no need to restart. 135111544975bb29ede282333209e945a75430b221a8David Brown 135211544975bb29ede282333209e945a75430b221a8David Brown final Call ringingCall = mCM.getFirstActiveRingingCall(); 135311544975bb29ede282333209e945a75430b221a8David Brown // Don't check ringingCall.isRinging() here, since that'll be true 135411544975bb29ede282333209e945a75430b221a8David Brown // for the WAITING state also. We only allow the ringer for 135511544975bb29ede282333209e945a75430b221a8David Brown // regular INCOMING calls. 135611544975bb29ede282333209e945a75430b221a8David Brown if (DBG) log("- ringingCall state: " + ringingCall.getState()); 135711544975bb29ede282333209e945a75430b221a8David Brown if (ringingCall.getState() == Call.State.INCOMING) { 135811544975bb29ede282333209e945a75430b221a8David Brown mRinger.ring(); 135911544975bb29ede282333209e945a75430b221a8David Brown } 136011544975bb29ede282333209e945a75430b221a8David Brown } 136111544975bb29ede282333209e945a75430b221a8David Brown 136211544975bb29ede282333209e945a75430b221a8David Brown /** 1363b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Posts a PHONE_BATTERY_LOW event, causing us to play a warning 1364b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * tone if the user is in-call. 1365b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1366b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /* package */ void sendBatteryLow() { 1367b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project Message message = Message.obtain(this, PHONE_BATTERY_LOW); 1368b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project sendMessage(message); 1369b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1370b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1371b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void onBatteryLow() { 1372b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (DBG) log("onBatteryLow()..."); 1373b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 13743e2bc7b4724cf015d5ef06dfd33553a290a55f9bDaniel Sandler // A "low battery" warning tone is now played by 13753e2bc7b4724cf015d5ef06dfd33553a290a55f9bDaniel Sandler // StatusBarPolicy.updateBattery(). 1376b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1377b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1378b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1379b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project /** 1380b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Helper class to play tones through the earpiece (or speaker / BT) 1381b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * during a call, using the ToneGenerator. 1382b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1383b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * To use, just instantiate a new InCallTonePlayer 1384b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (passing in the TONE_* constant for the tone you want) 1385b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * and start() it. 1386b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * 1387b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * When we're done playing the tone, if the phone is idle at that 1388b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * point, we'll reset the audio routing and speaker state. 1389b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * (That means that for tones that get played *after* a call 1390b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * disconnects, like "busy" or "congestion" or "call ended", you 1391b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * should NOT call resetAudioStateAfterDisconnect() yourself. 1392b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * Instead, just start the InCallTonePlayer, which will automatically 1393b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * defer the resetAudioStateAfterDisconnect() call until the tone 1394b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project * finishes playing.) 1395b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project */ 1396b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private class InCallTonePlayer extends Thread { 1397b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private int mToneId; 139803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private int mState; 1399b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The possible tones we can play. 1400b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_NONE = 0; 1401b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_CALL_WAITING = 1; 1402b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_BUSY = 2; 1403b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_CONGESTION = 3; 1404b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_BATTERY_LOW = 4; 1405b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public static final int TONE_CALL_ENDED = 5; 14063800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_VOICE_PRIVACY = 6; 14073800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_REORDER = 7; 14083800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_INTERCEPT = 8; 14093800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_CDMA_DROP = 9; 14103800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_OUT_OF_SERVICE = 10; 14113800ac871d6548790ac6119bb68b9be0640af261David Krause public static final int TONE_REDIAL = 11; 1412af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville public static final int TONE_OTA_CALL_END = 12; 141303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent public static final int TONE_RING_BACK = 13; 1414975d455b9bf32f2c07527ffa96aafecf042a68d8The Android Open Source Project public static final int TONE_UNOBTAINABLE_NUMBER = 14; 1415b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1416b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // The tone volume relative to other sounds in the stream 14173dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent private static final int TONE_RELATIVE_VOLUME_EMERGENCY = 100; 1418b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int TONE_RELATIVE_VOLUME_HIPRI = 80; 1419b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private static final int TONE_RELATIVE_VOLUME_LOPRI = 50; 1420b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1421421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman // Buffer time (in msec) to add on to tone timeout value. 1422421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman // Needed mainly when the timeout value for a tone is the 1423421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman // exact duration of the tone itself. 1424421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman private static final int TONE_TIMEOUT_BUFFER = 20; 1425421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman 142603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // The tone state 142703d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private static final int TONE_OFF = 0; 142803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private static final int TONE_ON = 1; 142903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent private static final int TONE_STOPPED = 2; 143003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 1431b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project InCallTonePlayer(int toneId) { 1432b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project super(); 1433b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project mToneId = toneId; 143403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mState = TONE_OFF; 1435b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1436b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1437b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project @Override 1438b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project public void run() { 143904a4162d2c47e63f27d8a6d0a4efd945f2c8052fDavid Brown log("InCallTonePlayer.run(toneId = " + mToneId + ")..."); 1440b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 14413800ac871d6548790ac6119bb68b9be0640af261David Krause int toneType = 0; // passed to ToneGenerator.startTone() 1442b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int toneVolume; // passed to the ToneGenerator constructor 1443b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int toneLengthMillis; 1444872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan int phoneType = mCM.getFgPhone().getPhoneType(); 14453800ac871d6548790ac6119bb68b9be0640af261David Krause 1446b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project switch (mToneId) { 1447b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TONE_CALL_WAITING: 1448b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneType = ToneGenerator.TONE_SUP_CALL_WAITING; 1449b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 145003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // Call waiting tone is stopped by stopTone() method 145103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; 1452b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1453b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TONE_BUSY: 145479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 14553800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT; 14563800ac871d6548790ac6119bb68b9be0640af261David Krause toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 1457421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 1000; 1458872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan } else if ((phoneType == Phone.PHONE_TYPE_GSM) 1459872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan || (phoneType == Phone.PHONE_TYPE_SIP)) { 14603800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_SUP_BUSY; 14613800ac871d6548790ac6119bb68b9be0640af261David Krause toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 14623800ac871d6548790ac6119bb68b9be0640af261David Krause toneLengthMillis = 4000; 146379b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink } else { 146479b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink throw new IllegalStateException("Unexpected phone type: " + phoneType); 14653800ac871d6548790ac6119bb68b9be0640af261David Krause } 1466b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1467b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TONE_CONGESTION: 1468b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneType = ToneGenerator.TONE_SUP_CONGESTION; 1469b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1470b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneLengthMillis = 4000; 1471b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1472b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TONE_BATTERY_LOW: 1473b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // For now, use ToneGenerator.TONE_PROP_ACK (two quick 1474b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // beeps). TODO: is there some other ToneGenerator 1475b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // tone that would be more appropriate here? Or 1476b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // should we consider adding a new custom tone? 1477b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneType = ToneGenerator.TONE_PROP_ACK; 1478b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1479b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneLengthMillis = 1000; 1480b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1481b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project case TONE_CALL_ENDED: 1482b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneType = ToneGenerator.TONE_PROP_PROMPT; 1483520c34f2281e3ef6f2293606b4fe99b0fcb2afabPeng Zhu toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1484421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 200; 1485b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project break; 1486af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville case TONE_OTA_CALL_END: 1487af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville if (mApplication.cdmaOtaConfigData.otaPlaySuccessFailureTone == 1488af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville OtaUtils.OTA_PLAY_SUCCESS_FAILURE_TONE_ON) { 1489af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville toneType = ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD; 1490814d369bd1ee21f0b9f8cd2209e3f61ed15329e7Charulata R Pardhanani toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1491421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 750; 1492af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } else { 1493af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville toneType = ToneGenerator.TONE_PROP_PROMPT; 1494520c34f2281e3ef6f2293606b4fe99b0fcb2afabPeng Zhu toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1495421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 200; 1496af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville } 1497af684393e2c6d0c051b9d5a189c2cd1de2506831Wink Saville break; 14983800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_VOICE_PRIVACY: 14993800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE; 15001c3518a5cf9b39dbc462a1ab8c1e5390cd5c8f04Peng Zhu toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 15013800ac871d6548790ac6119bb68b9be0640af261David Krause toneLengthMillis = 5000; 15023800ac871d6548790ac6119bb68b9be0640af261David Krause break; 15033800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_REORDER: 1504b3ea9d2c99efb837b2b4d0c54a91b36ca05aa43aShruthi N.K toneType = ToneGenerator.TONE_CDMA_REORDER; 1505b3ea9d2c99efb837b2b4d0c54a91b36ca05aa43aShruthi N.K toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 1506421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 4000; 15073800ac871d6548790ac6119bb68b9be0640af261David Krause break; 15083800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_INTERCEPT: 15093800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_CDMA_ABBR_INTERCEPT; 15103800ac871d6548790ac6119bb68b9be0640af261David Krause toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 1511421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 500; 15123800ac871d6548790ac6119bb68b9be0640af261David Krause break; 15133800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_CDMA_DROP: 15143800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_OUT_OF_SERVICE: 15153800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_CDMA_CALLDROP_LITE; 15163800ac871d6548790ac6119bb68b9be0640af261David Krause toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 1517421475c4fe1b2388ce84be8d85f61a639ee3e253Paul Berman toneLengthMillis = 375; 15183800ac871d6548790ac6119bb68b9be0640af261David Krause break; 15193800ac871d6548790ac6119bb68b9be0640af261David Krause case TONE_REDIAL: 15203800ac871d6548790ac6119bb68b9be0640af261David Krause toneType = ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE; 1521e1c85a5471a4a80c1bff9a3bfe0e18a4d0e59b92Peng Zhu toneVolume = TONE_RELATIVE_VOLUME_LOPRI; 15223800ac871d6548790ac6119bb68b9be0640af261David Krause toneLengthMillis = 5000; 15233800ac871d6548790ac6119bb68b9be0640af261David Krause break; 152403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent case TONE_RING_BACK: 152503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneType = ToneGenerator.TONE_SUP_RINGTONE; 152603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 152703d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // Call ring back tone is stopped by stopTone() method 152803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneLengthMillis = Integer.MAX_VALUE - TONE_TIMEOUT_BUFFER; 152903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent break; 15309eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla case TONE_UNOBTAINABLE_NUMBER: 15319eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla toneType = ToneGenerator.TONE_SUP_ERROR; 15329eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla toneVolume = TONE_RELATIVE_VOLUME_HIPRI; 15339eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla toneLengthMillis = 4000; 15349eb2ffdf7b4752c7199eba6a3b88f63edc4a0ac8Naveen Kalla break; 1535b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project default: 1536b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project throw new IllegalArgumentException("Bad toneId: " + mToneId); 1537b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1538b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1539b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // If the mToneGenerator creation fails, just continue without it. It is 1540b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // a local audio signal, and is not as important. 1541b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project ToneGenerator toneGenerator; 1542b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project try { 1543b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project int stream; 1544b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (mBluetoothHandsfree != null) { 1545b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stream = mBluetoothHandsfree.isAudioOn() ? AudioManager.STREAM_BLUETOOTH_SCO: 1546b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project AudioManager.STREAM_VOICE_CALL; 1547b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } else { 1548b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project stream = AudioManager.STREAM_VOICE_CALL; 1549b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1550b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneGenerator = new ToneGenerator(stream, toneVolume); 1551b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // if (DBG) log("- created toneGenerator: " + toneGenerator); 1552b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } catch (RuntimeException e) { 1553796c70c99bc39295bf685061056f06ab8949c742David Brown Log.w(LOG_TAG, 1554796c70c99bc39295bf685061056f06ab8949c742David Brown "InCallTonePlayer: Exception caught while creating ToneGenerator: " + e); 1555b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project toneGenerator = null; 1556b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1557b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1558b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Using the ToneGenerator (with the CALL_WAITING / BUSY / 1559b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CONGESTION tones at least), the ToneGenerator itself knows 1560b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // the right pattern of tones to play; we do NOT need to 1561b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // manually start/stop each individual tone, or manually 1562b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // insert the correct delay between tones. (We just start it 1563b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // and let it run for however long we want the tone pattern to 1564b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // continue.) 1565b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1566b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // TODO: When we stop the ToneGenerator in the middle of a 1567b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "tone pattern", it sounds bad if we cut if off while the 1568b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // tone is actually playing. Consider adding API to the 1569b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // ToneGenerator to say "stop at the next silent part of the 1570b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // pattern", or simply "play the pattern N times and then 1571b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // stop." 15723800ac871d6548790ac6119bb68b9be0640af261David Krause boolean needToStopTone = true; 15737fe7f7e57aaa38290c37ab48867d34a279d198f3w boolean okToPlayTone = false; 1574b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1575b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project if (toneGenerator != null) { 157603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent int ringerMode = mAudioManager.getRingerMode(); 157779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (phoneType == Phone.PHONE_TYPE_CDMA) { 15787fe7f7e57aaa38290c37ab48867d34a279d198f3w if (toneType == ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD) { 157979b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 158079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 15817fe7f7e57aaa38290c37ab48867d34a279d198f3w if (DBG) log("- InCallTonePlayer: start playing call tone=" + toneType); 15827fe7f7e57aaa38290c37ab48867d34a279d198f3w okToPlayTone = true; 15837fe7f7e57aaa38290c37ab48867d34a279d198f3w needToStopTone = false; 15847fe7f7e57aaa38290c37ab48867d34a279d198f3w } 15857fe7f7e57aaa38290c37ab48867d34a279d198f3w } else if ((toneType == ToneGenerator.TONE_CDMA_NETWORK_BUSY_ONE_SHOT) || 1586b3ea9d2c99efb837b2b4d0c54a91b36ca05aa43aShruthi N.K (toneType == ToneGenerator.TONE_CDMA_REORDER) || 15877fe7f7e57aaa38290c37ab48867d34a279d198f3w (toneType == ToneGenerator.TONE_CDMA_ABBR_REORDER) || 15887fe7f7e57aaa38290c37ab48867d34a279d198f3w (toneType == ToneGenerator.TONE_CDMA_ABBR_INTERCEPT) || 15897fe7f7e57aaa38290c37ab48867d34a279d198f3w (toneType == ToneGenerator.TONE_CDMA_CALLDROP_LITE)) { 159079b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if (ringerMode != AudioManager.RINGER_MODE_SILENT) { 15917fe7f7e57aaa38290c37ab48867d34a279d198f3w if (DBG) log("InCallTonePlayer:playing call fail tone:" + toneType); 15927fe7f7e57aaa38290c37ab48867d34a279d198f3w okToPlayTone = true; 15937fe7f7e57aaa38290c37ab48867d34a279d198f3w needToStopTone = false; 15947fe7f7e57aaa38290c37ab48867d34a279d198f3w } 15957fe7f7e57aaa38290c37ab48867d34a279d198f3w } else if ((toneType == ToneGenerator.TONE_CDMA_ALERT_AUTOREDIAL_LITE) || 15967fe7f7e57aaa38290c37ab48867d34a279d198f3w (toneType == ToneGenerator.TONE_CDMA_ALERT_NETWORK_LITE)) { 159779b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink if ((ringerMode != AudioManager.RINGER_MODE_SILENT) && 159879b9f6e30e8402b103f1ec3ed9dda1fcad2b1cd5Tammo Spalink (ringerMode != AudioManager.RINGER_MODE_VIBRATE)) { 15997fe7f7e57aaa38290c37ab48867d34a279d198f3w if (DBG) log("InCallTonePlayer:playing tone for toneType=" + toneType); 16007fe7f7e57aaa38290c37ab48867d34a279d198f3w okToPlayTone = true; 16017fe7f7e57aaa38290c37ab48867d34a279d198f3w needToStopTone = false; 16027fe7f7e57aaa38290c37ab48867d34a279d198f3w } 1603520c34f2281e3ef6f2293606b4fe99b0fcb2afabPeng Zhu } else { // For the rest of the tones, always OK to play. 1604520c34f2281e3ef6f2293606b4fe99b0fcb2afabPeng Zhu okToPlayTone = true; 16053800ac871d6548790ac6119bb68b9be0640af261David Krause } 1606520c34f2281e3ef6f2293606b4fe99b0fcb2afabPeng Zhu } else { // Not "CDMA" 16077fe7f7e57aaa38290c37ab48867d34a279d198f3w okToPlayTone = true; 16083800ac871d6548790ac6119bb68b9be0640af261David Krause } 1609b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 161003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent synchronized (this) { 161103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (okToPlayTone && mState != TONE_STOPPED) { 161203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mState = TONE_ON; 161303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneGenerator.startTone(toneType); 161403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent try { 161503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent wait(toneLengthMillis + TONE_TIMEOUT_BUFFER); 161603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } catch (InterruptedException e) { 161703d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent Log.w(LOG_TAG, 161803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent "InCallTonePlayer stopped: " + e); 161903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 162003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (needToStopTone) { 162103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneGenerator.stopTone(); 162203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 16233800ac871d6548790ac6119bb68b9be0640af261David Krause } 162403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // if (DBG) log("- InCallTonePlayer: done playing."); 162503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent toneGenerator.release(); 162603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mState = TONE_OFF; 16273800ac871d6548790ac6119bb68b9be0640af261David Krause } 1628b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1629b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 1630b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // Finally, do the same cleanup we otherwise would have done 1631b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // in onDisconnect(). 1632b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // 1633b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // (But watch out: do NOT do this if the phone is in use, 1634b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // since some of our tones get played *during* a call (like 1635b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // CALL_WAITING and BATTERY_LOW) and we definitely *don't* 1636b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // want to reset the audio mode / speaker / bluetooth after 1637b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // playing those! 1638b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // This call is really here for use with tones that get played 1639b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // *after* a call disconnects, like "busy" or "congestion" or 1640b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // "call ended", where the phone has already become idle but 1641b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // we need to defer the resetAudioStateAfterDisconnect() call 1642b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project // till the tone finishes playing.) 1643170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (mCM.getState() == Phone.State.IDLE) { 1644b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project resetAudioStateAfterDisconnect(); 1645b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1646b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 164703d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent 164803d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent public void stopTone() { 164903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent synchronized (this) { 165003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (mState == TONE_ON) { 165103d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent notify(); 165203d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 165303d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mState = TONE_STOPPED; 165403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 165503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent } 1656b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 1657b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 16580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville /** 16590fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * Displays a notification when the phone receives a DisplayInfo record. 16600fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville */ 16610fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private void onDisplayInfo(AsyncResult r) { 16620fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Extract the DisplayInfo String from the message 16630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CdmaDisplayInfoRec displayInfoRec = (CdmaDisplayInfoRec)(r.result); 16640fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (displayInfoRec != null) { 16660fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville String displayInfo = displayInfoRec.alpha; 16670fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("onDisplayInfo: displayInfo=" + displayInfo); 16680fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CdmaDisplayInfo.displayInfoRecord(mApplication, displayInfo); 16690fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // start a 2 second timer 16710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville sendEmptyMessageDelayed(DISPLAYINFO_NOTIFICATION_DONE, 16720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville DISPLAYINFO_NOTIFICATION_TIME); 16730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 16740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 16750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville /** 16770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * Helper class to play SignalInfo tones using the ToneGenerator. 16780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * 16790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * To use, just instantiate a new SignalInfoTonePlayer 16800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * (passing in the ToneID constant for the tone you want) 16810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * and start() it. 16820fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville */ 16830fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private class SignalInfoTonePlayer extends Thread { 16840fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private int mToneId; 16850fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16860fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville SignalInfoTonePlayer(int toneId) { 16870fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville super(); 16880fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mToneId = toneId; 16890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 16900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville @Override 16920fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville public void run() { 169304a4162d2c47e63f27d8a6d0a4efd945f2c8052fDavid Brown log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")..."); 16940fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16950fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (mSignalInfoToneGenerator != null) { 16960fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //First stop any ongoing SignalInfo tone 16970fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mSignalInfoToneGenerator.stopTone(); 16980fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 16990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Start playing the new tone if its a valid tone 17000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mSignalInfoToneGenerator.startTone(mToneId); 17010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17020fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville /** 17060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * Plays a tone when the phone receives a SignalInfo record. 17070fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville */ 17080fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private void onSignalInfo(AsyncResult r) { 1709a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang // Signal Info are totally ignored on non-voice-capable devices. 1710a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang if (!PhoneApp.sVoiceCapable) { 1711a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang Log.w(LOG_TAG, "Got onSignalInfo() on non-voice-capable device! Ignoring..."); 1712a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang return; 1713a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang } 1714a0a3e4d52f8d39a6a8c1341144a1e6c522db0055John Wang 17158343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (PhoneUtils.isRealIncomingCall(mCM.getFirstActiveRingingCall().getState())) { 171605fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu // Do not start any new SignalInfo tone when Call state is INCOMING 171705fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu // and stop any previous SignalInfo tone which is being played 171805fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu stopSignalInfoTone(); 171905fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu } else { 172005fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu // Extract the SignalInfo String from the message 172105fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu CdmaSignalInfoRec signalInfoRec = (CdmaSignalInfoRec)(r.result); 172205fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu // Only proceed if a Signal info is present. 172305fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu if (signalInfoRec != null) { 172405fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu boolean isPresent = signalInfoRec.isPresent; 172505fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu if (DBG) log("onSignalInfo: isPresent=" + isPresent); 172605fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu if (isPresent) {// if tone is valid 172705fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu int uSignalType = signalInfoRec.signalType; 172805fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu int uAlertPitch = signalInfoRec.alertPitch; 172905fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu int uSignal = signalInfoRec.signal; 173005fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu 173105fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu if (DBG) log("onSignalInfo: uSignalType=" + uSignalType + ", uAlertPitch=" + 173205fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu uAlertPitch + ", uSignal=" + uSignal); 173305fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu //Map the Signal to a ToneGenerator ToneID only if Signal info is present 173405fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu int toneID = SignalToneUtil.getAudioToneFromSignalInfo 173505fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu (uSignalType, uAlertPitch, uSignal); 173605fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu 173705fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu //Create the SignalInfo tone player and pass the ToneID 173805fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu new SignalInfoTonePlayer(toneID).start(); 173905fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu } 17400fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17410fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17420fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17430fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17440fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville /** 174505fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu * Stops a SignalInfo tone in the following condition 174605fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu * 1 - On receiving a New Ringing Call 174705fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu * 2 - On disconnecting a call 174805fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu * 3 - On answering a Call Waiting Call 174905fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu */ 175005fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu /* package */ void stopSignalInfoTone() { 175105fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu if (DBG) log("stopSignalInfoTone: Stopping SignalInfo tone player"); 175205fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu new SignalInfoTonePlayer(ToneGenerator.TONE_CDMA_SIGNAL_OFF).start(); 175305fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu } 175405fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu 175505fb729f41a3f7e06891d0c73c04be4be933a89cPeng Zhu /** 17560fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * Plays a Call waiting tone if it is present in the second incoming call. 17570fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville */ 17580fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville private void onCdmaCallWaiting(AsyncResult r) { 17591c48fc89c22508154ac6a682dc39c8f827e0c634w // Remove any previous Call waiting timers in the queue 17601c48fc89c22508154ac6a682dc39c8f827e0c634w removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 17611c48fc89c22508154ac6a682dc39c8f827e0c634w removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT); 17621c48fc89c22508154ac6a682dc39c8f827e0c634w 17631c48fc89c22508154ac6a682dc39c8f827e0c634w // Set the Phone Call State to SINGLE_ACTIVE as there is only one connection 17641c48fc89c22508154ac6a682dc39c8f827e0c634w // else we would not have received Call waiting 17651c48fc89c22508154ac6a682dc39c8f827e0c634w mApplication.cdmaPhoneCallState.setCurrentCallState( 17661c48fc89c22508154ac6a682dc39c8f827e0c634w CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE); 17671c48fc89c22508154ac6a682dc39c8f827e0c634w 17687f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // Display the incoming call to the user if the InCallScreen isn't 17697f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown // already in the foreground. 17700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (!mApplication.isShowingCallScreen()) { 177149c2f55d9544b3262b82ff956cc84c06cfed7f41David Brown if (DBG) log("- showing incoming call (CDMA call waiting)..."); 17727f63f08c5c88d604abba447032ed42f4f972f3efDavid Brown showIncomingCall(); 17730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 17740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Start timer for CW display 17760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mCallWaitingTimeOut = false; 17770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville sendEmptyMessageDelayed(CALLWAITING_CALLERINFO_DISPLAY_DONE, 17780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CALLWAITING_CALLERINFO_DISPLAY_TIME); 17790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17800fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Set the mAddCallMenuStateAfterCW state to false 17810fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(false); 17820fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17830fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Start the timer for disabling "Add Call" menu option 17840fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville sendEmptyMessageDelayed(CALLWAITING_ADDCALL_DISABLE_TIMEOUT, 17850fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CALLWAITING_ADDCALL_DISABLE_TIME); 17860fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 17870fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Extract the Call waiting information 17880fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville CdmaCallWaitingNotification infoCW = (CdmaCallWaitingNotification) r.result; 17890fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville int isPresent = infoCW.isPresent; 17900fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("onCdmaCallWaiting: isPresent=" + isPresent); 17910fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (isPresent == 1 ) {//'1' if tone is valid 17920fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville int uSignalType = infoCW.signalType; 17930fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville int uAlertPitch = infoCW.alertPitch; 17940fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville int uSignal = infoCW.signal; 17950fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (DBG) log("onCdmaCallWaiting: uSignalType=" + uSignalType + ", uAlertPitch=" 17960fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville + uAlertPitch + ", uSignal=" + uSignal); 17970fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Map the Signal to a ToneGenerator ToneID only if Signal info is present 17980fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville int toneID = 17990fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville SignalToneUtil.getAudioToneFromSignalInfo(uSignalType, uAlertPitch, uSignal); 18000fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18010fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Create the SignalInfo tone player and pass the ToneID 18020fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville new SignalInfoTonePlayer(toneID).start(); 18030fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18040fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18050fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18060fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville /** 180777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * Posts a event causing us to clean up after rejecting (or timing-out) a 180877350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * CDMA call-waiting call. 180977350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * 181077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * This method is safe to call from any thread. 181177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * @see onCdmaCallWaitingReject() 181277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown */ 181377350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown /* package */ void sendCdmaCallWaitingReject() { 181477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown sendEmptyMessage(CDMA_CALL_WAITING_REJECT); 181577350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown } 181677350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown 181777350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown /** 18180fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * Performs Call logging based on Timeout or Ignore Call Waiting Call for CDMA, 18190fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville * and finally calls Hangup on the Call Waiting connection. 182077350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * 182177350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * This method should be called only from the UI thread. 182277350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown * @see sendCdmaCallWaitingReject() 18230fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville */ 182477350aabae2f056ede7d0df806a9e5a3c22daf7aDavid Brown private void onCdmaCallWaitingReject() { 1825170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang final Call ringingCall = mCM.getFirstActiveRingingCall(); 18260fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18270fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Call waiting timeout scenario 18280fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (ringingCall.getState() == Call.State.WAITING) { 18290fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Code for perform Call logging and missed call notification 18300fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Connection c = ringingCall.getLatestConnection(); 18310fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18320fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if (c != null) { 1833de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman String number = c.getAddress(); 1834de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman int presentation = c.getNumberPresentation(); 1835c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman final long date = c.getCreateTime(); 1836c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman final long duration = c.getDurationMillis(); 1837c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman final int callLogType = mCallWaitingTimeOut ? 183811aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania Calls.MISSED_TYPE : Calls.INCOMING_TYPE; 18390fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18400fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // get the callerinfo object and then log the call with it. 18410fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville Object o = c.getUserData(); 1842c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman final CallerInfo ci; 18430fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville if ((o == null) || (o instanceof CallerInfo)) { 18440fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville ci = (CallerInfo) o; 18450fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } else { 18460fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 18470fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18480fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 1849de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // Do final CNAP modifications of logNumber prior to logging [mimicking 1850de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // onDisconnect()] 1851de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman final String logNumber = PhoneUtils.modifyForSpecialCnapCases( 1852872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mApplication, ci, number, presentation); 1853de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman final int newPresentation = (ci != null) ? ci.numberPresentation : presentation; 1854de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman if (DBG) log("- onCdmaCallWaitingReject(): logNumber set to: " + logNumber 1855de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman + ", newPresentation value is: " + newPresentation); 1856de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman 185711aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania CallLogAsync.AddCallArgs args = 185811aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania new CallLogAsync.AddCallArgs( 1859872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan mApplication, ci, logNumber, presentation, 186011aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania callLogType, date, duration); 186111aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania 186211aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania mCallLog.addCall(args); 18630fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 186411aceea577d724e61056a646ef6ac8c6430613eeNicolas Catania if (callLogType == Calls.MISSED_TYPE) { 18650fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Add missed call notification 1866c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman showMissedCallNotification(c, date); 18671c48fc89c22508154ac6a682dc39c8f827e0c634w } else { 18681c48fc89c22508154ac6a682dc39c8f827e0c634w // Remove Call waiting 20 second display timer in the queue 18691c48fc89c22508154ac6a682dc39c8f827e0c634w removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE); 18700fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18710fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18720fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville // Hangup the RingingCall connection for CW 18730fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville PhoneUtils.hangup(c); 18740fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18750fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville 18760fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville //Reset the mCallWaitingTimeOut boolean 18770fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville mCallWaitingTimeOut = false; 18780fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 18790fb2b4b8eff811fd3243aefdf536e7ba2b10f4e9Wink Saville } 1880b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project 18813800ac871d6548790ac6119bb68b9be0640af261David Krause /** 18823800ac871d6548790ac6119bb68b9be0640af261David Krause * Return the private variable mPreviousCdmaCallState. 18833800ac871d6548790ac6119bb68b9be0640af261David Krause */ 18843800ac871d6548790ac6119bb68b9be0640af261David Krause /* package */ Call.State getPreviousCdmaCallState() { 18853800ac871d6548790ac6119bb68b9be0640af261David Krause return mPreviousCdmaCallState; 18863800ac871d6548790ac6119bb68b9be0640af261David Krause } 18873800ac871d6548790ac6119bb68b9be0640af261David Krause 18883800ac871d6548790ac6119bb68b9be0640af261David Krause /** 188924f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon * Return the private variable mVoicePrivacyState. 18903800ac871d6548790ac6119bb68b9be0640af261David Krause */ 189124f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon /* package */ boolean getVoicePrivacyState() { 189224f2ad06f72bda5d06281ff082598aad60f74a66Martin Hibdon return mVoicePrivacyState; 18933800ac871d6548790ac6119bb68b9be0640af261David Krause } 18943800ac871d6548790ac6119bb68b9be0640af261David Krause 18953800ac871d6548790ac6119bb68b9be0640af261David Krause /** 18963800ac871d6548790ac6119bb68b9be0640af261David Krause * Return the private variable mIsCdmaRedialCall. 18973800ac871d6548790ac6119bb68b9be0640af261David Krause */ 18983800ac871d6548790ac6119bb68b9be0640af261David Krause /* package */ boolean getIsCdmaRedialCall() { 18993800ac871d6548790ac6119bb68b9be0640af261David Krause return mIsCdmaRedialCall; 19003800ac871d6548790ac6119bb68b9be0640af261David Krause } 19013800ac871d6548790ac6119bb68b9be0640af261David Krause 190280e7149ffe1f9cd99cc6c161717ff1780232d907Wink Saville /** 1903c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman * Helper function used to show a missed call notification. 1904c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman */ 1905c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman private void showMissedCallNotification(Connection c, final long date) { 1906c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman PhoneUtils.CallerInfoToken info = 1907c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman PhoneUtils.startGetCallerInfo(mApplication, c, this, Long.valueOf(date)); 1908c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman if (info != null) { 1909c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // at this point, we've requested to start a query, but it makes no 1910c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // sense to log this missed call until the query comes back. 1911c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman if (VDBG) log("showMissedCallNotification: Querying for CallerInfo on missed call..."); 1912c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman if (info.isFinal) { 1913c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // it seems that the query we have actually is up to date. 1914c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // send the notification then. 1915c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman CallerInfo ci = info.currentInfo; 1916de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman 1917de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // Check number presentation value; if we have a non-allowed presentation, 1918de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // then display an appropriate presentation string instead as the missed 1919de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman // call. 1920de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman String name = ci.name; 1921de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman String number = ci.phoneNumber; 1922de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman if (ci.numberPresentation == Connection.PRESENTATION_RESTRICTED) { 1923872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan name = mApplication.getString(R.string.private_num); 1924de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } else if (ci.numberPresentation != Connection.PRESENTATION_ALLOWED) { 1925872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan name = mApplication.getString(R.string.unknown); 1926de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } else { 1927872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan number = PhoneUtils.modifyForSpecialCnapCases(mApplication, 1928de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman ci, number, ci.numberPresentation); 1929de0d16c814b5e7f6c75d00025dc331f64703de1cPaul Berman } 1930df266ade99188365d4a52f89a6d26b549c2aaf9aDavid Brown mApplication.notificationMgr.notifyMissedCall(name, number, 1931c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman ci.phoneLabel, date); 1932c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman } 1933c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman } else { 1934c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // getCallerInfo() can return null in rare cases, like if we weren't 1935c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman // able to get a valid phone number out of the specified Connection. 1936c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman Log.w(LOG_TAG, "showMissedCallNotification: got null CallerInfo for Connection " + c); 1937c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman } 1938c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman } 1939c9eddc4caa45b1e39b964a60c4edab9ae6f689cfPaul Berman 1940678d72446de9c185c767206338f5fb199e0cd845Peng Zhu /** 1941678d72446de9c185c767206338f5fb199e0cd845Peng Zhu * Inner class to handle emergency call tone and vibrator 1942678d72446de9c185c767206338f5fb199e0cd845Peng Zhu */ 1943678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private class EmergencyTonePlayerVibrator { 1944678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private final int EMG_VIBRATE_LENGTH = 1000; // ms. 1945678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private final int EMG_VIBRATE_PAUSE = 1000; // ms. 1946678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private final long[] mVibratePattern = 1947678d72446de9c185c767206338f5fb199e0cd845Peng Zhu new long[] { EMG_VIBRATE_LENGTH, EMG_VIBRATE_PAUSE }; 1948678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1949678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private ToneGenerator mToneGenerator; 1950678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private Vibrator mEmgVibrator; 19513dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent private int mInCallVolume; 1952678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1953678d72446de9c185c767206338f5fb199e0cd845Peng Zhu /** 1954678d72446de9c185c767206338f5fb199e0cd845Peng Zhu * constructor 1955678d72446de9c185c767206338f5fb199e0cd845Peng Zhu */ 1956678d72446de9c185c767206338f5fb199e0cd845Peng Zhu public EmergencyTonePlayerVibrator() { 1957678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1958678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1959678d72446de9c185c767206338f5fb199e0cd845Peng Zhu /** 1960678d72446de9c185c767206338f5fb199e0cd845Peng Zhu * Start the emergency tone or vibrator. 1961678d72446de9c185c767206338f5fb199e0cd845Peng Zhu */ 1962678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private void start() { 1963678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (VDBG) log("call startEmergencyToneOrVibrate."); 1964678d72446de9c185c767206338f5fb199e0cd845Peng Zhu int ringerMode = mAudioManager.getRingerMode(); 1965678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1966678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if ((mIsEmergencyToneOn == EMERGENCY_TONE_ALERT) && 1967678d72446de9c185c767206338f5fb199e0cd845Peng Zhu (ringerMode == AudioManager.RINGER_MODE_NORMAL)) { 196804a4162d2c47e63f27d8a6d0a4efd945f2c8052fDavid Brown log("EmergencyTonePlayerVibrator.start(): emergency tone..."); 1969678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mToneGenerator = new ToneGenerator (AudioManager.STREAM_VOICE_CALL, 19703dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent InCallTonePlayer.TONE_RELATIVE_VOLUME_EMERGENCY); 1971678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mToneGenerator != null) { 19723dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent mInCallVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 19733dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 19743dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 19753dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent 0); 1976678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mToneGenerator.startTone(ToneGenerator.TONE_CDMA_EMERGENCY_RINGBACK); 1977678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mCurrentEmergencyToneState = EMERGENCY_TONE_ALERT; 1978678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1979678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } else if (mIsEmergencyToneOn == EMERGENCY_TONE_VIBRATE) { 198004a4162d2c47e63f27d8a6d0a4efd945f2c8052fDavid Brown log("EmergencyTonePlayerVibrator.start(): emergency vibrate..."); 1981678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmgVibrator = new Vibrator(); 1982678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (mEmgVibrator != null) { 1983678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmgVibrator.vibrate(mVibratePattern, 0); 1984678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mCurrentEmergencyToneState = EMERGENCY_TONE_VIBRATE; 1985678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1986678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1987678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 1988678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1989678d72446de9c185c767206338f5fb199e0cd845Peng Zhu /** 1990678d72446de9c185c767206338f5fb199e0cd845Peng Zhu * If the emergency tone is active, stop the tone or vibrator accordingly. 1991678d72446de9c185c767206338f5fb199e0cd845Peng Zhu */ 1992678d72446de9c185c767206338f5fb199e0cd845Peng Zhu private void stop() { 1993678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if (VDBG) log("call stopEmergencyToneOrVibrate."); 1994678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 1995678d72446de9c185c767206338f5fb199e0cd845Peng Zhu if ((mCurrentEmergencyToneState == EMERGENCY_TONE_ALERT) 1996678d72446de9c185c767206338f5fb199e0cd845Peng Zhu && (mToneGenerator != null)) { 1997678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mToneGenerator.stopTone(); 1998678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mToneGenerator.release(); 19993dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, 20003dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent mInCallVolume, 20013dee774b27d7992f6cb51cde9b1b2d379d0e1169Eric Laurent 0); 2002678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } else if ((mCurrentEmergencyToneState == EMERGENCY_TONE_VIBRATE) 2003678d72446de9c185c767206338f5fb199e0cd845Peng Zhu && (mEmgVibrator != null)) { 2004678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mEmgVibrator.cancel(); 2005678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 2006678d72446de9c185c767206338f5fb199e0cd845Peng Zhu mCurrentEmergencyToneState = EMERGENCY_TONE_OFF; 2007678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 2008678d72446de9c185c767206338f5fb199e0cd845Peng Zhu } 2009678d72446de9c185c767206338f5fb199e0cd845Peng Zhu 2010eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang private void onRingbackTone(AsyncResult r) { 2011eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang boolean playTone = (Boolean)(r.result); 2012eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 2013eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang if (playTone == true) { 2014eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // Only play when foreground call is in DIALING or ALERTING. 201503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent // to prevent a late coming playtone after ALERTING. 2016eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // Don't play ringback tone if it is in play, otherwise it will cut 2017eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang // the current tone and replay it 2018170160f6550b2933ff5a6c96c879d074a3ca2f16John Wang if (mCM.getActiveFgCallState().isDialing() && 201903d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer == null) { 202003d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_RING_BACK); 2021eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang mInCallRingbackTonePlayer.start(); 2022eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 2023eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } else { 202403d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent if (mInCallRingbackTonePlayer != null) { 202503d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer.stopTone(); 202603d3877ce3396d533761216f3a0dce0ec71d1410Eric Laurent mInCallRingbackTonePlayer = null; 2027eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 2028eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 2029eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang } 2030eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang 2031eee76740ccf80cf2e4c3885dad7f7b544003bcdcjohnwang /** 20325bf2817fb998e6d7c7b50103733bfe8710d63916John Wang * Toggle mute and unmute requests while keeping the same mute state 20335bf2817fb998e6d7c7b50103733bfe8710d63916John Wang */ 20345bf2817fb998e6d7c7b50103733bfe8710d63916John Wang private void onResendMute() { 2035a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang boolean muteState = PhoneUtils.getMute(); 2036a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang PhoneUtils.setMute(!muteState); 2037a50e10e2efadac960987eaadc0938c6f92d3ee90John Wang PhoneUtils.setMute(muteState); 20385bf2817fb998e6d7c7b50103733bfe8710d63916John Wang } 20395bf2817fb998e6d7c7b50103733bfe8710d63916John Wang 20405bf2817fb998e6d7c7b50103733bfe8710d63916John Wang /** 204140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * Retrieve the phone number from the caller info or the connection. 204240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * 204340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * For incoming call the number is in the Connection object. For 204440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * outgoing call we use the CallerInfo phoneNumber field if 204540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * present. All the processing should have been done already (CDMA vs GSM numbers). 204640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * 204740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * If CallerInfo is missing the phone number, get it from the connection. 204840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * Apply the Call Name Presentation (CNAP) transform in the connection on the number. 204940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * 205040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @param conn The phone connection. 205140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @param info The CallerInfo. Maybe null. 205240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @return the phone number. 205340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania */ 205440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania private String getLogNumber(Connection conn, CallerInfo callerInfo) { 205540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania String number = null; 205640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 205740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if (conn.isIncoming()) { 205840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania number = conn.getAddress(); 205940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } else { 206064824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania // For emergency and voicemail calls, 206164824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania // CallerInfo.phoneNumber does *not* contain a valid phone 206264824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania // number. Instead it contains an I18N'd string such as 206364824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania // "Emergency Number" or "Voice Mail" so we get the number 206464824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania // from the connection. 206564824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania if (null == callerInfo || TextUtils.isEmpty(callerInfo.phoneNumber) || 206664824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania callerInfo.isEmergencyNumber() || callerInfo.isVoiceMailNumber()) { 2067872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan if (conn.getCall().getPhone().getPhoneType() == Phone.PHONE_TYPE_CDMA) { 206840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania // In cdma getAddress() is not always equals to getOrigDialString(). 206940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania number = conn.getOrigDialString(); 207040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } else { 207140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania number = conn.getAddress(); 207240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 207364824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania } else { 207464824003c89a7758240425f5c9f8d29cb00e4a65Nicolas Catania number = callerInfo.phoneNumber; 207540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 207640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 207740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 207840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if (null == number) { 207940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania return null; 208040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } else { 208140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania int presentation = conn.getNumberPresentation(); 208240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 208340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania // Do final CNAP modifications. 2084872a3a7af50ce6a4efb180336614bddefe102ac5Hung-ying Tyan number = PhoneUtils.modifyForSpecialCnapCases(mApplication, callerInfo, 208504a7ee829585973c667ca688a41f65897eaad452Nicolas Catania number, presentation); 20868343169cc89621d46dce86449f5ee1ff5d3a4919John Wang if (!PhoneNumberUtils.isUriNumber(number)) { 20878343169cc89621d46dce86449f5ee1ff5d3a4919John Wang number = PhoneNumberUtils.stripSeparators(number); 20888343169cc89621d46dce86449f5ee1ff5d3a4919John Wang } 208904a7ee829585973c667ca688a41f65897eaad452Nicolas Catania if (VDBG) log("getLogNumber: " + number); 209004a7ee829585973c667ca688a41f65897eaad452Nicolas Catania return number; 209140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 209240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 209340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 209440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania /** 209540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * Get the caller info. 209640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * 209740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @param conn The phone connection. 209840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @return The CallerInfo associated with the connection. Maybe null. 209940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania */ 210040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania private CallerInfo getCallerInfoFromConnection(Connection conn) { 210140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania CallerInfo ci = null; 210240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania Object o = conn.getUserData(); 210340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 210440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if ((o == null) || (o instanceof CallerInfo)) { 210540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania ci = (CallerInfo) o; 210640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } else { 210740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania ci = ((PhoneUtils.CallerInfoToken) o).currentInfo; 210840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 210940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania return ci; 211040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 211140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 211240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania /** 211340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * Get the presentation from the callerinfo if not null otherwise, 211440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * get it from the connection. 211540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * 211640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @param conn The phone connection. 211740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @param info The CallerInfo. Maybe null. 211840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania * @return The presentation to use in the logs. 211940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania */ 212040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania private int getPresentation(Connection conn, CallerInfo callerInfo) { 212140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania int presentation; 212240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 212340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if (null == callerInfo) { 212440e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania presentation = conn.getNumberPresentation(); 212540e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } else { 212640e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania presentation = callerInfo.numberPresentation; 212740e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if (DBG) log("- getPresentation(): ignoring connection's presentation: " + 212840e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania conn.getNumberPresentation()); 212940e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 213040e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania if (DBG) log("- getPresentation: presentation: " + presentation); 213140e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania return presentation; 213240e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania } 213340e46378d410065b7d3a5f3f2c1666c45e678689Nicolas Catania 2134b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project private void log(String msg) { 2135796c70c99bc39295bf685061056f06ab8949c742David Brown Log.d(LOG_TAG, msg); 2136b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project } 2137b16363f5fc191b769e88c364243e34b92eb22688The Android Open Source Project} 2138