Merge "Add support for rejecting Telecom call with a specified reason."
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index dd000ce..f5f5c66 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -540,7 +540,7 @@
if (mConferenceHost == null) {
return;
}
- mConferenceHost.performReject();
+ mConferenceHost.performReject(android.telecom.Call.REJECT_REASON_DECLINED);
}
/**
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index f2b2244..2f5e2a6 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -113,6 +113,7 @@
private static final int MSG_SET_CALL_RADIO_TECH = 18;
private static final int MSG_ON_CONNECTION_EVENT = 19;
private static final int MSG_REDIAL_CONNECTION_CHANGED = 20;
+ private static final int MSG_REJECT = 21;
private List<Uri> mParticipants;
private boolean mIsAdhocConferenceCall;
@@ -273,6 +274,10 @@
int cause = (int) msg.obj;
hangup(cause);
break;
+ case MSG_REJECT:
+ int rejectReason = (int) msg.obj;
+ reject(rejectReason);
+ break;
case MSG_SET_CALL_RADIO_TECH:
int vrat = (int) msg.obj;
@@ -926,13 +931,18 @@
@Override
public void onReject() {
- performReject();
+ performReject(android.telecom.Call.REJECT_REASON_DECLINED);
}
- public void performReject() {
+ @Override
+ public void onReject(@android.telecom.Call.RejectReason int rejectReason) {
+ performReject(rejectReason);
+ }
+
+ public void performReject(int rejectReason) {
Log.v(this, "performReject");
if (isValidRingingCall()) {
- mHandler.obtainMessage(MSG_HANGUP, android.telephony.DisconnectCause.INCOMING_REJECTED)
+ mHandler.obtainMessage(MSG_REJECT, rejectReason)
.sendToTarget();
}
super.onReject();
@@ -1678,6 +1688,46 @@
}
}
+ protected void reject(@android.telecom.Call.RejectReason int rejectReason) {
+ if (mOriginalConnection != null) {
+ mHangupDisconnectCause = android.telephony.DisconnectCause.INCOMING_REJECTED;
+ try {
+ // Hanging up a ringing call requires that we invoke call.hangup() as opposed to
+ // connection.hangup(). Without this change, the party originating the call
+ // will not get sent to voicemail if the user opts to reject the call.
+ if (isValidRingingCall()) {
+ Call call = getCall();
+ if (call != null) {
+ call.hangup(rejectReason);
+ } else {
+ Log.w(this, "Attempting to hangup a connection without backing call.");
+ }
+ } else {
+ // We still prefer to call connection.hangup() for non-ringing calls
+ // in order to support hanging-up specific calls within a conference call.
+ // If we invoked call.hangup() while in a conference, we would end up
+ // hanging up the entire conference call instead of the specific connection.
+ mOriginalConnection.hangup();
+ }
+ } catch (CallStateException e) {
+ Log.e(this, e, "Call to Connection.hangup failed with exception");
+ }
+ } else {
+ if (getState() == STATE_DISCONNECTED) {
+ Log.i(this, "hangup called on an already disconnected call!");
+ close();
+ } else {
+ // There are a few cases where mOriginalConnection has not been set yet. For
+ // example, when the radio has to be turned on to make an emergency call,
+ // mOriginalConnection could not be set for many seconds.
+ setTelephonyConnectionDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
+ android.telephony.DisconnectCause.LOCAL,
+ "Local Disconnect before connection established."));
+ close();
+ }
+ }
+ }
+
com.android.internal.telephony.Connection getOriginalConnection() {
return mOriginalConnection;
}