Merge "Show connection managers if any are present" into lmp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ed4e910..f668255 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -429,8 +429,8 @@
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />
- <action android:name="android.telecomm.intent.action.SHOW_CALL_SETTINGS" />
- <action android:name="android.telecomm.intent.action.CHANGE_PHONE_ACCOUNTS" />
+ <action android:name="android.telecomm.action.SHOW_CALL_SETTINGS" />
+ <action android:name="android.telecomm.action.CHANGE_PHONE_ACCOUNTS" />
<action android:name="com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
diff --git a/res/values/config.xml b/res/values/config.xml
index 0ced13f..3daf89a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -120,8 +120,6 @@
<bool name="config_enabled_lte" translatable="false">false</bool>
<!-- Show cdma auto network mode in (glabal) roaming -->
<bool name="config_show_cdma" translatable="false">false</bool>
- <!-- Display enhanced 4G LTE mode menu if true -->
- <bool name="config_enhanced_4g_lte_mode_enable" translatable="false">false</bool>
<!-- Package name for the default in-call UI and dialer [DO NOT TRANSLATE] -->
<string name="ui_default_package" translatable="false">com.android.dialer</string>
diff --git a/sip/src/com/android/services/telephony/sip/SipConnection.java b/sip/src/com/android/services/telephony/sip/SipConnection.java
index 534b27a..583fa0e 100644
--- a/sip/src/com/android/services/telephony/sip/SipConnection.java
+++ b/sip/src/com/android/services/telephony/sip/SipConnection.java
@@ -21,13 +21,13 @@
import android.os.Message;
import android.telecomm.AudioState;
import android.telecomm.Connection;
+import android.telecomm.PhoneAccount;
import android.telecomm.PhoneCapabilities;
import android.util.Log;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.sip.SipPhone;
-import com.android.phone.Constants;
import java.util.List;
import java.util.Objects;
@@ -307,7 +307,7 @@
if (address == null) {
address = "";
}
- return Uri.fromParts(Constants.SCHEME_SIP, address, null);
+ return Uri.fromParts(PhoneAccount.SCHEME_SIP, address, null);
}
private void close() {
diff --git a/sip/src/com/android/services/telephony/sip/SipUtil.java b/sip/src/com/android/services/telephony/sip/SipUtil.java
index 5733a18..e926fa1 100644
--- a/sip/src/com/android/services/telephony/sip/SipUtil.java
+++ b/sip/src/com/android/services/telephony/sip/SipUtil.java
@@ -32,8 +32,6 @@
"com.android.services.telephony.sip.phone_account";
static final String GATEWAY_PROVIDER_PACKAGE =
"com.android.phone.extra.GATEWAY_PROVIDER_PACKAGE";
- static final String SCHEME_TEL = "tel";
- static final String SCHEME_SIP = "sip";
private static boolean sIsVoipSupported;
private static boolean sIsVoipSupportedInitialized;
diff --git a/src/com/android/phone/CallController.java b/src/com/android/phone/CallController.java
index a42f57d..a25b7a9 100644
--- a/src/com/android/phone/CallController.java
+++ b/src/com/android/phone/CallController.java
@@ -32,6 +32,7 @@
import android.os.Message;
import android.os.SystemProperties;
import android.provider.CallLog.Calls;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.util.Log;
@@ -466,7 +467,8 @@
// app.cdmaOtaInCallScreenUiState.state are redundant.
// Combine them.
- boolean voicemailUriSpecified = scheme != null && scheme.equals("voicemail");
+ boolean voicemailUriSpecified = scheme != null &&
+ scheme.equals(PhoneAccount.SCHEME_VOICEMAIL);
// Check for an obscure ECM-related scenario: If the phone
// is currently in ECM (Emergency callback mode) and we
// dial a non-emergency number, that automatically
diff --git a/src/com/android/phone/CallGatewayManager.java b/src/com/android/phone/CallGatewayManager.java
index 893070b..a349d17 100644
--- a/src/com/android/phone/CallGatewayManager.java
+++ b/src/com/android/phone/CallGatewayManager.java
@@ -18,6 +18,7 @@
import android.content.Intent;
import android.net.Uri;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -185,7 +186,7 @@
*/
public static String formatProviderUri(Uri uri) {
if (uri != null) {
- if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
+ if (PhoneAccount.SCHEME_TEL.equals(uri.getScheme())) {
return PhoneNumberUtils.formatNumber(uri.getSchemeSpecificPart());
} else {
return uri.toString();
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 674f66d..0edf62f 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -25,7 +25,6 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneBase;
import com.android.internal.telephony.TelephonyCapabilities;
-import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec;
import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
import com.android.internal.telephony.cdma.SignalToneUtil;
@@ -71,12 +70,6 @@
// before giving up and falling back to the default ringtone.
private static final int RINGTONE_QUERY_WAIT_TIME = 500; // msec
- // Timers related to CDMA Call Waiting
- // 1) For displaying Caller Info
- // 2) For disabling "Add Call" menu option once User selects Ignore or CW Timeout occures
- private static final int CALLWAITING_CALLERINFO_DISPLAY_TIME = 20000; // msec
- private static final int CALLWAITING_ADDCALL_DISABLE_TIME = 30000; // msec
-
// Time to display the DisplayInfo Record sent by CDMA network
private static final int DISPLAYINFO_NOTIFICATION_TIME = 2000; // msec
@@ -88,33 +81,6 @@
/** The singleton instance. */
private static CallNotifier sInstance;
- // Boolean to keep track of whether or not a CDMA Call Waiting call timed out.
- //
- // This is CDMA-specific, because with CDMA we *don't* get explicit
- // notification from the telephony layer that a call-waiting call has
- // stopped ringing. Instead, when a call-waiting call first comes in we
- // start a 20-second timer (see CALLWAITING_CALLERINFO_DISPLAY_DONE), and
- // if the timer expires we clean up the call and treat it as a missed call.
- //
- // If this field is true, that means that the current Call Waiting call
- // "timed out" and should be logged in Call Log as a missed call. If it's
- // false when we reach onCdmaCallWaitingReject(), we can assume the user
- // explicitly rejected this call-waiting call.
- //
- // This field is reset to false any time a call-waiting call first comes
- // in, and after cleaning up a missed call-waiting call. It's only ever
- // set to true when the CALLWAITING_CALLERINFO_DISPLAY_DONE timer fires.
- //
- // TODO: do we really need a member variable for this? Don't we always
- // know at the moment we call onCdmaCallWaitingReject() whether this is an
- // explicit rejection or not?
- // (Specifically: when we call onCdmaCallWaitingReject() from
- // PhoneUtils.hangupRingingCall() that means the user deliberately rejected
- // the call, and if we call onCdmaCallWaitingReject() because of a
- // CALLWAITING_CALLERINFO_DISPLAY_DONE event that means that it timed
- // out...)
- private boolean mCallWaitingTimeOut = false;
-
// values used to track the query state
private static final int CALLERINFO_QUERY_READY = 0;
private static final int CALLERINFO_QUERYING = -1;
@@ -130,10 +96,7 @@
// Events generated internally:
private static final int PHONE_MWI_CHANGED = 21;
- private static final int CALLWAITING_CALLERINFO_DISPLAY_DONE = 22;
- private static final int CALLWAITING_ADDCALL_DISABLE_TIMEOUT = 23;
private static final int DISPLAYINFO_NOTIFICATION_DONE = 24;
- private static final int CDMA_CALL_WAITING_REJECT = 26;
private static final int UPDATE_IN_CALL_NOTIFICATION = 27;
// Emergency call related defines:
@@ -166,9 +129,6 @@
// Ringback tone player
private InCallTonePlayer mInCallRingbackTonePlayer;
- // Call waiting tone player
- private InCallTonePlayer mCallWaitingTonePlayer;
-
// Cached AudioManager
private AudioManager mAudioManager;
@@ -287,28 +247,6 @@
onMwiChanged(mApplication.phone.getMessageWaitingIndicator());
break;
- case CallStateMonitor.PHONE_CDMA_CALL_WAITING:
- if (DBG) log("Received PHONE_CDMA_CALL_WAITING event");
- onCdmaCallWaiting((AsyncResult) msg.obj);
- break;
-
- case CDMA_CALL_WAITING_REJECT:
- Log.i(LOG_TAG, "Received CDMA_CALL_WAITING_REJECT event");
- onCdmaCallWaitingReject();
- break;
-
- case CALLWAITING_CALLERINFO_DISPLAY_DONE:
- Log.i(LOG_TAG, "Received CALLWAITING_CALLERINFO_DISPLAY_DONE event");
- mCallWaitingTimeOut = true;
- onCdmaCallWaitingReject();
- break;
-
- case CALLWAITING_ADDCALL_DISABLE_TIMEOUT:
- if (DBG) log("Received CALLWAITING_ADDCALL_DISABLE_TIMEOUT event ...");
- // Set the mAddCallMenuStateAfterCW state to true
- mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
- break;
-
case CallStateMonitor.PHONE_STATE_DISPLAYINFO:
if (DBG) log("Received PHONE_STATE_DISPLAYINFO event");
onDisplayInfo((AsyncResult) msg.obj);
@@ -573,8 +511,6 @@
// arrives at the same time that the query is still being run,
// and before the timeout window has closed.
EventLog.writeEvent(EventLogTags.PHONE_UI_MULTIPLE_QUERY);
-
- ringAndNotifyOfIncomingCall(c);
}
}
@@ -628,14 +564,6 @@
// Just bail out.
return;
}
-
- // If the ringing call still does not have any connection anymore, do not send the
- // notification.
- final Call ringingCall = mCM.getFirstActiveRingingCall();
-
- if (ringingCall != null && ringingCall.getLatestConnection() == c) {
- ringAndNotifyOfIncomingCall(c);
- }
}
private void onUnknownConnectionAppeared(AsyncResult r) {
@@ -649,23 +577,6 @@
}
/**
- * If it is not a waiting call (there is no other active call in foreground), we will ring the
- * ringtone. Otherwise we will play the call waiting tone instead.
- * @param c The new ringing connection.
- */
- private void ringAndNotifyOfIncomingCall(Connection c) {
- if (PhoneUtils.isRealIncomingCall(c.getState())) {
- mRinger.ring();
- } else {
- if (VDBG) log("- starting call waiting tone...");
- if (mCallWaitingTonePlayer == null) {
- mCallWaitingTonePlayer = new InCallTonePlayer(InCallTonePlayer.TONE_CALL_WAITING);
- mCallWaitingTonePlayer.start();
- }
- }
- }
-
- /**
* Updates the phone UI in response to phone state changes.
*
* Watch out: certain state changes are actually handled by their own
@@ -709,11 +620,6 @@
mApplication.updatePhoneState(state);
if (state == PhoneConstants.State.OFFHOOK) {
- // stop call waiting tone if needed when answering
- if (mCallWaitingTonePlayer != null) {
- mCallWaitingTonePlayer.stopTone();
- mCallWaitingTonePlayer = null;
- }
if (VDBG) log("onPhoneStateChanged: OFF HOOK");
// make sure audio is in in-call mode now
@@ -781,9 +687,6 @@
// Clear ringback tone player
mInCallRingbackTonePlayer = null;
- // Clear call waiting tone player
- mCallWaitingTonePlayer = null;
-
// Instantiate mSignalInfoToneGenerator
createSignalInfoToneGenerator();
}
@@ -911,10 +814,6 @@
if ((c != null) && (c.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)) {
// Resetting the CdmaPhoneCallState members
mApplication.cdmaPhoneCallState.resetCdmaPhoneCallState();
-
- // Remove Call waiting timers
- removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
- removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT);
}
// Stop the ringer if it was ringing (for an incoming call that
@@ -941,12 +840,6 @@
mRinger.stopRing();
}
- // stop call waiting tone if needed when disconnecting
- if (mCallWaitingTonePlayer != null) {
- mCallWaitingTonePlayer.stopTone();
- mCallWaitingTonePlayer = null;
- }
-
// If this is the end of an OTASP call, pass it on to the PhoneApp.
if (c != null && TelephonyCapabilities.supportsOtasp(c.getCall().getPhone())) {
final String number = c.getAddress();
@@ -1542,107 +1435,6 @@
}
/**
- * Plays a Call waiting tone if it is present in the second incoming call.
- */
- private void onCdmaCallWaiting(AsyncResult r) {
- // Remove any previous Call waiting timers in the queue
- removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
- removeMessages(CALLWAITING_ADDCALL_DISABLE_TIMEOUT);
-
- // Set the Phone Call State to SINGLE_ACTIVE as there is only one connection
- // else we would not have received Call waiting
- mApplication.cdmaPhoneCallState.setCurrentCallState(
- CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE);
-
- // Start timer for CW display
- mCallWaitingTimeOut = false;
- sendEmptyMessageDelayed(CALLWAITING_CALLERINFO_DISPLAY_DONE,
- CALLWAITING_CALLERINFO_DISPLAY_TIME);
-
- // Set the mAddCallMenuStateAfterCW state to false
- mApplication.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(false);
-
- // Start the timer for disabling "Add Call" menu option
- sendEmptyMessageDelayed(CALLWAITING_ADDCALL_DISABLE_TIMEOUT,
- CALLWAITING_ADDCALL_DISABLE_TIME);
-
- // Extract the Call waiting information
- CdmaCallWaitingNotification infoCW = (CdmaCallWaitingNotification) r.result;
- int isPresent = infoCW.isPresent;
- if (DBG) log("onCdmaCallWaiting: isPresent=" + isPresent);
- if (isPresent == 1 ) {//'1' if tone is valid
- int uSignalType = infoCW.signalType;
- int uAlertPitch = infoCW.alertPitch;
- int uSignal = infoCW.signal;
- if (DBG) log("onCdmaCallWaiting: uSignalType=" + uSignalType + ", uAlertPitch="
- + uAlertPitch + ", uSignal=" + uSignal);
- //Map the Signal to a ToneGenerator ToneID only if Signal info is present
- int toneID =
- SignalToneUtil.getAudioToneFromSignalInfo(uSignalType, uAlertPitch, uSignal);
-
- //Create the SignalInfo tone player and pass the ToneID
- new SignalInfoTonePlayer(toneID).start();
- }
-
- // TODO: Remove this.
- //mCallModeler.onCdmaCallWaiting(infoCW);
- }
-
- /**
- * Posts a event causing us to clean up after rejecting (or timing-out) a
- * CDMA call-waiting call.
- *
- * This method is safe to call from any thread.
- * @see #onCdmaCallWaitingReject()
- */
- /* package */ void sendCdmaCallWaitingReject() {
- sendEmptyMessage(CDMA_CALL_WAITING_REJECT);
- }
-
- /**
- * Performs Call logging based on Timeout or Ignore Call Waiting Call for CDMA,
- * and finally calls Hangup on the Call Waiting connection.
- *
- * This method should be called only from the UI thread.
- * @see #sendCdmaCallWaitingReject()
- */
- private void onCdmaCallWaitingReject() {
- final Call ringingCall = mCM.getFirstActiveRingingCall();
-
- // Call waiting timeout scenario
- if (ringingCall.getState() == Call.State.WAITING) {
- // Code for perform Call logging and missed call notification
- Connection c = ringingCall.getLatestConnection();
-
- if (c != null) {
- final int callLogType = mCallWaitingTimeOut ?
- Calls.MISSED_TYPE : Calls.INCOMING_TYPE;
-
- // TODO: This callLogType override is not ideal. Connection should be astracted away
- // at a telephony-phone layer that can understand and edit the callTypes within
- // the abstraction for CDMA devices.
- mCallLogger.logCall(c, callLogType);
-
- if (callLogType != Calls.MISSED_TYPE) {
- // Remove Call waiting 20 second display timer in the queue
- removeMessages(CALLWAITING_CALLERINFO_DISPLAY_DONE);
- }
-
- // Hangup the RingingCall connection for CW
- PhoneUtils.hangup(c);
- }
-
- //Reset the mCallWaitingTimeOut boolean
- mCallWaitingTimeOut = false;
- }
-
- // Call modeler needs to know about this event regardless of the
- // state conditionals in the previous code.
- // TODO: Remove this.
- //mCallModeler.onCdmaCallWaitingReject();
- }
-
- /**
* Return the private variable mPreviousCdmaCallState.
*/
/* package */ Call.State getPreviousCdmaCallState() {
diff --git a/src/com/android/phone/Constants.java b/src/com/android/phone/Constants.java
index 3e10c3a..79a1e9a 100644
--- a/src/com/android/phone/Constants.java
+++ b/src/com/android/phone/Constants.java
@@ -125,16 +125,6 @@
}
//
- // URI schemes
- //
-
- public static final String SCHEME_SIP = "sip";
- public static final String SCHEME_SMS = "sms";
- public static final String SCHEME_SMSTO = "smsto";
- public static final String SCHEME_TEL = "tel";
- public static final String SCHEME_VOICEMAIL = "voicemail";
-
- //
// TODO: Move all the various EXTRA_* and intent action constants here too.
// (Currently they're all over the place: InCallScreen,
// OutgoingCallBroadcaster, OtaUtils, etc.)
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index bed49a9..ca42f2a 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -30,6 +30,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.text.Editable;
import android.text.TextUtils;
@@ -213,7 +214,7 @@
// Extract phone number from intent
Uri data = getIntent().getData();
- if (data != null && (Constants.SCHEME_TEL.equals(data.getScheme()))) {
+ if (data != null && (PhoneAccount.SCHEME_TEL.equals(data.getScheme()))) {
String number = PhoneNumberUtils.getNumberFromIntent(getIntent(), this);
if (number != null) {
mDigits.setText(number);
@@ -520,7 +521,7 @@
return;
}
Intent intent = new Intent(Intent.ACTION_CALL_EMERGENCY);
- intent.setData(Uri.fromParts(Constants.SCHEME_TEL, mLastNumber, null));
+ intent.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, mLastNumber, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 1806558..e6fc11c 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -330,22 +330,13 @@
android.util.Log.d(LOG_TAG, "keep ltePref");
}
- // Enable enhanced 4G LTE mode settings depending on the value in config.xml
- final boolean isEnhanced4GLteModeEnabled = getResources().getBoolean(
- R.bool.config_enhanced_4g_lte_mode_enable);
- if (!isEnhanced4GLteModeEnabled) {
+ // Enable enhanced 4G LTE mode settings depending on whether exists on platform
+ if (!ImsManager.isEnhanced4gLteModeSettingEnabledByPlatform(this)) {
Preference pref = prefSet.findPreference(BUTTON_4G_LTE_KEY);
if (pref != null) {
prefSet.removePreference(pref);
}
}
- Preference pref = prefSet.findPreference(BUTTON_4G_LTE_KEY);
- if (pref != null) {
- if (!ImsManager.isEnhanced4gLteModeSettingEnabledByPlatform(this)) {
- ((SwitchPreference)pref).setChecked(false);
- pref.setEnabled(false);
- }
- }
ActionBar actionBar = getActionBar();
if (actionBar != null) {
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 6650892..668038c 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -40,6 +40,7 @@
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.Settings;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
import android.text.BidiFormatter;
@@ -322,7 +323,7 @@
}
Intent intent = new Intent(Intent.ACTION_CALL,
- Uri.fromParts(Constants.SCHEME_VOICEMAIL, "", null));
+ Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null));
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
diff --git a/src/com/android/phone/OtaUtils.java b/src/com/android/phone/OtaUtils.java
index fe11831..4a9154f 100644
--- a/src/com/android/phone/OtaUtils.java
+++ b/src/com/android/phone/OtaUtils.java
@@ -37,6 +37,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.telecomm.PhoneAccount;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
@@ -687,7 +688,7 @@
if (!mApplication.cdmaOtaProvisionData.inOtaSpcState) {
// Place an outgoing call to the special OTASP number:
Intent newIntent = new Intent(Intent.ACTION_CALL);
- newIntent.setData(Uri.fromParts(Constants.SCHEME_TEL, OTASP_NUMBER, null));
+ newIntent.setData(Uri.fromParts(PhoneAccount.SCHEME_TEL, OTASP_NUMBER, null));
// Initiate the outgoing call:
mApplication.callController.placeCall(newIntent);
diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index 6d8830e..0f47c12 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -35,6 +35,7 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -607,7 +608,7 @@
// a plain address, whether it could be a tel: URI, etc.)
Uri uri = intent.getData();
String scheme = uri.getScheme();
- if (Constants.SCHEME_SIP.equals(scheme) || PhoneNumberUtils.isUriNumber(number)) {
+ if (PhoneAccount.SCHEME_SIP.equals(scheme) || PhoneNumberUtils.isUriNumber(number)) {
Log.i(TAG, "The requested number was detected as SIP call.");
startSipCallOptionHandler(this, intent, uri, number);
finish();
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 98db518..99cb206 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -113,14 +113,12 @@
private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
private static final int CMD_SEND_ENVELOPE = 25;
private static final int EVENT_SEND_ENVELOPE_DONE = 26;
- private static final int CMD_SET_CDMA_SUBSCRIPTION = 27;
- private static final int EVENT_SET_CDMA_SUBSCRIPTION_DONE = 28;
- private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 29;
- private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 30;
- private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 31;
- private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 32;
- private static final int CMD_EXCHANGE_SIM_IO = 33;
- private static final int EVENT_EXCHANGE_SIM_IO_DONE = 34;
+ private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
+ private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
+ private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
+ private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
+ private static final int CMD_EXCHANGE_SIM_IO = 31;
+ private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
/** The singleton instance. */
private static PhoneInterfaceManager sInstance;
@@ -582,17 +580,6 @@
handleNullReturnEvent(msg, "setPreferredNetworkType");
break;
- case CMD_SET_CDMA_SUBSCRIPTION:
- request = (MainThreadRequest) msg.obj;
- onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_DONE, request);
- int subscriptionType = (Integer) request.argument;
- mPhone.setCdmaSubscription(subscriptionType, onCompleted);
- break;
-
- case EVENT_SET_CDMA_SUBSCRIPTION_DONE:
- handleNullReturnEvent(msg, "setCdmaSubscription");
- break;
-
case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
request = (MainThreadRequest)msg.obj;
onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
@@ -1878,31 +1865,6 @@
}
/**
- * Set the CDMA subscription source.
- * Used for device supporting both NV and RUIM for CDMA.
- *
- * @param subscriptionType the subscription type, 0 for RUIM, 1 for NV.
- * @return true on success; false on any failure.
- */
- @Override
- public boolean setCdmaSubscription(int subscriptionType) {
- enforceModifyPermissionOrCarrierPrivilege();
- if (DBG) log("setCdmaSubscription: type " + subscriptionType);
- if (subscriptionType != mPhone.CDMA_SUBSCRIPTION_RUIM_SIM &&
- subscriptionType != mPhone.CDMA_SUBSCRIPTION_NV) {
- loge("setCdmaSubscription: unsupported subscriptionType.");
- return false;
- }
- Boolean success = (Boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION, subscriptionType);
- if (DBG) log("setCdmaSubscription: " + (success ? "ok" : "fail"));
- if (success) {
- Settings.Global.putInt(mPhone.getContext().getContentResolver(),
- Settings.Global.CDMA_SUBSCRIPTION_MODE, subscriptionType);
- }
- return success;
- }
-
- /**
* Set mobile data enabled
* Used by the user through settings etc to turn on/off mobile data
*
@@ -2016,9 +1978,9 @@
}
@Override
- public boolean setOperatorBrandOverride(String iccId, String brand) {
+ public boolean setOperatorBrandOverride(String brand) {
enforceModifyPermissionOrCarrierPrivilege();
- return mPhone.setOperatorBrandOverride(iccId, brand);
+ return mPhone.setOperatorBrandOverride(brand);
}
@Override
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index ae40087..2b864cc 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -33,6 +33,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
+import android.telecomm.PhoneAccount;
import android.telecomm.VideoProfile;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
@@ -367,27 +368,6 @@
// Regular incoming call (with no other active calls)
log("hangupRingingCall(): regular incoming call: hangup()");
return hangup(ringing);
- } else if (state == Call.State.WAITING) {
- // Call-waiting: there's an incoming call, but another call is
- // already active.
- // TODO: It would be better for the telephony layer to provide
- // a "hangupWaitingCall()" API that works on all devices,
- // rather than us having to check the phone type here and do
- // the notifier.sendCdmaCallWaitingReject() hack for CDMA phones.
- if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- // CDMA: Ringing call and Call waiting hangup is handled differently.
- // For Call waiting we DO NOT call the conventional hangup(call) function
- // as in CDMA we just want to hangup the Call waiting connection.
- log("hangupRingingCall(): CDMA-specific call-waiting hangup");
- final CallNotifier notifier = PhoneGlobals.getInstance().notifier;
- notifier.sendCdmaCallWaitingReject();
- return true;
- } else {
- // Otherwise, the regular hangup() API works for
- // call-waiting calls too.
- log("hangupRingingCall(): call-waiting call: hangup()");
- return hangup(ringing);
- }
} else {
// Unexpected state: the ringing call isn't INCOMING or
// WAITING, so there's no reason to have called
@@ -618,7 +598,7 @@
if (useGateway) {
// TODO: 'tel' should be a constant defined in framework base
// somewhere (it is in webkit.)
- if (null == gatewayUri || !Constants.SCHEME_TEL.equals(gatewayUri.getScheme())) {
+ if (null == gatewayUri || !PhoneAccount.SCHEME_TEL.equals(gatewayUri.getScheme())) {
Log.e(LOG_TAG, "Unsupported URL:" + gatewayUri);
return CALL_STATUS_FAILED;
}
@@ -1255,7 +1235,7 @@
// The sip: scheme is simple: just treat the rest of the URI as a
// SIP address.
- if (Constants.SCHEME_SIP.equals(scheme)) {
+ if (PhoneAccount.SCHEME_SIP.equals(scheme)) {
return uri.getSchemeSpecificPart();
}
@@ -1266,7 +1246,7 @@
// Check for a voicemail-dialing request. If the voicemail number is
// empty, throw a VoiceMailNumberMissingException.
- if (Constants.SCHEME_VOICEMAIL.equals(scheme) &&
+ if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme) &&
(number == null || TextUtils.isEmpty(number)))
throw new VoiceMailNumberMissingException();
diff --git a/src/com/android/phone/SimContacts.java b/src/com/android/phone/SimContacts.java
index bebb6ea..cc2b992 100644
--- a/src/com/android/phone/SimContacts.java
+++ b/src/com/android/phone/SimContacts.java
@@ -38,6 +38,7 @@
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
+import android.telecomm.PhoneAccount;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
@@ -345,7 +346,7 @@
return true;
}
Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
- Uri.fromParts(Constants.SCHEME_TEL, phoneNumber, null));
+ Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
diff --git a/src/com/android/services/telephony/CdmaConference.java b/src/com/android/services/telephony/CdmaConference.java
new file mode 100644
index 0000000..90f8566
--- /dev/null
+++ b/src/com/android/services/telephony/CdmaConference.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony;
+
+import android.telecomm.Conference;
+import android.telecomm.Connection;
+import android.telecomm.PhoneAccountHandle;
+import android.telecomm.PhoneCapabilities;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
+
+import java.util.List;
+
+/**
+ * CDMA-based conference call.
+ */
+public class CdmaConference extends Conference {
+
+ private int mCapabilities =
+ PhoneCapabilities.MUTE |
+ PhoneCapabilities.MERGE_CONFERENCE;
+
+ public CdmaConference(PhoneAccountHandle phoneAccount) {
+ super(phoneAccount);
+ updateCapabilities();
+ setActive();
+ }
+
+ private void updateCapabilities() {
+ setCapabilities(mCapabilities);
+ }
+ /**
+ * Invoked when the Conference and all it's {@link Connection}s should be disconnected.
+ */
+ @Override
+ public void onDisconnect() {
+ Call call = getOriginalCall();
+ if (call != null) {
+ Log.d(this, "Found multiparty call to hangup for conference.");
+ try {
+ call.hangup();
+ } catch (CallStateException e) {
+ Log.e(this, e, "Exception thrown trying to hangup conference");
+ }
+ }
+ }
+
+ @Override
+ public void onSeparate(Connection connection) {
+ Log.e(this, new Exception(), "Separate not supported for CDMA conference call.");
+ }
+
+ @Override
+ public void onHold() {
+ Log.e(this, new Exception(), "Hold not supported for CDMA conference call.");
+ }
+
+ /**
+ * Invoked when the conference should be moved from hold to active.
+ */
+ @Override
+ public void onUnhold() {
+ Log.e(this, new Exception(), "Unhold not supported for CDMA conference call.");
+ }
+
+ @Override
+ public void onMerge() {
+ Log.i(this, "Merging CDMA conference call.");
+ // Can only merge once
+ mCapabilities &= ~PhoneCapabilities.MERGE_CONFERENCE;
+ // Once merged, swap is enabled.
+ mCapabilities |= PhoneCapabilities.SWAP_CONFERENCE;
+ updateCapabilities();
+ sendFlash();
+ }
+
+ @Override
+ public void onSwap() {
+ Log.i(this, "Swapping CDMA conference call.");
+ sendFlash();
+ }
+
+ private void sendFlash() {
+ Call call = getOriginalCall();
+ if (call != null) {
+ try {
+ // For CDMA calls, this just sends a flash command.
+ call.getPhone().switchHoldingAndActive();
+ } catch (CallStateException e) {
+ Log.e(this, e, "Error while trying to send flash command.");
+ }
+ }
+ }
+
+ private Call getMultipartyCallForConnection(Connection connection) {
+ com.android.internal.telephony.Connection radioConnection =
+ getOriginalConnection(connection);
+ if (radioConnection != null) {
+ Call call = radioConnection.getCall();
+ if (call != null && call.isMultiparty()) {
+ return call;
+ }
+ }
+ return null;
+ }
+
+ private Call getOriginalCall() {
+ List<Connection> connections = getConnections();
+ if (!connections.isEmpty()) {
+ com.android.internal.telephony.Connection originalConnection =
+ getOriginalConnection(connections.get(0));
+ if (originalConnection != null) {
+ return originalConnection.getCall();
+ }
+ }
+ return null;
+ }
+
+ private com.android.internal.telephony.Connection getOriginalConnection(Connection connection) {
+ if (connection instanceof CdmaConnection) {
+ return ((CdmaConnection) connection).getOriginalConnection();
+ } else {
+ Log.e(this, null, "Non CDMA connection found in a CDMA conference");
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
new file mode 100644
index 0000000..e3a0981
--- /dev/null
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony;
+
+import android.os.Handler;
+import android.telecomm.Connection;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages CDMA conference calls. CDMA conference calls are much more limited than GSM conference
+ * calls. Two main points of difference:
+ * 1) Users cannot manage individual calls within a conference
+ * 2) Whether a conference call starts off as a conference or as two distinct calls is a matter of
+ * physical location (some antennas are different than others). Worst still, there's no
+ * indication given to us as to what state they are in.
+ *
+ * To make life easier on the user we do the following: Whenever there exist 2 or more calls, we
+ * say that we are in a conference call with {@link Connection#CAPABILITY_GENERIC_CONFERENCE}.
+ * Generic indicates that this is a simple conference that doesn't support conference management.
+ * The conference call will also support "MERGE" to begin with and stop supporting it the first time
+ * we are asked to actually execute a merge. I emphasize when "we are asked" because we get no
+ * indication whether the merge succeeds from CDMA, we just assume it does. Thats the best we
+ * can do. Also, we do not kill a conference call once it is created unless all underlying
+ * connections also go away.
+ *
+ * Outgoing CDMA calls made while another call exists would normally trigger a conference to be
+ * created. To avoid this and make it seem like there is a "dialing" state, we fake it and prevent
+ * the conference from being created for 3 seconds. This is a more pleasant experience for the user.
+ */
+final class CdmaConferenceController {
+ private final Connection.Listener mConnectionListener = new Connection.Listener() {
+ @Override
+ public void onStateChanged(Connection c, int state) {
+ recalculateConference();
+ }
+
+ @Override
+ public void onDisconnected(Connection c, int cause, String message) {
+ recalculateConference();
+ }
+
+ @Override
+ public void onDestroyed(Connection c) {
+ remove((CdmaConnection) c);
+ }
+ };
+
+ private static final int ADD_OUTGOING_CONNECTION_DELAY_MILLIS = 6000;
+
+ /** The known CDMA connections. */
+ private final List<CdmaConnection> mCdmaConnections = new ArrayList<>();
+
+ /**
+ * Newly added connections. We keep track of newly added outgoing connections because we do not
+ * create a conference until a second outgoing call has existing for
+ * {@link #ADD_OUTGOING_CONNECTION_DELAY_MILLIS} milliseconds. This allows the UI to show the
+ * call as "Dialing" for a certain amount of seconds.
+ */
+ private final List<CdmaConnection> mPendingOutgoingConnections = new ArrayList<>();
+
+ private final TelephonyConnectionService mConnectionService;
+
+ private final Handler mHandler = new Handler();
+
+ public CdmaConferenceController(TelephonyConnectionService connectionService) {
+ mConnectionService = connectionService;
+ }
+
+ /** The CDMA conference connection object. */
+ private CdmaConference mConference;
+
+ void add(final CdmaConnection connection) {
+ if (!mCdmaConnections.isEmpty() && connection.isOutgoing()) {
+ connection.forceAsDialing(true);
+ // There already exists a connection, so this will probably result in a conference once
+ // it is added. For connections which are added while another connection exists, we
+ // mark them as "dialing" for set amount of time to give the user time to see their
+ // new call as "Dialing" before it turns into a conference call.
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ connection.forceAsDialing(false);
+ addInternal(connection);
+ }
+ }, ADD_OUTGOING_CONNECTION_DELAY_MILLIS);
+ } else {
+ // This is the first connection, or it is incoming, so let it flow through.
+ addInternal(connection);
+ }
+ }
+
+ private void addInternal(CdmaConnection connection) {
+ mCdmaConnections.add(connection);
+ connection.addConnectionListener(mConnectionListener);
+ recalculateConference();
+ }
+
+ private void remove(CdmaConnection connection) {
+ connection.removeConnectionListener(mConnectionListener);
+ mCdmaConnections.remove(connection);
+ recalculateConference();
+ }
+
+ private void recalculateConference() {
+ List<CdmaConnection> conferenceConnections = new ArrayList<>(mCdmaConnections.size());
+ for (CdmaConnection connection : mCdmaConnections) {
+ // We do not include call-waiting calls in conferences.
+ if (!connection.isCallWaiting() &&
+ connection.getState() != Connection.STATE_DISCONNECTED) {
+ conferenceConnections.add(connection);
+ }
+ }
+
+ Log.d(this, "recalculating conference calls %d", conferenceConnections.size());
+ if (conferenceConnections.size() >= 2) {
+ boolean isNewlyCreated = false;
+
+ // There are two or more CDMA connections. Do the following:
+ // 1) Create a new conference connection if it doesn't exist.
+ if (mConference == null) {
+ Log.i(this, "Creating new Cdma conference call");
+ mConference = new CdmaConference(null);
+ isNewlyCreated = true;
+ }
+
+ // 2) Add any new connections to the conference
+ List<Connection> existingChildConnections =
+ new ArrayList<>(mConference.getConnections());
+ for (CdmaConnection connection : conferenceConnections) {
+ if (!existingChildConnections.contains(connection)) {
+ Log.i(this, "Adding connection to conference call: %s", connection);
+ mConference.addConnection(connection);
+ }
+ existingChildConnections.remove(connection);
+ }
+
+ // 3) Remove any lingering old/disconnected/destroyed connections
+ for (Connection oldConnection : existingChildConnections) {
+ mConference.removeConnection(oldConnection);
+ Log.i(this, "Removing connection from conference call: %s", oldConnection);
+ }
+
+ // 4) Add the conference to the connection service if it is new.
+ if (isNewlyCreated) {
+ Log.d(this, "Adding the conference call");
+ mConnectionService.addConference(mConference);
+ }
+ } else if (conferenceConnections.isEmpty()) {
+ // There are no more connection so if we still have a conference, lets remove it.
+ if (mConference != null) {
+ Log.i(this, "Destroying the CDMA conference connection.");
+ mConference.destroy();
+ }
+ }
+ }
+}
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 67104b5..12ccbce 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -16,8 +16,14 @@
package com.android.services.telephony;
+import android.os.Handler;
+import android.os.Message;
import android.telecomm.PhoneCapabilities;
+import android.telephony.DisconnectCause;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Connection;
/**
@@ -25,14 +31,41 @@
*/
final class CdmaConnection extends TelephonyConnection {
+ private static final int MSG_CALL_WAITING_MISSED = 1;
+ private static final int TIMEOUT_CALL_WAITING_MILLIS = 20 * 1000;
+
+ private final Handler mHandler = new Handler() {
+
+ /** ${inheritDoc} */
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CALL_WAITING_MISSED:
+ hangupCallWaiting(DisconnectCause.INCOMING_MISSED);
+ break;
+ default:
+ break;
+ }
+ }
+
+ };
+
/**
* {@code True} if the CDMA connection should allow mute.
*/
private final boolean mAllowMute;
+ private final boolean mIsOutgoing;
- CdmaConnection(Connection connection, boolean allowMute) {
+ private boolean mIsCallWaiting;
+
+ CdmaConnection(Connection connection, boolean allowMute, boolean isOutgoing) {
super(connection);
mAllowMute = allowMute;
+ mIsOutgoing = isOutgoing;
+ mIsCallWaiting = connection != null && connection.getState() == Call.State.WAITING;
+ if (mIsCallWaiting) {
+ startCallWaitingTimer();
+ }
}
/** {@inheritDoc} */
@@ -55,6 +88,41 @@
}
@Override
+ public void onReject() {
+ Connection connection = getOriginalConnection();
+ if (connection != null) {
+ switch (connection.getState()) {
+ case INCOMING:
+ // Normal ringing calls are handled the generic way.
+ super.onReject();
+ break;
+ case WAITING:
+ hangupCallWaiting(DisconnectCause.INCOMING_REJECTED);
+ break;
+ default:
+ Log.e(this, new Exception(), "Rejecting a non-ringing call");
+ // might as well hang this up, too.
+ super.onReject();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onAnswer() {
+ mHandler.removeMessages(MSG_CALL_WAITING_MISSED);
+ super.onAnswer();
+ }
+
+ @Override
+ public void onSetState(int state) {
+ Connection originalConnection = getOriginalConnection();
+ mIsCallWaiting = originalConnection != null &&
+ originalConnection.getState() == Call.State.WAITING;
+ super.onSetState(state);
+ }
+
+ @Override
protected int buildCallCapabilities() {
int capabilities = 0;
if (mAllowMute) {
@@ -62,4 +130,42 @@
}
return capabilities;
}
+
+ void forceAsDialing(boolean isDialing) {
+ if (isDialing) {
+ setDialing();
+ } else {
+ updateState();
+ }
+ }
+
+ boolean isOutgoing() {
+ return mIsOutgoing;
+ }
+
+ boolean isCallWaiting() {
+ return mIsCallWaiting;
+ }
+
+ /**
+ * We do not get much in the way of confirmation for Cdma call waiting calls. There is no
+ * indication that a rejected call succeeded, a call waiting call has stopped. Instead we
+ * simulate this for the user. We allow TIMEOUT_CALL_WAITING_MILLIS milliseconds before we
+ * assume that the call was missed and reject it ourselves. reject the call automatically.
+ */
+ private void startCallWaitingTimer() {
+ mHandler.sendEmptyMessageDelayed(MSG_CALL_WAITING_MISSED, TIMEOUT_CALL_WAITING_MILLIS);
+ }
+
+ private void hangupCallWaiting(int disconnectCause) {
+ Connection originalConnection = getOriginalConnection();
+ if (originalConnection != null) {
+ try {
+ originalConnection.hangup();
+ } catch (CallStateException e) {
+ Log.e(this, e, "Failed to hangup call waiting call");
+ }
+ setDisconnected(disconnectCause, null);
+ }
+ }
}
diff --git a/src/com/android/services/telephony/GsmConference.java b/src/com/android/services/telephony/GsmConference.java
index a45b896..00e46fa 100644
--- a/src/com/android/services/telephony/GsmConference.java
+++ b/src/com/android/services/telephony/GsmConference.java
@@ -37,7 +37,7 @@
PhoneCapabilities.SUPPORT_HOLD |
PhoneCapabilities.HOLD |
PhoneCapabilities.MUTE |
- PhoneCapabilities.SWAP_CALLS);
+ PhoneCapabilities.MANAGE_CONFERENCE);
setActive();
}
diff --git a/src/com/android/services/telephony/GsmConnection.java b/src/com/android/services/telephony/GsmConnection.java
index 99f2cde..ecd851e 100644
--- a/src/com/android/services/telephony/GsmConnection.java
+++ b/src/com/android/services/telephony/GsmConnection.java
@@ -25,8 +25,6 @@
* Manages a single phone call handled by GSM.
*/
final class GsmConnection extends TelephonyConnection {
- private boolean mIsConferenceCapable;
-
GsmConnection(Connection connection) {
super(connection);
}
@@ -47,13 +45,6 @@
}
}
- void setIsConferenceCapable(boolean isConferenceCapable) {
- if (mIsConferenceCapable != isConferenceCapable) {
- mIsConferenceCapable = isConferenceCapable;
- updateCallCapabilities();
- }
- }
-
@Override
public void performConference(TelephonyConnection otherConnection) {
Log.d(this, "performConference - %s", this);
@@ -77,9 +68,6 @@
if (getState() == STATE_ACTIVE || getState() == STATE_HOLDING) {
capabilities |= PhoneCapabilities.HOLD;
}
- if (mIsConferenceCapable) {
- capabilities |= PhoneCapabilities.MERGE_CALLS;
- }
return capabilities;
}
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index f64dedf..73bc3a9 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -33,8 +33,11 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.google.common.base.Preconditions;
+import java.util.Objects;
+
/**
* Listens to incoming-call events from the associated phone object and notifies Telecomm upon each
* occurence. One instance of these exists for each of the telephony-based call services.
@@ -42,6 +45,7 @@
final class PstnIncomingCallNotifier {
/** New ringing connection event code. */
private static final int EVENT_NEW_RINGING_CONNECTION = 100;
+ private static final int EVENT_CDMA_CALL_WAITING = 101;
/** The phone proxy object to listen to. */
private final PhoneProxy mPhoneProxy;
@@ -64,6 +68,9 @@
case EVENT_NEW_RINGING_CONNECTION:
handleNewRingingConnection((AsyncResult) msg.obj);
break;
+ case EVENT_CDMA_CALL_WAITING:
+ handleCdmaCallWaiting((AsyncResult) msg.obj);
+ break;
default:
break;
}
@@ -121,23 +128,24 @@
private void registerForNotifications() {
Phone newPhone = mPhoneProxy.getActivePhone();
if (newPhone != mPhoneBase) {
- if (mPhoneBase != null) {
- Log.i(this, "Unregistering: %s", mPhoneBase);
- mPhoneBase.unregisterForNewRingingConnection(mHandler);
- }
+ unregisterForNotifications();
if (newPhone != null) {
Log.i(this, "Registering: %s", newPhone);
mPhoneBase = newPhone;
mPhoneBase.registerForNewRingingConnection(
mHandler, EVENT_NEW_RINGING_CONNECTION, null);
+ mPhoneBase.registerForCallWaiting(
+ mHandler, EVENT_CDMA_CALL_WAITING, null);
}
}
}
private void unregisterForNotifications() {
if (mPhoneBase != null) {
+ Log.i(this, "Unregistering: %s", mPhoneBase);
mPhoneBase.unregisterForNewRingingConnection(mHandler);
+ mPhoneBase.unregisterForCallWaiting(mHandler);
}
}
@@ -159,6 +167,21 @@
}
}
+ private void handleCdmaCallWaiting(AsyncResult asyncResult) {
+ Log.d(this, "handleCdmaCallWaiting");
+ CdmaCallWaitingNotification ccwi = (CdmaCallWaitingNotification) asyncResult.result;
+ Call call = mPhoneBase.getRingingCall();
+ if (call.getState() == Call.State.WAITING) {
+ Connection connection = call.getLatestConnection();
+ if (connection != null) {
+ String number = connection.getAddress();
+ if (number != null && Objects.equals(number, ccwi.number)) {
+ sendIncomingCallIntent(connection);
+ }
+ }
+ }
+ }
+
/**
* Sends the incoming call intent to telecomm.
*/
diff --git a/src/com/android/services/telephony/TelecommAccountRegistry.java b/src/com/android/services/telephony/TelecommAccountRegistry.java
index 095073b..1eaf6e1 100644
--- a/src/com/android/services/telephony/TelecommAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecommAccountRegistry.java
@@ -97,7 +97,7 @@
: dummyPrefix + "SIM card in slot " + slotId;
PhoneAccount account = PhoneAccount.builder()
.withAccountHandle(phoneAccountHandle)
- .withHandle(Uri.fromParts(TEL_SCHEME, line1Number, null))
+ .withHandle(Uri.fromParts(PhoneAccount.SCHEME_TEL, line1Number, null))
.withSubscriptionNumber(subNumber)
.withCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
PhoneAccount.CAPABILITY_CALL_PROVIDER)
@@ -132,8 +132,6 @@
}
};
- private static final String TEL_SCHEME = "tel";
- private static final String VOICEMAIL_SCHEME = "voicemail";
private static TelecommAccountRegistry sInstance;
private final Context mContext;
private final TelecommManager mTelecommManager;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 9cbf8a6..60e5d17 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -22,6 +22,7 @@
import android.os.Message;
import android.telecomm.AudioState;
import android.telecomm.Connection;
+import android.telecomm.PhoneAccount;
import android.telecomm.PhoneCapabilities;
import android.telephony.DisconnectCause;
@@ -222,9 +223,6 @@
@Override
public void onAnswer(int videoState) {
Log.v(this, "onAnswer");
- // TODO: Tons of hairy logic is missing here around multiple active calls on
- // CDMA devices. See {@link CallManager.acceptCall}.
-
if (isValidRingingCall() && getPhone() != null) {
try {
getPhone().acceptCall(videoState);
@@ -390,7 +388,7 @@
updateHandle();
}
- private void hangup(int disconnectCause) {
+ protected void hangup(int disconnectCause) {
if (mOriginalConnection != null) {
try {
// Hanging up a ringing call requires that we invoke call.hangup() as opposed to
@@ -490,7 +488,7 @@
return true;
}
- private void updateState() {
+ protected void updateState() {
if (mOriginalConnection == null) {
return;
}
@@ -642,7 +640,7 @@
if (address == null) {
address = "";
}
- return Uri.fromParts(TelephonyConnectionService.SCHEME_TEL, address, null);
+ return Uri.fromParts(PhoneAccount.SCHEME_TEL, address, null);
}
/**
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index f77666a..5d96665 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -20,11 +20,10 @@
import android.content.Intent;
import android.net.Uri;
import android.telecomm.Connection;
-import android.telecomm.PhoneCapabilities;
import android.telecomm.ConnectionRequest;
import android.telecomm.ConnectionService;
+import android.telecomm.PhoneAccount;
import android.telecomm.PhoneAccountHandle;
-import android.telecomm.Response;
import android.telephony.DisconnectCause;
import android.telephony.PhoneNumberUtils;
import android.telephony.ServiceState;
@@ -47,11 +46,10 @@
* Service for making GSM and CDMA connections.
*/
public class TelephonyConnectionService extends ConnectionService {
- static String SCHEME_TEL = "tel";
- static String SCHEME_VOICEMAIL = "voicemail";
-
private final GsmConferenceController mGsmConferenceController =
new GsmConferenceController(this);
+ private final CdmaConferenceController mCdmaConferenceController =
+ new CdmaConferenceController(this);
private ComponentName mExpectedComponentName = null;
private EmergencyCallHelper mEmergencyCallHelper;
@@ -65,7 +63,7 @@
public Connection onCreateOutgoingConnection(
PhoneAccountHandle connectionManagerPhoneAccount,
final ConnectionRequest request) {
- Log.v(this, "onCreateOutgoingConnection, request: " + request);
+ Log.i(this, "onCreateOutgoingConnection, request: " + request);
Uri handle = request.getHandle();
if (handle == null) {
@@ -76,7 +74,7 @@
String scheme = handle.getScheme();
final String number;
- if (SCHEME_VOICEMAIL.equals(scheme)) {
+ if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme)) {
// TODO: We don't check for SecurityException here (requires
// CALL_PRIVILEGED permission).
final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
@@ -88,9 +86,9 @@
}
// Convert voicemail: to tel:
- handle = Uri.fromParts(SCHEME_TEL, number, null);
+ handle = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null);
} else {
- if (!SCHEME_TEL.equals(scheme)) {
+ if (!PhoneAccount.SCHEME_TEL.equals(scheme)) {
Log.d(this, "onCreateOutgoingConnection, Handle %s is not type tel", scheme);
return Connection.createFailedConnection(DisconnectCause.INVALID_NUMBER,
"Handle scheme is not type tel");
@@ -139,7 +137,8 @@
}
}
- final TelephonyConnection connection = createConnectionFor(phone, null);
+ final TelephonyConnection connection =
+ createConnectionFor(phone, null, true /* isOutgoing */);
if (connection == null) {
return Connection.createFailedConnection(
DisconnectCause.OUTGOING_FAILURE, "Invalid phone type");
@@ -181,7 +180,7 @@
public Connection onCreateIncomingConnection(
PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
- Log.v(this, "onCreateIncomingConnection, request: " + request);
+ Log.i(this, "onCreateIncomingConnection, request: " + request);
Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
if (phone == null) {
@@ -190,18 +189,21 @@
Call call = phone.getRingingCall();
if (!call.getState().isRinging()) {
- Log.v(this, "onCreateIncomingConnection, no ringing call");
+ Log.i(this, "onCreateIncomingConnection, no ringing call");
return Connection.createFailedConnection(DisconnectCause.INCOMING_MISSED,
"Found no ringing call");
}
- com.android.internal.telephony.Connection originalConnection = call.getEarliestConnection();
+ com.android.internal.telephony.Connection originalConnection =
+ call.getState() == Call.State.WAITING ?
+ call.getLatestConnection() : call.getEarliestConnection();
if (isOriginalConnectionKnown(originalConnection)) {
- Log.v(this, "onCreateIncomingConnection, original connection already registered");
+ Log.i(this, "onCreateIncomingConnection, original connection already registered");
return Connection.createCanceledConnection();
}
- Connection connection = createConnectionFor(phone, originalConnection);
+ Connection connection =
+ createConnectionFor(phone, originalConnection, false /* isOutgoing */);
if (connection == null) {
connection = Connection.createCanceledConnection();
return Connection.createCanceledConnection();
@@ -253,7 +255,9 @@
}
private TelephonyConnection createConnectionFor(
- Phone phone, com.android.internal.telephony.Connection originalConnection) {
+ Phone phone,
+ com.android.internal.telephony.Connection originalConnection,
+ boolean isOutgoing) {
int phoneType = phone.getPhoneType();
if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
GsmConnection connection = new GsmConnection(originalConnection);
@@ -261,7 +265,10 @@
return connection;
} else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
boolean allowMute = allowMute(phone);
- return new CdmaConnection(originalConnection, allowMute);
+ CdmaConnection connection =
+ new CdmaConnection(originalConnection, allowMute, isOutgoing);
+ mCdmaConferenceController.add(connection);
+ return connection;
} else {
return null;
}
diff --git a/tests/src/com/android/phone/tests/CallDialTest.java b/tests/src/com/android/phone/tests/CallDialTest.java
index 5ea80d1..baade32 100644
--- a/tests/src/com/android/phone/tests/CallDialTest.java
+++ b/tests/src/com/android/phone/tests/CallDialTest.java
@@ -23,6 +23,7 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telecomm.PhoneAccount;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
@@ -125,9 +126,9 @@
if (number.contains(":")) {
uri = Uri.parse(number);
} else if (PhoneNumberUtils.isUriNumber(number)) {
- uri = Uri.fromParts(Constants.SCHEME_SIP, number, null);
+ uri = Uri.fromParts(PhoneAccount.SCHEME_SIP, number, null);
} else {
- uri = Uri.fromParts(Constants.SCHEME_TEL, number, null);
+ uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null);
}
}
log("==> uri: " + uri);