Implement cancelOutgoingCall
Change-Id: I9e5da9c607675bc3c230f6eb6d1cc149a38bf905
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index a6ec347..1169d5a 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -53,14 +53,15 @@
* from the time the call intent was received by Telecomm (vs. the time the call was
* connected etc).
*/
-final class Call {
+final class Call implements OutgoingCallResponse {
/**
* Listener for events on the call.
*/
interface Listener {
void onSuccessfulOutgoingCall(Call call);
- void onFailedOutgoingCall(Call call, boolean isAborted, int errorCode, String errorMsg);
+ void onFailedOutgoingCall(Call call, int errorCode, String errorMsg);
+ void onCancelledOutgoingCall(Call call);
void onSuccessfulIncomingCall(Call call, CallInfo callInfo);
void onFailedIncomingCall(Call call);
void onRequestingRingback(Call call, boolean requestingRingback);
@@ -524,37 +525,39 @@
Preconditions.checkState(mOutgoingCallProcessor == null);
mOutgoingCallProcessor = new OutgoingCallProcessor(
- this,
- Switchboard.getInstance().getCallServiceRepository(),
- new AsyncResultCallback<Boolean>() {
- @Override
- public void onResult(Boolean wasCallPlaced, int errorCode, String errorMsg) {
- if (wasCallPlaced) {
- handleSuccessfulOutgoing();
- } else {
- handleFailedOutgoing(
- mOutgoingCallProcessor.isAborted(), errorCode, errorMsg);
- }
- mOutgoingCallProcessor = null;
- }
- });
+ this, Switchboard.getInstance().getCallServiceRepository(), this);
mOutgoingCallProcessor.process();
}
- void handleSuccessfulOutgoing() {
+ @Override
+ public void onOutgoingCallSuccess() {
// TODO(santoscordon): Replace this with state transitions related to "connecting".
for (Listener l : mListeners) {
l.onSuccessfulOutgoingCall(this);
}
+ mOutgoingCallProcessor = null;
}
- void handleFailedOutgoing(boolean isAborted, int errorCode, String errorMsg) {
+ @Override
+ public void onOutgoingCallFailure(int code, String msg) {
// TODO(santoscordon): Replace this with state transitions related to "connecting".
for (Listener l : mListeners) {
- l.onFailedOutgoingCall(this, isAborted, errorCode, errorMsg);
+ l.onFailedOutgoingCall(this, code, msg);
}
clearCallService();
+ mOutgoingCallProcessor = null;
+ }
+
+ @Override
+ public void onOutgoingCallCancel() {
+ // TODO(santoscordon): Replace this with state transitions related to "connecting".
+ for (Listener l : mListeners) {
+ l.onCancelledOutgoingCall(this);
+ }
+
+ clearCallService();
+ mOutgoingCallProcessor = null;
}
/**
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index 5d7b47a..782f7a4 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -61,18 +61,19 @@
private static final int MSG_NOTIFY_INCOMING_CALL = 1;
private static final int MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL = 2;
private static final int MSG_HANDLE_FAILED_OUTGOING_CALL = 3;
- private static final int MSG_SET_ACTIVE = 4;
- private static final int MSG_SET_RINGING = 5;
- private static final int MSG_SET_DIALING = 6;
- private static final int MSG_SET_DISCONNECTED = 7;
- private static final int MSG_SET_ON_HOLD = 8;
- private static final int MSG_SET_REQUESTING_RINGBACK = 9;
- private static final int MSG_ON_POST_DIAL_WAIT = 10;
- private static final int MSG_CAN_CONFERENCE = 11;
- private static final int MSG_SET_IS_CONFERENCED = 12;
- private static final int MSG_ADD_CONFERENCE_CALL = 13;
- private static final int MSG_HANDOFF_CALL = 14;
- private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 15;
+ private static final int MSG_CANCEL_OUTGOING_CALL = 4;
+ private static final int MSG_SET_ACTIVE = 5;
+ private static final int MSG_SET_RINGING = 6;
+ private static final int MSG_SET_DIALING = 7;
+ private static final int MSG_SET_DISCONNECTED = 8;
+ private static final int MSG_SET_ON_HOLD = 9;
+ private static final int MSG_SET_REQUESTING_RINGBACK = 10;
+ private static final int MSG_ON_POST_DIAL_WAIT = 11;
+ private static final int MSG_CAN_CONFERENCE = 12;
+ private static final int MSG_SET_IS_CONFERENCED = 13;
+ private static final int MSG_ADD_CONFERENCE_CALL = 14;
+ private static final int MSG_HANDOFF_CALL = 15;
+ private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 16;
private final Handler mHandler = new Handler() {
@Override
@@ -100,7 +101,7 @@
case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
String callId = (String) msg.obj;
if (mPendingOutgoingCalls.containsKey(callId)) {
- mPendingOutgoingCalls.remove(callId).onResult(true, 0, null);
+ mPendingOutgoingCalls.remove(callId).onOutgoingCallSuccess();
} else {
//Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
}
@@ -115,8 +116,8 @@
// TODO(santoscordon): Do something with 'reason' or get rid of it.
if (mPendingOutgoingCalls.containsKey(callId)) {
- mPendingOutgoingCalls.remove(callId).onResult(
- false, statusCode, statusMsg);
+ mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
+ statusCode, statusMsg);
mCallIdMapper.removeCall(callId);
} else {
//Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
@@ -126,6 +127,15 @@
}
break;
}
+ case MSG_CANCEL_OUTGOING_CALL: {
+ String callId = (String) msg.obj;
+ if (mPendingOutgoingCalls.containsKey(callId)) {
+ mPendingOutgoingCalls.remove(callId).onOutgoingCallCancel();
+ } else {
+ //Log.w(this, "cancelOutgoingCall, unknown call: %s", callId);
+ }
+ break;
+ }
case MSG_SET_ACTIVE:
call = mCallIdMapper.getCall(msg.obj);
if (call != null) {
@@ -306,6 +316,14 @@
/** {@inheritDoc} */
@Override
+ public void cancelOutgoingCall(String callId) {
+ logIncoming("cancelOutgoingCall %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
public void setActive(String callId) {
logIncoming("setActive %s", callId);
mCallIdMapper.checkValidCallId(callId);
@@ -428,7 +446,7 @@
private final CallServiceDescriptor mDescriptor;
private final CallIdMapper mCallIdMapper = new CallIdMapper("CallService");
private final IncomingCallsManager mIncomingCallsManager;
- private final Map<String, AsyncResultCallback<Boolean>> mPendingOutgoingCalls = new HashMap<>();
+ private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
private final Handler mHandler = new Handler();
private Binder mBinder = new Binder();
@@ -472,13 +490,13 @@
* Attempts to place the specified call, see {@link ICallService#call}. Returns the result
* asynchronously through the specified callback.
*/
- void call(final Call call, final AsyncResultCallback<Boolean> resultCallback) {
+ void call(final Call call, final OutgoingCallResponse callResponse) {
Log.d(this, "call(%s) via %s.", call, getComponentName());
BindCallback callback = new BindCallback() {
@Override
public void onSuccess() {
String callId = mCallIdMapper.getCallId(call);
- mPendingOutgoingCalls.put(callId, resultCallback);
+ mPendingOutgoingCalls.put(callId, callResponse);
try {
CallInfo callInfo = call.toCallInfo(callId);
@@ -486,15 +504,15 @@
mServiceInterface.call(callInfo);
} catch (RemoteException e) {
Log.e(this, e, "Failure to call -- %s", getDescriptor());
- mPendingOutgoingCalls.remove(callId).onResult(
- false, DisconnectCause.ERROR_UNSPECIFIED, e.toString());
+ mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
+ DisconnectCause.ERROR_UNSPECIFIED, e.toString());
}
}
@Override
public void onFailure() {
Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
- resultCallback.onResult(false, DisconnectCause.ERROR_UNSPECIFIED, null);
+ callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
}
};
@@ -661,10 +679,10 @@
void removeCall(Call call) {
mPendingIncomingCalls.remove(call);
- AsyncResultCallback<Boolean> outgoingResultCallback =
- mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
+ OutgoingCallResponse outgoingResultCallback =
+ mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
if (outgoingResultCallback != null) {
- outgoingResultCallback.onResult(false, DisconnectCause.ERROR_UNSPECIFIED, null);
+ outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
}
mCallIdMapper.removeCall(call);
@@ -737,8 +755,8 @@
*/
private void handleCallServiceDeath() {
if (!mPendingOutgoingCalls.isEmpty()) {
- for (AsyncResultCallback<Boolean> callback : mPendingOutgoingCalls.values()) {
- callback.onResult(false, DisconnectCause.ERROR_UNSPECIFIED, null);
+ for (OutgoingCallResponse callback : mPendingOutgoingCalls.values()) {
+ callback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
}
mPendingOutgoingCalls.clear();
}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index d5ddedc..174e59f 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -145,15 +145,17 @@
}
@Override
- public void onFailedOutgoingCall(Call call, boolean isAborted, int errorCode, String errorMsg) {
- Log.v(this, "onFailedOutgoingCall, call: %s, isAborted: %b", call, isAborted);
- if (isAborted) {
- setCallState(call, CallState.ABORTED);
- removeCall(call);
- } else {
- // TODO: Replace disconnect cause with more specific disconnect causes.
- markCallAsDisconnected(call, errorCode, errorMsg);
- }
+ public void onFailedOutgoingCall(Call call, int errorCode, String errorMsg) {
+ Log.v(this, "onFailedOutgoingCall, call: %s", call);
+ // TODO: Replace disconnect cause with more specific disconnect causes.
+ markCallAsDisconnected(call, errorCode, errorMsg);
+ }
+
+ @Override
+ public void onCancelledOutgoingCall(Call call) {
+ Log.v(this, "onCancelledOutgoingCall, call: %s", call);
+ setCallState(call, CallState.ABORTED);
+ removeCall(call);
}
@Override
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index 4531455..ffcfe6d 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -91,7 +91,7 @@
*/
private Iterator<CallServiceDescriptor> mCallServiceDescriptorIterator;
- private AsyncResultCallback<Boolean> mResultCallback;
+ private OutgoingCallResponse mResultCallback;
private boolean mIsAborted = false;
@@ -111,7 +111,7 @@
OutgoingCallProcessor(
Call call,
CallServiceRepository callServiceRepository,
- AsyncResultCallback<Boolean> resultCallback) {
+ OutgoingCallResponse resultCallback) {
ThreadUtil.checkOnMainThread();
@@ -263,17 +263,22 @@
callService.incrementAssociatedCallCount();
Log.i(this, "Attempting to call from %s", callService.getDescriptor());
- callService.call(mCall, new AsyncResultCallback<Boolean>() {
+ callService.call(mCall, new OutgoingCallResponse() {
@Override
- public void onResult(Boolean wasCallPlaced, int errorCode, String errorMsg) {
- if (wasCallPlaced) {
- handleSuccessfulCallAttempt(callService);
- } else {
- handleFailedCallAttempt(errorCode, errorMsg);
- }
+ public void onOutgoingCallSuccess() {
+ handleSuccessfulCallAttempt(callService);
+ callService.decrementAssociatedCallCount();
+ }
- // If successful, the call should not have it's own association to keep
- // the call service bound.
+ @Override
+ public void onOutgoingCallFailure(int code, String msg) {
+ handleFailedCallAttempt(code, msg);
+ callService.decrementAssociatedCallCount();
+ }
+
+ @Override
+ public void onOutgoingCallCancel() {
+ abort();
callService.decrementAssociatedCallCount();
}
});
@@ -288,7 +293,13 @@
private void sendResult(boolean wasCallPlaced, int errorCode, String errorMsg) {
if (mResultCallback != null) {
- mResultCallback.onResult(wasCallPlaced, errorCode, errorMsg);
+ if (mIsAborted) {
+ mResultCallback.onOutgoingCallCancel();
+ } else if (wasCallPlaced) {
+ mResultCallback.onOutgoingCallSuccess();
+ } else {
+ mResultCallback.onOutgoingCallFailure(errorCode, errorMsg);
+ }
mResultCallback = null;
mHandler.removeMessages(MSG_EXPIRE);
diff --git a/src/com/android/telecomm/OutgoingCallResponse.java b/src/com/android/telecomm/OutgoingCallResponse.java
new file mode 100644
index 0000000..3d5c393
--- /dev/null
+++ b/src/com/android/telecomm/OutgoingCallResponse.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 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.telecomm;
+
+/**
+ * A callback for providing the result of placing an outgoing call.
+ */
+interface OutgoingCallResponse {
+ void onOutgoingCallSuccess();
+ void onOutgoingCallFailure(int code, String msg);
+ void onOutgoingCallCancel();
+}