Rename CallServiceWrapper to ConnectionServiceWrapper
Change-Id: I5a082e50dafea0104174cb97d3ae8af168944fc3
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 2be3355..3d4771b 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -23,9 +23,9 @@
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract.Contacts;
-import android.telecomm.CallInfo;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.CallState;
+import android.telecomm.ConnectionRequest;
import android.telecomm.GatewayInfo;
import android.telecomm.PhoneAccount;
import android.telecomm.Response;
@@ -63,7 +63,7 @@
void onSuccessfulOutgoingCall(Call call);
void onFailedOutgoingCall(Call call, int errorCode, String errorMsg);
void onCancelledOutgoingCall(Call call);
- void onSuccessfulIncomingCall(Call call, CallInfo callInfo);
+ void onSuccessfulIncomingCall(Call call);
void onFailedIncomingCall(Call call);
void onRequestingRingback(Call call, boolean requestingRingback);
void onPostDialWait(Call call, String remaining);
@@ -86,7 +86,7 @@
@Override
public void onCancelledOutgoingCall(Call call) {}
@Override
- public void onSuccessfulIncomingCall(Call call, CallInfo callInfo) {}
+ public void onSuccessfulIncomingCall(Call call) {}
@Override
public void onFailedIncomingCall(Call call) {}
@Override
@@ -166,15 +166,9 @@
private Uri mHandle;
/**
- * The call service which is attempted or already connecting this call.
+ * The connection service which is attempted or already connecting this call.
*/
- private CallServiceWrapper mCallService;
-
- /**
- * The set of call services that were attempted in the process of placing/switching this call
- * but turned out unsuitable. Only used in the context of call switching.
- */
- private Set<CallServiceWrapper> mIncompatibleCallServices;
+ private ConnectionServiceWrapper mConnectionService;
private boolean mIsEmergencyCall;
@@ -187,11 +181,11 @@
private int mDisconnectCause = DisconnectCause.NOT_VALID;
/**
- * Additional disconnect information provided by the call service.
+ * Additional disconnect information provided by the connection service.
*/
private String mDisconnectMessage;
- /** Info used by the call services. */
+ /** Info used by the connection services. */
private Bundle mExtras = Bundle.EMPTY;
/** Set of listeners on this call. */
@@ -211,8 +205,8 @@
/** Whether this call is requesting that Telecomm play the ringback tone on its behalf. */
private boolean mRequestingRingback = false;
- /** Incoming call-info to use when direct-to-voicemail query finishes. */
- private CallInfo mPendingDirectToVoicemailCallInfo;
+ /** Whether direct-to-voicemail query is pending. */
+ private boolean mDirectToVoicemailQueryPending;
private boolean mIsConferenceCapable = false;
@@ -272,8 +266,8 @@
/** {@inheritDoc} */
@Override public String toString() {
String component = null;
- if (mCallService != null && mCallService.getComponentName() != null) {
- component = mCallService.getComponentName().flattenToShortString();
+ if (mConnectionService != null && mConnectionService.getComponentName() != null) {
+ component = mConnectionService.getComponentName().flattenToShortString();
}
return String.format(Locale.US, "[%s, %s, %s]", mState, component, Log.piiHandle(mHandle));
}
@@ -435,48 +429,36 @@
return mChildCalls;
}
- CallServiceWrapper getCallService() {
- return mCallService;
+ ConnectionServiceWrapper getConnectionService() {
+ return mConnectionService;
}
- void setCallService(CallServiceWrapper callService) {
- setCallService(callService, null);
+ void setConnectionService(ConnectionServiceWrapper service) {
+ Preconditions.checkNotNull(service);
+
+ clearConnectionService();
+
+ service.incrementAssociatedCallCount();
+ mConnectionService = service;
+ mConnectionService.addCall(this);
}
/**
- * Changes the call service this call is associated with. If callToReplace is non-null then this
- * call takes its place within the call service.
+ * Clears the associated connection service.
*/
- void setCallService(CallServiceWrapper callService, Call callToReplace) {
- Preconditions.checkNotNull(callService);
-
- clearCallService();
-
- callService.incrementAssociatedCallCount();
- mCallService = callService;
- if (callToReplace == null) {
- mCallService.addCall(this);
- } else {
- mCallService.replaceCall(this, callToReplace);
- }
- }
-
- /**
- * Clears the associated call service.
- */
- void clearCallService() {
- if (mCallService != null) {
- CallServiceWrapper callServiceTemp = mCallService;
- mCallService = null;
- callServiceTemp.removeCall(this);
+ void clearConnectionService() {
+ if (mConnectionService != null) {
+ ConnectionServiceWrapper serviceTemp = mConnectionService;
+ mConnectionService = null;
+ serviceTemp.removeCall(this);
// Decrementing the count can cause the service to unbind, which itself can trigger the
// service-death code. Since the service death code tries to clean up any associated
// calls, we need to make sure to remove that information (e.g., removeCall()) before
// we decrement. Technically, invoking removeCall() prior to decrementing is all that is
- // necessary, but cleaning up mCallService prior to triggering an unbind is good to do.
- // If you change this, make sure to update {@link clearCallServiceSelector} as well.
- decrementAssociatedCallCount(callServiceTemp);
+ // necessary, but cleaning up mConnectionService prior to triggering an unbind is good
+ // to do.
+ decrementAssociatedCallCount(serviceTemp);
}
}
@@ -498,17 +480,15 @@
* the result of the query will determine if the call is rejected or passed through to the
* in-call UI.
*/
- void handleVerifiedIncoming(CallInfo callInfo) {
- Preconditions.checkState(callInfo.getState() == CallState.RINGING);
-
- // We do not handle incoming calls immediately when they are verified by the call service.
- // We allow the caller-info-query code to execute first so that we can read the
+ void handleVerifiedIncoming(ConnectionRequest request) {
+ // We do not handle incoming calls immediately when they are verified by the connection
+ // service. We allow the caller-info-query code to execute first so that we can read the
// direct-to-voicemail property before deciding if we want to show the incoming call to the
// user or if we want to reject the call.
- mPendingDirectToVoicemailCallInfo = callInfo;
+ mDirectToVoicemailQueryPending = true;
// Setting the handle triggers the caller info lookup code.
- setHandle(callInfo.getHandle());
+ setHandle(request.getHandle());
// Timeout the direct-to-voicemail lookup execution so that we dont wait too long before
// showing the user the incoming call screen.
@@ -521,7 +501,7 @@
}
void processDirectToVoicemail() {
- if (mPendingDirectToVoicemailCallInfo != null) {
+ if (mDirectToVoicemailQueryPending) {
if (mCallerInfo != null && mCallerInfo.shouldSendToVoicemail) {
Log.i(this, "Directing call to voicemail: %s.", this);
// TODO(santoscordon): Once we move State handling from CallsManager to Call, we
@@ -534,16 +514,16 @@
// TODO(santoscordon): Replace this with state transition to RINGING.
for (Listener l : mListeners) {
- l.onSuccessfulIncomingCall(this, mPendingDirectToVoicemailCallInfo);
+ l.onSuccessfulIncomingCall(this);
}
}
- mPendingDirectToVoicemailCallInfo = null;
+ mDirectToVoicemailQueryPending = false;
}
}
void handleFailedIncoming() {
- clearCallService();
+ clearConnectionService();
// TODO: Needs more specific disconnect error for this case.
setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED, null);
@@ -557,7 +537,7 @@
/**
* Starts the outgoing call sequence. Upon completion, there should exist an active connection
- * through a call service (or the call will have failed).
+ * through a connection service (or the call will have failed).
*/
void startOutgoing() {
Preconditions.checkState(mOutgoingCallProcessor == null);
@@ -583,7 +563,7 @@
l.onFailedOutgoingCall(this, code, msg);
}
- clearCallService();
+ clearConnectionService();
mOutgoingCallProcessor = null;
}
@@ -594,45 +574,19 @@
l.onCancelledOutgoingCall(this);
}
- clearCallService();
+ clearConnectionService();
mOutgoingCallProcessor = null;
}
/**
- * Adds the specified call service to the list of incompatible services. The set is used when
- * attempting to switch a phone call between call services such that incompatible services can
- * be avoided.
- *
- * @param callService The incompatible call service.
- */
- void addIncompatibleCallService(CallServiceWrapper callService) {
- if (mIncompatibleCallServices == null) {
- mIncompatibleCallServices = Sets.newHashSet();
- }
- mIncompatibleCallServices.add(callService);
- }
-
- /**
- * Checks whether or not the specified callService was identified as incompatible in the
- * context of this call.
- *
- * @param callService The call service to evaluate.
- * @return True upon incompatible call services and false otherwise.
- */
- boolean isIncompatibleCallService(CallServiceWrapper callService) {
- return mIncompatibleCallServices != null &&
- mIncompatibleCallServices.contains(callService);
- }
-
- /**
* Plays the specified DTMF tone.
*/
void playDtmfTone(char digit) {
- if (mCallService == null) {
- Log.w(this, "playDtmfTone() request on a call without a call service.");
+ if (mConnectionService == null) {
+ Log.w(this, "playDtmfTone() request on a call without a connection service.");
} else {
- Log.i(this, "Send playDtmfTone to call service for call %s", this);
- mCallService.playDtmfTone(this, digit);
+ Log.i(this, "Send playDtmfTone to connection service for call %s", this);
+ mConnectionService.playDtmfTone(this, digit);
}
}
@@ -640,29 +594,29 @@
* Stops playing any currently playing DTMF tone.
*/
void stopDtmfTone() {
- if (mCallService == null) {
- Log.w(this, "stopDtmfTone() request on a call without a call service.");
+ if (mConnectionService == null) {
+ Log.w(this, "stopDtmfTone() request on a call without a connectino service.");
} else {
- Log.i(this, "Send stopDtmfTone to call service for call %s", this);
- mCallService.stopDtmfTone(this);
+ Log.i(this, "Send stopDtmfTone to connection service for call %s", this);
+ mConnectionService.stopDtmfTone(this);
}
}
/**
- * Attempts to disconnect the call through the call service.
+ * Attempts to disconnect the call through the connection service.
*/
void disconnect() {
if (mState == CallState.NEW) {
Log.v(this, "Aborting call %s", this);
abort();
} else if (mState != CallState.ABORTED && mState != CallState.DISCONNECTED) {
- Preconditions.checkNotNull(mCallService);
+ Preconditions.checkNotNull(mConnectionService);
- Log.i(this, "Send disconnect to call service for call: %s", this);
- // The call isn't officially disconnected until the call service confirms that the call
- // was actually disconnected. Only then is the association between call and call service
- // severed, see {@link CallsManager#markCallAsDisconnected}.
- mCallService.disconnect(this);
+ Log.i(this, "Send disconnect to connection service for call: %s", this);
+ // The call isn't officially disconnected until the connection service confirms that the
+ // call was actually disconnected. Only then is the association between call and
+ // connection service severed, see {@link CallsManager#markCallAsDisconnected}.
+ mConnectionService.disconnect(this);
}
}
@@ -676,16 +630,16 @@
* Answers the call if it is ringing.
*/
void answer() {
- Preconditions.checkNotNull(mCallService);
+ Preconditions.checkNotNull(mConnectionService);
// Check to verify that the call is still in the ringing state. A call can change states
// between the time the user hits 'answer' and Telecomm receives the command.
if (isRinging("answer")) {
- // At this point, we are asking the call service to answer but we don't assume that
- // it will work. Instead, we wait until confirmation from the call service that the
- // call is in a non-RINGING state before changing the UI. See
- // {@link CallServiceAdapter#setActive} and other set* methods.
- mCallService.answer(this);
+ // At this point, we are asking the connection service to answer but we don't assume
+ // that it will work. Instead, we wait until confirmation from the connectino service
+ // that the call is in a non-RINGING state before changing the UI. See
+ // {@link ConnectionServiceAdapter#setActive} and other set* methods.
+ mConnectionService.answer(this);
}
}
@@ -696,12 +650,12 @@
* @param textMessage An optional text message to send as part of the rejection.
*/
void reject(boolean rejectWithMessage, String textMessage) {
- Preconditions.checkNotNull(mCallService);
+ Preconditions.checkNotNull(mConnectionService);
// Check to verify that the call is still in the ringing state. A call can change states
// between the time the user hits 'reject' and Telecomm receives the command.
if (isRinging("reject")) {
- mCallService.reject(this);
+ mConnectionService.reject(this);
}
}
@@ -709,10 +663,10 @@
* Puts the call on hold if it is currently active.
*/
void hold() {
- Preconditions.checkNotNull(mCallService);
+ Preconditions.checkNotNull(mConnectionService);
if (mState == CallState.ACTIVE) {
- mCallService.hold(this);
+ mConnectionService.hold(this);
}
}
@@ -720,37 +674,13 @@
* Releases the call from hold if it is currently active.
*/
void unhold() {
- Preconditions.checkNotNull(mCallService);
+ Preconditions.checkNotNull(mConnectionService);
if (mState == CallState.ON_HOLD) {
- mCallService.unhold(this);
+ mConnectionService.unhold(this);
}
}
- /**
- * @return An object containing read-only information about this call.
- */
- CallInfo toCallInfo(String callId) {
- CallServiceDescriptor descriptor = null;
- if (mCallService != null) {
- descriptor = mCallService.getDescriptor();
- }
- Bundle extras = mExtras;
- if (mGatewayInfo != null && mGatewayInfo.getGatewayProviderPackageName() != null &&
- mGatewayInfo.getOriginalHandle() != null) {
- extras = (Bundle) mExtras.clone();
- extras.putString(
- NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE,
- mGatewayInfo.getGatewayProviderPackageName());
- extras.putParcelable(
- NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
- mGatewayInfo.getOriginalHandle());
-
- }
- return new CallInfo(callId, mState, mHandle, mGatewayInfo, mAccount,
- extras, descriptor);
- }
-
/** Checks if this is a live call or not. */
boolean isAlive() {
switch (mState) {
@@ -794,25 +724,25 @@
}
void postDialContinue(boolean proceed) {
- getCallService().onPostDialContinue(this, proceed);
+ mConnectionService.onPostDialContinue(this, proceed);
}
void phoneAccountClicked() {
- getCallService().onPhoneAccountClicked(this);
+ mConnectionService.onPhoneAccountClicked(this);
}
void conferenceInto(Call conferenceCall) {
- if (mCallService == null) {
- Log.w(this, "conference requested on a call without a call service.");
+ if (mConnectionService == null) {
+ Log.w(this, "conference requested on a call without a connection service.");
} else {
- mCallService.conference(conferenceCall, this);
+ mConnectionService.conference(conferenceCall, this);
}
}
void expireConference() {
// The conference call expired before we got a confirmation of the conference from the
- // call service...so start shutting down.
- clearCallService();
+ // connection service...so start shutting down.
+ clearConnectionService();
for (Listener l : mListeners) {
l.onExpiredConferenceCall(this);
}
diff --git a/src/com/android/telecomm/CallActivity.java b/src/com/android/telecomm/CallActivity.java
index 2868216..0e66d32 100644
--- a/src/com/android/telecomm/CallActivity.java
+++ b/src/com/android/telecomm/CallActivity.java
@@ -97,8 +97,8 @@
}
/**
- * Processes INCOMING_CALL intents. Grabs the call service informations from the intent extra
- * and forwards that to the CallsManager to start the incoming call flow.
+ * Processes INCOMING_CALL intents. Grabs the connection service informations from the intent
+ * extra and forwards that to the CallsManager to start the incoming call flow.
*
* @param intent The incoming call intent.
*/
@@ -115,7 +115,7 @@
clientExtras = intent.getBundleExtra(TelecommConstants.EXTRA_INCOMING_CALL_EXTRAS);
}
- Log.d(this, "Processing incoming call from call service [%s]", descriptor);
+ Log.d(this, "Processing incoming call from connection service [%s]", descriptor);
mCallsManager.processIncomingCallIntent(descriptor, clientExtras);
}
}
diff --git a/src/com/android/telecomm/CallAudioManager.java b/src/com/android/telecomm/CallAudioManager.java
index 865e3ca..35de0cc 100644
--- a/src/com/android/telecomm/CallAudioManager.java
+++ b/src/com/android/telecomm/CallAudioManager.java
@@ -396,8 +396,8 @@
private void updateAudioForForegroundCall() {
Call call = CallsManager.getInstance().getForegroundCall();
- if (call != null && call.getCallService() != null) {
- call.getCallService().onAudioStateChanged(call, mAudioState);
+ if (call != null && call.getConnectionService() != null) {
+ call.getConnectionService().onAudioStateChanged(call, mAudioState);
}
}
diff --git a/src/com/android/telecomm/CallIdMapper.java b/src/com/android/telecomm/CallIdMapper.java
index 9f803c6..2366343 100644
--- a/src/com/android/telecomm/CallIdMapper.java
+++ b/src/com/android/telecomm/CallIdMapper.java
@@ -85,8 +85,8 @@
void checkValidCallId(String callId) {
// Note, no need for thread check, this method is thread safe.
if (!isValidCallId(callId)) {
- // TODO(santoscordon): Re-enable this once we stop getting updates to CallServiceWrapper
- // for remote connections.
+ // TODO(santoscordon): Re-enable this once we stop getting updates to
+ // ConnectionServiceWrapper for remote connections.
//throw new IllegalArgumentException(
// "Invalid call ID for " + mCallIdPrefix + ": " + callId);
}
diff --git a/src/com/android/telecomm/CallServiceRepository.java b/src/com/android/telecomm/CallServiceRepository.java
index af4098c..e1feb0f 100644
--- a/src/com/android/telecomm/CallServiceRepository.java
+++ b/src/com/android/telecomm/CallServiceRepository.java
@@ -33,19 +33,19 @@
import java.util.Set;
/**
- * Searches for and returns call services.
+ * Searches for and returns connection services.
*/
-class CallServiceRepository extends BaseRepository<CallServiceWrapper> {
+class CallServiceRepository extends BaseRepository<ConnectionServiceWrapper> {
/**
* The representation of a single lookup. Maintains lookup state and invokes the "complete"
* callback when finished.
*/
private final class CallServiceLookup {
final Set<ComponentName> mOutstandingProviders = Sets.newHashSet();
- final Set<CallServiceWrapper> mServices = Sets.newHashSet();
- final LookupCallback<CallServiceWrapper> mCallback;
+ final Set<ConnectionServiceWrapper> mServices = Sets.newHashSet();
+ final LookupCallback<ConnectionServiceWrapper> mCallback;
- CallServiceLookup(LookupCallback<CallServiceWrapper> callback) {
+ CallServiceLookup(LookupCallback<ConnectionServiceWrapper> callback) {
mCallback = callback;
}
@@ -141,7 +141,8 @@
ComponentName providerName = provider.getComponentName();
if (mOutstandingProviders.remove(providerName)) {
if (callServiceDescriptors != null) {
- // Add all the call services from this provider to the call-service cache.
+ // Add all the connection services from this provider to the connection-service
+ // cache.
for (CallServiceDescriptor descriptor : callServiceDescriptors) {
mServices.add(getService(descriptor.getServiceComponent(), descriptor));
}
@@ -151,7 +152,7 @@
finishLookup();
}
} else {
- Log.i(this, "Unexpected call services from %s in lookup.", providerName);
+ Log.i(this, "Unexpected connection services from %s in lookup.", providerName);
}
}
@@ -169,23 +170,24 @@
}
/**
- * Returns the call service implementation specified by the descriptor.
+ * Returns the connection service implementation specified by the descriptor.
*
* @param descriptor The call-service descriptor.
*/
- CallServiceWrapper getService(CallServiceDescriptor descriptor) {
+ ConnectionServiceWrapper getService(CallServiceDescriptor descriptor) {
return getService(descriptor.getServiceComponent(), descriptor);
}
/** {@inheritDoc} */
@Override
- protected void onLookupServices(LookupCallback<CallServiceWrapper> callback) {
+ protected void onLookupServices(LookupCallback<ConnectionServiceWrapper> callback) {
new CallServiceLookup(callback).start();
}
@Override
- protected CallServiceWrapper onCreateNewServiceWrapper(ComponentName componentName,
+ protected ConnectionServiceWrapper onCreateNewServiceWrapper(ComponentName componentName,
Object param) {
- return new CallServiceWrapper((CallServiceDescriptor) param, mIncomingCallsManager, this);
+ return new ConnectionServiceWrapper(
+ (CallServiceDescriptor) param, mIncomingCallsManager, this);
}
}
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
deleted file mode 100644
index 1414e0a..0000000
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * 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;
-
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telecomm.CallAudioState;
-import android.telecomm.CallInfo;
-import android.telecomm.CallService;
-import android.telecomm.CallServiceDescriptor;
-import android.telecomm.ConnectionRequest;
-import android.telecomm.TelecommConstants;
-import android.telephony.DisconnectCause;
-
-import com.android.internal.os.SomeArgs;
-
-import com.android.internal.telecomm.ICallService;
-import com.android.internal.telecomm.ICallServiceAdapter;
-import com.android.internal.telecomm.ICallServiceProvider;
-import com.android.internal.telecomm.ICallVideoProvider;
-import com.android.internal.telecomm.RemoteServiceCallback;
-import com.android.telecomm.BaseRepository.LookupCallback;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
-import org.apache.http.conn.ClientConnectionRequest;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Wrapper for {@link ICallService}s, handles binding to {@link ICallService} and keeps track of
- * when the object can safely be unbound. Other classes should not use {@link ICallService} directly
- * and instead should use this class to invoke methods of {@link ICallService}.
- */
-final class CallServiceWrapper extends ServiceBinder<ICallService> {
- private static final String TAG = CallServiceWrapper.class.getSimpleName();
-
- private final class Adapter extends ICallServiceAdapter.Stub {
- 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_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_QUERY_REMOTE_CALL_SERVICES = 15;
- private static final int MSG_SET_CALL_VIDEO_PROVIDER = 16;
- private static final int MSG_SET_FEATURES = 17;
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- Call call;
- switch (msg.what) {
- case MSG_NOTIFY_INCOMING_CALL:
- CallInfo clientCallInfo = (CallInfo) msg.obj;
- call = mCallIdMapper.getCall(clientCallInfo.getId());
- if (call != null && mPendingIncomingCalls.remove(call) &&
- call.isIncoming()) {
- CallInfo callInfo = new CallInfo(null, clientCallInfo.getState(),
- clientCallInfo.getHandle());
- mIncomingCallsManager.handleSuccessfulIncomingCall(call, callInfo);
- } else {
- // TODO(santoscordon): For this an the other commented logging, we need
- // to reenable it. At the moment all CallServiceAdapters receive
- // notification of changes to all calls, even calls which it may not own
- // (ala remote connections). We need to fix that and then uncomment the
- // logging calls here.
- //Log.w(this, "notifyIncomingCall, unknown incoming call: %s, id: %s",
- // call, clientCallInfo.getId());
- }
- break;
- case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
- String callId = (String) msg.obj;
- if (mPendingOutgoingCalls.containsKey(callId)) {
- mPendingOutgoingCalls.remove(callId).onOutgoingCallSuccess();
- } else {
- //Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
- }
- break;
- }
- case MSG_HANDLE_FAILED_OUTGOING_CALL: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- String callId = (String) args.arg1;
- int statusCode = args.argi1;
- String statusMsg = (String) args.arg2;
- // TODO(santoscordon): Do something with 'reason' or get rid of it.
-
- if (mPendingOutgoingCalls.containsKey(callId)) {
- mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
- statusCode, statusMsg);
- mCallIdMapper.removeCall(callId);
- } else {
- //Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
- }
- } finally {
- args.recycle();
- }
- 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) {
- mCallsManager.markCallAsActive(call);
- } else {
- //Log.w(this, "setActive, unknown call id: %s", msg.obj);
- }
- break;
- case MSG_SET_RINGING:
- call = mCallIdMapper.getCall(msg.obj);
- if (call != null) {
- mCallsManager.markCallAsRinging(call);
- } else {
- //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
- }
- break;
- case MSG_SET_DIALING:
- call = mCallIdMapper.getCall(msg.obj);
- if (call != null) {
- mCallsManager.markCallAsDialing(call);
- } else {
- //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
- }
- break;
- case MSG_SET_DISCONNECTED: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- call = mCallIdMapper.getCall(args.arg1);
- String disconnectMessage = (String) args.arg2;
- int disconnectCause = args.argi1;
- if (call != null) {
- mCallsManager.markCallAsDisconnected(call, disconnectCause,
- disconnectMessage);
- } else {
- //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_SET_ON_HOLD:
- call = mCallIdMapper.getCall(msg.obj);
- if (call != null) {
- mCallsManager.markCallAsOnHold(call);
- } else {
- //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
- }
- break;
- case MSG_SET_REQUESTING_RINGBACK: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- call = mCallIdMapper.getCall(args.arg1);
- boolean ringback = (boolean) args.arg2;
- if (call != null) {
- call.setRequestingRingback(ringback);
- } else {
- //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_ON_POST_DIAL_WAIT: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- call = mCallIdMapper.getCall(args.arg1);
- if (call != null) {
- String remaining = (String) args.arg2;
- call.onPostDialWait(remaining);
- } else {
- //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_CAN_CONFERENCE: {
- call = mCallIdMapper.getCall(msg.obj);
- if (call != null) {
- call.setIsConferenceCapable(msg.arg1 == 1);
- } else {
- //Log.w(CallServiceWrapper.this, "canConference, unknown call id: %s",
- // msg.obj);
- }
- break;
- }
- case MSG_SET_IS_CONFERENCED: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- Call childCall = mCallIdMapper.getCall(args.arg1);
- if (childCall != null) {
- String conferenceCallId = (String) args.arg2;
- if (conferenceCallId == null) {
- childCall.setParentCall(null);
- } else {
- Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
- if (conferenceCall != null &&
- !mPendingConferenceCalls.contains(conferenceCall)) {
- childCall.setParentCall(conferenceCall);
- } else {
- //Log.w(this, "setIsConferenced, unknown conference id %s",
- // conferenceCallId);
- }
- }
- } else {
- //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_ADD_CONFERENCE_CALL: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- String callId = (String) args.arg1;
- Call conferenceCall = mCallIdMapper.getCall(callId);
- if (mPendingConferenceCalls.remove(conferenceCall)) {
- Log.v(this, "confirming conf call %s", conferenceCall);
- conferenceCall.confirmConference();
- } else {
- //Log.w(this, "addConference, unknown call id: %s", callId);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_QUERY_REMOTE_CALL_SERVICES: {
- CallServiceWrapper.this.queryRemoteConnectionServices(
- (RemoteServiceCallback) msg.obj);
- break;
- }
- case MSG_SET_CALL_VIDEO_PROVIDER: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- call = mCallIdMapper.getCall(args.arg1);
- ICallVideoProvider callVideoProvider = (ICallVideoProvider) args.arg2;
- if (call != null) {
- call.setCallVideoProvider(callVideoProvider);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- case MSG_SET_FEATURES: {
- SomeArgs args = (SomeArgs) msg.obj;
- try {
- call = mCallIdMapper.getCall(args.arg1);
- int features = (int) args.arg2;
- if (call != null) {
- call.setFeatures(features);
- }
- } finally {
- args.recycle();
- }
- break;
- }
- }
- }
- };
-
- /** {@inheritDoc} */
- @Override
- public void notifyIncomingCall(CallInfo callInfo) {
- logIncoming("notifyIncomingCall %s", callInfo);
- mCallIdMapper.checkValidCallId(callInfo.getId());
- mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, callInfo).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void handleSuccessfulOutgoingCall(String callId) {
- logIncoming("handleSuccessfulOutgoingCall %s", callId);
- mCallIdMapper.checkValidCallId(callId);
- mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, callId).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void handleFailedOutgoingCall(
- ConnectionRequest request,
- int errorCode,
- String errorMsg) {
- logIncoming("handleFailedOutgoingCall %s %d %s", request, errorCode, errorMsg);
- mCallIdMapper.checkValidCallId(request.getCallId());
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = request.getCallId();
- args.argi1 = errorCode;
- args.arg2 = errorMsg;
- mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
- }
-
- /** {@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);
- mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setRinging(String callId) {
- logIncoming("setRinging %s", callId);
- mCallIdMapper.checkValidCallId(callId);
- mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider) {
- logIncoming("setCallVideoProvider %s", callId);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = callVideoProvider;
- mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setDialing(String callId) {
- logIncoming("setDialing %s", callId);
- mCallIdMapper.checkValidCallId(callId);
- mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setDisconnected(
- String callId, int disconnectCause, String disconnectMessage) {
- logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = disconnectMessage;
- args.argi1 = disconnectCause;
- mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setOnHold(String callId) {
- logIncoming("setOnHold %s", callId);
- mCallIdMapper.checkValidCallId(callId);
- mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
- }
-
- /** {@inheritDoc} */
- @Override
- public void setRequestingRingback(String callId, boolean ringback) {
- logIncoming("setRequestingRingback %s %b", callId, ringback);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = ringback;
- mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
- }
-
- /** ${inheritDoc} */
- @Override
- public void removeCall(String callId) {
- logIncoming("removeCall %s", callId);
- }
-
- /** ${inheritDoc} */
- @Override
- public void setCanConference(String callId, boolean canConference) {
- logIncoming("setCanConference %s %b", callId, canConference);
- mHandler.obtainMessage(MSG_CAN_CONFERENCE, canConference ? 1 : 0, 0, callId)
- .sendToTarget();
- }
-
- /** ${inheritDoc} */
- @Override
- public void setIsConferenced(String callId, String conferenceCallId) {
- logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = conferenceCallId;
- mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
- }
-
- /** ${InheritDoc} */
- @Override
- public void addConferenceCall(String callId, CallInfo callInfo) {
- logIncoming("addConferenceCall %s %s", callId, callInfo);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = callInfo;
- mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, args).sendToTarget();
- }
-
- @Override
- public void onPostDialWait(String callId, String remaining) throws RemoteException {
- logIncoming("onPostDialWait %s %s", callId, remaining);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = remaining;
- mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
- }
-
- /** ${inheritDoc} */
- @Override
- public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
- logIncoming("queryRemoteCSs");
- mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
- }
-
- @Override
- public void setFeatures(String callId, int features) {
- logIncoming("setFeatures %s %d", callId, features);
- mCallIdMapper.checkValidCallId(callId);
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = callId;
- args.arg2 = features;
- mHandler.obtainMessage(MSG_SET_FEATURES, args).sendToTarget();
- }
- }
-
- private final Adapter mAdapter = new Adapter();
- private final CallsManager mCallsManager = CallsManager.getInstance();
- private final Set<Call> mPendingIncomingCalls = new HashSet<>();
- private final Set<Call> mPendingConferenceCalls = new HashSet<>();
- private final CallServiceDescriptor mDescriptor;
- private final CallIdMapper mCallIdMapper = new CallIdMapper("CallService");
- private final IncomingCallsManager mIncomingCallsManager;
- private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
- private final Handler mHandler = new Handler();
-
- private Binder mBinder = new Binder();
- private ICallService mServiceInterface;
- private final CallServiceRepository mCallServiceRepository;
-
- /**
- * Creates a call-service for the specified descriptor.
- *
- * @param descriptor The call-service descriptor from
- * {@link ICallServiceProvider#lookupCallServices}.
- * @param incomingCallsManager Manages the incoming call initialization flow.
- * @param callServiceRepository Call service repository.
- */
- CallServiceWrapper(
- CallServiceDescriptor descriptor,
- IncomingCallsManager incomingCallsManager,
- CallServiceRepository callServiceRepository) {
- super(TelecommConstants.ACTION_CALL_SERVICE, descriptor.getServiceComponent());
- mDescriptor = descriptor;
- mIncomingCallsManager = incomingCallsManager;
- mCallServiceRepository = callServiceRepository;
- }
-
- CallServiceDescriptor getDescriptor() {
- return mDescriptor;
- }
-
- /** See {@link ICallService#setCallServiceAdapter}. */
- private void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter) {
- if (isServiceValid("setCallServiceAdapter")) {
- try {
- logOutgoing("setCallServiceAdapter %s", callServiceAdapter);
- mServiceInterface.setCallServiceAdapter(callServiceAdapter);
- } catch (RemoteException e) {
- }
- }
- }
-
- /**
- * Attempts to place the specified call, see {@link ICallService#call}. Returns the result
- * asynchronously through the specified callback.
- */
- 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, callResponse);
-
- try {
- CallInfo callInfo = call.toCallInfo(callId);
- logOutgoing("call %s", callInfo);
- mServiceInterface.call(callInfo);
- } catch (RemoteException e) {
- Log.e(this, e, "Failure to call -- %s", getDescriptor());
- mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
- DisconnectCause.ERROR_UNSPECIFIED, e.toString());
- }
- }
-
- @Override
- public void onFailure() {
- Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
- callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
- }
- };
-
- mBinder.bind(callback);
- }
-
- /** @see CallService#abort(String) */
- void abort(Call call) {
- // Clear out any pending outgoing call data
- String callId = mCallIdMapper.getCallId(call);
-
- // If still bound, tell the call service to abort.
- if (isServiceValid("abort")) {
- try {
- logOutgoing("abort %s", callId);
- mServiceInterface.abort(callId);
- } catch (RemoteException e) {
- }
- }
-
- removeCall(call);
- }
-
- /** @see CallService#hold(String) */
- void hold(Call call) {
- if (isServiceValid("hold")) {
- try {
- logOutgoing("hold %s", mCallIdMapper.getCallId(call));
- mServiceInterface.hold(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#unhold(String) */
- void unhold(Call call) {
- if (isServiceValid("unhold")) {
- try {
- logOutgoing("unhold %s", mCallIdMapper.getCallId(call));
- mServiceInterface.unhold(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#onAudioStateChanged(String,CallAudioState) */
- void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
- if (isServiceValid("onAudioStateChanged")) {
- try {
- logOutgoing("onAudioStateChanged %s %s",
- mCallIdMapper.getCallId(activeCall), audioState);
- mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
- audioState);
- } catch (RemoteException e) {
- }
- }
- }
-
- /**
- * Starts retrieval of details for an incoming call. Details are returned through the
- * call-service adapter using the specified call ID. Upon failure, the specified error callback
- * is invoked. Can be invoked even when the call service is unbound. See
- * {@link ICallService#setIncomingCallId}.
- *
- * @param call The call used for the incoming call.
- * @param extras The {@link CallService}-provided extras which need to be sent back.
- * @param errorCallback The callback to invoke upon failure.
- */
- void setIncomingCallId(final Call call, final Bundle extras, final Runnable errorCallback) {
- Log.d(this, "setIncomingCall(%s) via %s.", call, getComponentName());
- BindCallback callback = new BindCallback() {
- @Override
- public void onSuccess() {
- if (isServiceValid("setIncomingCallId")) {
- mPendingIncomingCalls.add(call);
- try {
- logOutgoing("setIncomingCallId %s %s",
- mCallIdMapper.getCallId(call), extras);
- mServiceInterface.setIncomingCallId(mCallIdMapper.getCallId(call),
- extras);
- } catch (RemoteException e) {
- }
- }
- }
-
- @Override
- public void onFailure() {
- errorCallback.run();
- }
- };
-
- mBinder.bind(callback);
- }
-
- /** @see CallService#disconnect(String) */
- void disconnect(Call call) {
- if (isServiceValid("disconnect")) {
- try {
- logOutgoing("disconnect %s", mCallIdMapper.getCallId(call));
- mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#answer(String) */
- void answer(Call call) {
- if (isServiceValid("answer")) {
- try {
- logOutgoing("answer %s", mCallIdMapper.getCallId(call));
- mServiceInterface.answer(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#reject(String) */
- void reject(Call call) {
- if (isServiceValid("reject")) {
- try {
- logOutgoing("reject %s", mCallIdMapper.getCallId(call));
- mServiceInterface.reject(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#playDtmfTone(String,char) */
- void playDtmfTone(Call call, char digit) {
- if (isServiceValid("playDtmfTone")) {
- try {
- logOutgoing("playDtmfTone %s %c", mCallIdMapper.getCallId(call), digit);
- mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
- } catch (RemoteException e) {
- }
- }
- }
-
- /** @see CallService#stopDtmfTone(String) */
- void stopDtmfTone(Call call) {
- if (isServiceValid("stopDtmfTone")) {
- try {
- logOutgoing("stopDtmfTone %s", mCallIdMapper.getCallId(call));
- mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
- } catch (RemoteException e) {
- }
- }
- }
-
- void addCall(Call call) {
- if (mCallIdMapper.getCallId(call) == null) {
- mCallIdMapper.addCall(call);
- }
- }
-
- /**
- * Associates newCall with this call service by replacing callToReplace.
- */
- void replaceCall(Call newCall, Call callToReplace) {
- Preconditions.checkState(callToReplace.getCallService() == this);
- mCallIdMapper.replaceCall(newCall, callToReplace);
- }
-
- void removeCall(Call call) {
- mPendingIncomingCalls.remove(call);
-
- OutgoingCallResponse outgoingResultCallback =
- mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
- if (outgoingResultCallback != null) {
- outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
- }
-
- mCallIdMapper.removeCall(call);
- }
-
- void onPostDialContinue(Call call, boolean proceed) {
- if (isServiceValid("onPostDialContinue")) {
- try {
- logOutgoing("onPostDialContinue %s %b", mCallIdMapper.getCallId(call), proceed);
- mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
- } catch (RemoteException ignored) {
- }
- }
- }
-
- void onPhoneAccountClicked(Call call) {
- if (isServiceValid("onPhoneAccountClicked")) {
- try {
- logOutgoing("onPhoneAccountClicked %s", mCallIdMapper.getCallId(call));
- mServiceInterface.onPhoneAccountClicked(mCallIdMapper.getCallId(call));
- } catch (RemoteException ignored) {
- }
- }
- }
-
- void conference(final Call conferenceCall, Call call) {
- if (isServiceValid("conference")) {
- try {
- conferenceCall.setCallService(this);
- mPendingConferenceCalls.add(conferenceCall);
- mHandler.postDelayed(new Runnable() {
- @Override public void run() {
- if (mPendingConferenceCalls.remove(conferenceCall)) {
- conferenceCall.expireConference();
- Log.i(this, "Conference call expired: %s", conferenceCall);
- }
- }
- }, Timeouts.getConferenceCallExpireMillis());
-
- logOutgoing("conference %s %s",
- mCallIdMapper.getCallId(conferenceCall),
- mCallIdMapper.getCallId(call));
- mServiceInterface.conference(
- mCallIdMapper.getCallId(conferenceCall),
- mCallIdMapper.getCallId(call));
- } catch (RemoteException ignored) {
- }
- }
- }
-
- void splitFromConference(Call call) {
- if (isServiceValid("splitFromConference")) {
- try {
- logOutgoing("splitFromConference %s", mCallIdMapper.getCallId(call));
- mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
- } catch (RemoteException ignored) {
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override
- protected void setServiceInterface(IBinder binder) {
- if (binder == null) {
- // We have lost our service connection. Notify the world that this call service is done.
- // We must notify the adapter before CallsManager. The adapter will force any pending
- // outgoing calls to try the next call service. This needs to happen before CallsManager
- // tries to clean up any calls still associated with this call service.
- handleCallServiceDeath();
- CallsManager.getInstance().handleCallServiceDeath(this);
- mServiceInterface = null;
- } else {
- mServiceInterface = ICallService.Stub.asInterface(binder);
- setCallServiceAdapter(mAdapter);
- }
- }
-
- /**
- * Called when the associated call service dies.
- */
- private void handleCallServiceDeath() {
- if (!mPendingOutgoingCalls.isEmpty()) {
- for (OutgoingCallResponse callback : mPendingOutgoingCalls.values()) {
- callback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
- }
- mPendingOutgoingCalls.clear();
- }
-
- if (!mPendingIncomingCalls.isEmpty()) {
- // Iterate through a copy because the code inside the loop will modify the original
- // list.
- for (Call call : ImmutableList.copyOf(mPendingIncomingCalls)) {
- Preconditions.checkState(call.isIncoming());
- mIncomingCallsManager.handleFailedIncomingCall(call);
- }
-
- if (!mPendingIncomingCalls.isEmpty()) {
- Log.wtf(this, "Pending calls did not get cleared.");
- mPendingIncomingCalls.clear();
- }
- }
-
- mCallIdMapper.clear();
- }
-
- private void logIncoming(String msg, Object... params) {
- Log.d(this, "CallService -> Telecomm: " + msg, params);
- }
-
- private void logOutgoing(String msg, Object... params) {
- Log.d(this, "Telecomm -> CallService: " + msg, params);
- }
-
- private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
- final List<IBinder> callServices = new ArrayList<>();
- final List<ComponentName> components = new ArrayList<>();
-
- mCallServiceRepository.lookupServices(new LookupCallback<CallServiceWrapper>() {
- private int mRemainingResponses;
-
- /** ${inheritDoc} */
- @Override
- public void onComplete(Collection<CallServiceWrapper> services) {
- mRemainingResponses = services.size() - 1;
- for (CallServiceWrapper cs : services) {
- if (cs != CallServiceWrapper.this) {
- final CallServiceWrapper currentCallService = cs;
- cs.mBinder.bind(new BindCallback() {
- @Override
- public void onSuccess() {
- Log.d(this, "Adding ***** %s", currentCallService.getDescriptor());
- callServices.add(currentCallService.mServiceInterface.asBinder());
- components.add(currentCallService.getComponentName());
- maybeComplete();
- }
-
- @Override
- public void onFailure() {
- // add null so that we always add up to totalExpected even if
- // some of the call services fail to bind.
- maybeComplete();
- }
-
- private void maybeComplete() {
- if (--mRemainingResponses == 0) {
- try {
- callback.onResult(components, callServices);
- } catch (RemoteException ignored) {
- }
- }
- }
- });
- }
- }
- }
- });
- }
-}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 28e264a..f78fb7c 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -19,7 +19,6 @@
import android.net.Uri;
import android.os.Bundle;
import android.telecomm.CallAudioState;
-import android.telecomm.CallInfo;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.CallState;
import android.telecomm.GatewayInfo;
@@ -51,10 +50,10 @@
void onCallAdded(Call call);
void onCallRemoved(Call call);
void onCallStateChanged(Call call, CallState oldState, CallState newState);
- void onCallServiceChanged(
+ void onConnectionServiceChanged(
Call call,
- CallServiceWrapper oldCallService,
- CallServiceWrapper newCallService);
+ ConnectionServiceWrapper oldService,
+ ConnectionServiceWrapper newService);
void onIncomingCallAnswered(Call call);
void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage);
void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall);
@@ -123,9 +122,9 @@
public void onSuccessfulOutgoingCall(Call call) {
Log.v(this, "onSuccessfulOutgoingCall, %s", call);
if (mCalls.contains(call)) {
- // The call's CallService has been updated.
+ // The call's ConnectionService has been updated.
for (CallsManagerListener listener : mListeners) {
- listener.onCallServiceChanged(call, null, call.getCallService());
+ listener.onConnectionServiceChanged(call, null, call.getConnectionService());
}
} else {
Log.wtf(this, "unexpected successful call notification: %s", call);
@@ -150,9 +149,9 @@
}
@Override
- public void onSuccessfulIncomingCall(Call call, CallInfo callInfo) {
+ public void onSuccessfulIncomingCall(Call call) {
Log.d(this, "onSuccessfulIncomingCall");
- setCallState(call, callInfo.getState());
+ setCallState(call, CallState.RINGING);
addCall(call);
}
@@ -264,13 +263,13 @@
* specified call; using the specified call service descriptor. Upon success, execution returns
* to {@link #onSuccessfulIncomingCall} to start the in-call UI.
*
- * @param descriptor The descriptor of the call service to use for this incoming call.
+ * @param descriptor The descriptor of the connection service to use for this incoming call.
* @param extras The optional extras Bundle passed with the intent used for the incoming call.
*/
void processIncomingCallIntent(CallServiceDescriptor descriptor, Bundle extras) {
Log.d(this, "processIncomingCallIntent");
// Create a call with no handle. Eventually, switchboard will update the call with
- // additional information from the call service, but for now we just need one to pass
+ // additional information from the connection service, but for now we just need one to pass
// around.
Call call = new Call(true /* isIncoming */, false /* isConference */);
// TODO(santoscordon): Move this to be a part of addCall()
@@ -516,15 +515,15 @@
}
/**
- * Cleans up any calls currently associated with the specified call service when the
+ * Cleans up any calls currently associated with the specified connection service when the
* call-service binder disconnects unexpectedly.
*
- * @param callService The call service that disconnected.
+ * @param service The connection service that disconnected.
*/
- void handleCallServiceDeath(CallServiceWrapper callService) {
- Preconditions.checkNotNull(callService);
+ void handleConnectionServiceDeath(ConnectionServiceWrapper service) {
+ Preconditions.checkNotNull(service);
for (Call call : ImmutableList.copyOf(mCalls)) {
- if (call.getCallService() == callService) {
+ if (call.getConnectionService() == service) {
markCallAsDisconnected(call, DisconnectCause.ERROR_UNSPECIFIED, null);
}
}
@@ -630,7 +629,7 @@
Log.v(this, "removeCall(%s)", call);
call.removeListener(this);
- call.clearCallService();
+ call.clearConnectionService();
boolean shouldNotify = false;
if (mCalls.contains(call)) {
@@ -684,8 +683,8 @@
Call newForegroundCall = null;
for (Call call : mCalls) {
// TODO(santoscordon): Foreground-ness needs to be explicitly set. No call, regardless
- // of its state will be foreground by default and instead the call service should be
- // notified when its calls enter and exit foreground state. Foreground will mean that
+ // of its state will be foreground by default and instead the connection service should
+ // be notified when its calls enter and exit foreground state. Foreground will mean that
// the call should play audio and listen to microphone if it wants.
// Active calls have priority.
diff --git a/src/com/android/telecomm/CallsManagerListenerBase.java b/src/com/android/telecomm/CallsManagerListenerBase.java
index a5320a4..f34bdad 100644
--- a/src/com/android/telecomm/CallsManagerListenerBase.java
+++ b/src/com/android/telecomm/CallsManagerListenerBase.java
@@ -38,10 +38,10 @@
}
@Override
- public void onCallServiceChanged(
+ public void onConnectionServiceChanged(
Call call,
- CallServiceWrapper oldCallServiceWrapper,
- CallServiceWrapper newCallService) {
+ ConnectionServiceWrapper oldService,
+ ConnectionServiceWrapper newService) {
}
@Override
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
new file mode 100644
index 0000000..0ae8d20
--- /dev/null
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -0,0 +1,886 @@
+/*
+ * 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;
+
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.telecomm.CallAudioState;
+import android.telecomm.ConnectionService;
+import android.telecomm.CallServiceDescriptor;
+import android.telecomm.ConnectionRequest;
+import android.telecomm.GatewayInfo;
+import android.telecomm.TelecommConstants;
+import android.telephony.DisconnectCause;
+
+import com.android.internal.os.SomeArgs;
+
+import com.android.internal.telecomm.IConnectionService;
+import com.android.internal.telecomm.IConnectionServiceAdapter;
+import com.android.internal.telecomm.ICallServiceProvider;
+import com.android.internal.telecomm.ICallVideoProvider;
+import com.android.internal.telecomm.RemoteServiceCallback;
+import com.android.telecomm.BaseRepository.LookupCallback;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import org.apache.http.conn.ClientConnectionRequest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Wrapper for {@link IConnectionService}s, handles binding to {@link IConnectionService} and keeps
+ * track of when the object can safely be unbound. Other classes should not use
+ * {@link IConnectionService} directly and instead should use this class to invoke methods of
+ * {@link IConnectionService}.
+ */
+final class ConnectionServiceWrapper extends ServiceBinder<IConnectionService> {
+ 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_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_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_REMOVE_CALL = 14;
+ private static final int MSG_ON_POST_DIAL_WAIT = 15;
+ private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 16;
+ private static final int MSG_SET_CALL_VIDEO_PROVIDER = 17;
+ private static final int MSG_SET_FEATURES = 18;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ Call call;
+ switch (msg.what) {
+ case MSG_NOTIFY_INCOMING_CALL: {
+ ConnectionRequest request = (ConnectionRequest) msg.obj;
+ call = mCallIdMapper.getCall(request.getCallId());
+ if (call != null && mPendingIncomingCalls.remove(call) &&
+ call.isIncoming()) {
+ mIncomingCallsManager.handleSuccessfulIncomingCall(call, request);
+ } else {
+ // TODO(santoscordon): For this an the other commented logging, we need
+ // to reenable it. At the moment all ConnectionServiceAdapters receive
+ // notification of changes to all calls, even calls which it may not own
+ // (ala remote connections). We need to fix that and then uncomment the
+ // logging calls here.
+ //Log.w(this, "notifyIncomingCall, unknown incoming call: %s, id: %s",
+ // call, request.getId());
+ }
+ break;
+ }
+ case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL: {
+ ConnectionRequest request = (ConnectionRequest) msg.obj;
+ if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
+ mPendingOutgoingCalls.remove(
+ request.getCallId()).onOutgoingCallSuccess();
+ } else {
+ //Log.w(this, "handleSuccessfulOutgoingCall, unknown call: %s", callId);
+ }
+ break;
+ }
+ case MSG_HANDLE_FAILED_OUTGOING_CALL: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ ConnectionRequest request = (ConnectionRequest) msg.obj;
+ int statusCode = args.argi1;
+ String statusMsg = (String) args.arg2;
+ // TODO(santoscordon): Do something with 'reason' or get rid of it.
+
+ if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
+ mPendingOutgoingCalls.remove(request.getCallId())
+ .onOutgoingCallFailure(statusCode, statusMsg);
+ mCallIdMapper.removeCall(request.getCallId());
+ } else {
+ //Log.w(this, "handleFailedOutgoingCall, unknown call: %s", callId);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_CANCEL_OUTGOING_CALL: {
+ ConnectionRequest request = (ConnectionRequest) msg.obj;
+ if (mPendingOutgoingCalls.containsKey(request.getCallId())) {
+ mPendingOutgoingCalls.remove(
+ request.getCallId()).onOutgoingCallCancel();
+ } else {
+ //Log.w(this, "cancelOutgoingCall, unknown call: %s", callId);
+ }
+ break;
+ }
+ case MSG_SET_ACTIVE:
+ call = mCallIdMapper.getCall(msg.obj);
+ if (call != null) {
+ mCallsManager.markCallAsActive(call);
+ } else {
+ //Log.w(this, "setActive, unknown call id: %s", msg.obj);
+ }
+ break;
+ case MSG_SET_RINGING:
+ call = mCallIdMapper.getCall(msg.obj);
+ if (call != null) {
+ mCallsManager.markCallAsRinging(call);
+ } else {
+ //Log.w(this, "setRinging, unknown call id: %s", msg.obj);
+ }
+ break;
+ case MSG_SET_DIALING:
+ call = mCallIdMapper.getCall(msg.obj);
+ if (call != null) {
+ mCallsManager.markCallAsDialing(call);
+ } else {
+ //Log.w(this, "setDialing, unknown call id: %s", msg.obj);
+ }
+ break;
+ case MSG_SET_DISCONNECTED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ call = mCallIdMapper.getCall(args.arg1);
+ String disconnectMessage = (String) args.arg2;
+ int disconnectCause = args.argi1;
+ if (call != null) {
+ mCallsManager.markCallAsDisconnected(call, disconnectCause,
+ disconnectMessage);
+ } else {
+ //Log.w(this, "setDisconnected, unknown call id: %s", args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_SET_ON_HOLD:
+ call = mCallIdMapper.getCall(msg.obj);
+ if (call != null) {
+ mCallsManager.markCallAsOnHold(call);
+ } else {
+ //Log.w(this, "setOnHold, unknown call id: %s", msg.obj);
+ }
+ break;
+ case MSG_SET_REQUESTING_RINGBACK: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ call = mCallIdMapper.getCall(args.arg1);
+ boolean ringback = (boolean) args.arg2;
+ if (call != null) {
+ call.setRequestingRingback(ringback);
+ } else {
+ //Log.w(this, "setRingback, unknown call id: %s", args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_CAN_CONFERENCE: {
+ call = mCallIdMapper.getCall(msg.obj);
+ if (call != null) {
+ call.setIsConferenceCapable(msg.arg1 == 1);
+ } else {
+ //Log.w(ConnectionServiceWrapper.this,
+ // "canConference, unknown call id: %s", msg.obj);
+ }
+ break;
+ }
+ case MSG_SET_IS_CONFERENCED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Call childCall = mCallIdMapper.getCall(args.arg1);
+ if (childCall != null) {
+ String conferenceCallId = (String) args.arg2;
+ if (conferenceCallId == null) {
+ childCall.setParentCall(null);
+ } else {
+ Call conferenceCall = mCallIdMapper.getCall(conferenceCallId);
+ if (conferenceCall != null &&
+ !mPendingConferenceCalls.contains(conferenceCall)) {
+ childCall.setParentCall(conferenceCall);
+ } else {
+ //Log.w(this, "setIsConferenced, unknown conference id %s",
+ // conferenceCallId);
+ }
+ }
+ } else {
+ //Log.w(this, "setIsConferenced, unknown call id: %s", args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_ADD_CONFERENCE_CALL: {
+ Call conferenceCall = mCallIdMapper.getCall(msg.obj);
+ if (mPendingConferenceCalls.remove(conferenceCall)) {
+ Log.v(this, "confirming conf call %s", conferenceCall);
+ conferenceCall.confirmConference();
+ } else {
+ //Log.w(this, "addConference, unknown call id: %s", callId);
+ }
+ break;
+ }
+ case MSG_REMOVE_CALL:
+ break;
+ case MSG_ON_POST_DIAL_WAIT: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ call = mCallIdMapper.getCall(args.arg1);
+ if (call != null) {
+ String remaining = (String) args.arg2;
+ call.onPostDialWait(remaining);
+ } else {
+ //Log.w(this, "onPostDialWait, unknown call id: %s", args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_QUERY_REMOTE_CALL_SERVICES: {
+ ConnectionServiceWrapper.this.queryRemoteConnectionServices(
+ (RemoteServiceCallback) msg.obj);
+ break;
+ }
+ case MSG_SET_CALL_VIDEO_PROVIDER: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ call = mCallIdMapper.getCall(args.arg1);
+ ICallVideoProvider callVideoProvider = (ICallVideoProvider) args.arg2;
+ if (call != null) {
+ call.setCallVideoProvider(callVideoProvider);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_SET_FEATURES: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ call = mCallIdMapper.getCall(args.arg1);
+ int features = (int) args.arg2;
+ if (call != null) {
+ call.setFeatures(features);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ }
+ }
+ };
+
+ private final class Adapter extends IConnectionServiceAdapter.Stub {
+ /** {@inheritDoc} */
+ @Override
+ public void notifyIncomingCall(ConnectionRequest request) {
+ logIncoming("notifyIncomingCall %s", request);
+ mCallIdMapper.checkValidCallId(request.getCallId());
+ mHandler.obtainMessage(MSG_NOTIFY_INCOMING_CALL, request).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void handleSuccessfulOutgoingCall(ConnectionRequest request) {
+ logIncoming("handleSuccessfulOutgoingCall %s", request);
+ mCallIdMapper.checkValidCallId(request.getCallId());
+ mHandler.obtainMessage(MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL, request).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void handleFailedOutgoingCall(
+ ConnectionRequest request,
+ int errorCode,
+ String errorMsg) {
+ logIncoming("handleFailedOutgoingCall %s %d %s", request, errorCode, errorMsg);
+ mCallIdMapper.checkValidCallId(request.getCallId());
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = request;
+ args.argi1 = errorCode;
+ args.arg2 = errorMsg;
+ mHandler.obtainMessage(MSG_HANDLE_FAILED_OUTGOING_CALL, args).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void cancelOutgoingCall(ConnectionRequest request) {
+ logIncoming("cancelOutgoingCall %s", request);
+ mCallIdMapper.checkValidCallId(request.getCallId());
+ mHandler.obtainMessage(MSG_CANCEL_OUTGOING_CALL, request).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setActive(String callId) {
+ logIncoming("setActive %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setRinging(String callId) {
+ logIncoming("setRinging %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_SET_RINGING, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setCallVideoProvider(String callId, ICallVideoProvider callVideoProvider) {
+ logIncoming("setCallVideoProvider %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = callVideoProvider;
+ mHandler.obtainMessage(MSG_SET_CALL_VIDEO_PROVIDER, args).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setDialing(String callId) {
+ logIncoming("setDialing %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_SET_DIALING, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setDisconnected(
+ String callId, int disconnectCause, String disconnectMessage) {
+ logIncoming("setDisconnected %s %d %s", callId, disconnectCause, disconnectMessage);
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = disconnectMessage;
+ args.argi1 = disconnectCause;
+ mHandler.obtainMessage(MSG_SET_DISCONNECTED, args).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setOnHold(String callId) {
+ logIncoming("setOnHold %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_SET_ON_HOLD, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setRequestingRingback(String callId, boolean ringback) {
+ logIncoming("setRequestingRingback %s %b", callId, ringback);
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = ringback;
+ mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, args).sendToTarget();
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void removeCall(String callId) {
+ logIncoming("removeCall %s", callId);
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void setCanConference(String callId, boolean canConference) {
+ logIncoming("setCanConference %s %b", callId, canConference);
+ mHandler.obtainMessage(MSG_CAN_CONFERENCE, canConference ? 1 : 0, 0, callId)
+ .sendToTarget();
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void setIsConferenced(String callId, String conferenceCallId) {
+ logIncoming("setIsConferenced %s %s", callId, conferenceCallId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = conferenceCallId;
+ mHandler.obtainMessage(MSG_SET_IS_CONFERENCED, args).sendToTarget();
+ }
+
+ /** ${InheritDoc} */
+ @Override
+ public void addConferenceCall(String callId) {
+ logIncoming("addConferenceCall %s", callId);
+ mCallIdMapper.checkValidCallId(callId);
+ mHandler.obtainMessage(MSG_ADD_CONFERENCE_CALL, callId).sendToTarget();
+ }
+
+ @Override
+ public void onPostDialWait(String callId, String remaining) throws RemoteException {
+ logIncoming("onPostDialWait %s %s", callId, remaining);
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = remaining;
+ mHandler.obtainMessage(MSG_ON_POST_DIAL_WAIT, args).sendToTarget();
+ }
+
+ /** ${inheritDoc} */
+ @Override
+ public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
+ logIncoming("queryRemoteCSs");
+ mHandler.obtainMessage(MSG_QUERY_REMOTE_CALL_SERVICES, callback).sendToTarget();
+ }
+
+ @Override
+ public void setFeatures(String callId, int features) {
+ logIncoming("setFeatures %s %d", callId, features);
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = features;
+ mHandler.obtainMessage(MSG_SET_FEATURES, args).sendToTarget();
+ }
+ }
+
+ private final Adapter mAdapter = new Adapter();
+ private final CallsManager mCallsManager = CallsManager.getInstance();
+ private final Set<Call> mPendingIncomingCalls = new HashSet<>();
+ private final Set<Call> mPendingConferenceCalls = new HashSet<>();
+ private final CallServiceDescriptor mDescriptor;
+ private final CallIdMapper mCallIdMapper = new CallIdMapper("ConnectionService");
+ private final IncomingCallsManager mIncomingCallsManager;
+ private final Map<String, OutgoingCallResponse> mPendingOutgoingCalls = new HashMap<>();
+
+ private Binder mBinder = new Binder();
+ private IConnectionService mServiceInterface;
+ private final CallServiceRepository mCallServiceRepository;
+
+ /**
+ * Creates a call-service for the specified descriptor.
+ *
+ * @param descriptor The call-service descriptor from
+ * {@link ICallServiceProvider#lookupCallServices}.
+ * @param incomingCallsManager Manages the incoming call initialization flow.
+ * @param callServiceRepository Connection service repository.
+ */
+ ConnectionServiceWrapper(
+ CallServiceDescriptor descriptor,
+ IncomingCallsManager incomingCallsManager,
+ CallServiceRepository callServiceRepository) {
+ super(TelecommConstants.ACTION_CONNECTION_SERVICE, descriptor.getServiceComponent());
+ mDescriptor = descriptor;
+ mIncomingCallsManager = incomingCallsManager;
+ mCallServiceRepository = callServiceRepository;
+ }
+
+ CallServiceDescriptor getDescriptor() {
+ return mDescriptor;
+ }
+
+ /** See {@link IConnectionService#addConnectionServiceAdapter}. */
+ private void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
+ if (isServiceValid("addConnectionServiceAdapter")) {
+ try {
+ logOutgoing("addConnectionServiceAdapter%s", adapter);
+ mServiceInterface.addConnectionServiceAdapter(adapter);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /**
+ * Attempts to place the specified call, see {@link IConnectionService#call}. Returns the result
+ * asynchronously through the specified callback.
+ */
+ 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, callResponse);
+
+ GatewayInfo gatewayInfo = call.getGatewayInfo();
+ Bundle extras = call.getExtras();
+ if (gatewayInfo != null && gatewayInfo.getGatewayProviderPackageName() != null &&
+ gatewayInfo.getOriginalHandle() != null) {
+ extras = (Bundle) extras.clone();
+ extras.putString(
+ NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_PROVIDER_PACKAGE,
+ gatewayInfo.getGatewayProviderPackageName());
+ extras.putParcelable(
+ NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
+ gatewayInfo.getOriginalHandle());
+ }
+ ConnectionRequest request = new ConnectionRequest(callId, call.getHandle(), extras);
+
+ try {
+ mServiceInterface.call(request);
+ } catch (RemoteException e) {
+ Log.e(this, e, "Failure to call -- %s", getDescriptor());
+ mPendingOutgoingCalls.remove(callId).onOutgoingCallFailure(
+ DisconnectCause.ERROR_UNSPECIFIED, e.toString());
+ }
+ }
+
+ @Override
+ public void onFailure() {
+ Log.e(this, new Exception(), "Failure to call %s", getDescriptor());
+ callResponse.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+ }
+ };
+
+ mBinder.bind(callback);
+ }
+
+ /** @see ConnectionService#abort(String) */
+ void abort(Call call) {
+ // Clear out any pending outgoing call data
+ String callId = mCallIdMapper.getCallId(call);
+
+ // If still bound, tell the connection service to abort.
+ if (isServiceValid("abort")) {
+ try {
+ logOutgoing("abort %s", callId);
+ mServiceInterface.abort(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ removeCall(call);
+ }
+
+ /** @see ConnectionService#hold(String) */
+ void hold(Call call) {
+ if (isServiceValid("hold")) {
+ try {
+ logOutgoing("hold %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.hold(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#unhold(String) */
+ void unhold(Call call) {
+ if (isServiceValid("unhold")) {
+ try {
+ logOutgoing("unhold %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.unhold(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#onAudioStateChanged(String,CallAudioState) */
+ void onAudioStateChanged(Call activeCall, CallAudioState audioState) {
+ if (isServiceValid("onAudioStateChanged")) {
+ try {
+ logOutgoing("onAudioStateChanged %s %s",
+ mCallIdMapper.getCallId(activeCall), audioState);
+ mServiceInterface.onAudioStateChanged(mCallIdMapper.getCallId(activeCall),
+ audioState);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /**
+ * Starts retrieval of details for an incoming call. Details are returned through the
+ * call-service adapter using the specified call ID. Upon failure, the specified error callback
+ * is invoked. Can be invoked even when the connection service is unbound. See
+ * {@link IConnectionService#createIncomingCall}.
+ *
+ * @param call The call used for the incoming call.
+ * @param extras The {@link ConnectionService}-provided extras which need to be sent back.
+ * @param errorCallback The callback to invoke upon failure.
+ */
+ void createIncomingCall(final Call call, final Bundle extras, final Runnable errorCallback) {
+ Log.d(this, "createIncomingCall(%s) via %s.", call, getComponentName());
+ BindCallback callback = new BindCallback() {
+ @Override
+ public void onSuccess() {
+ if (isServiceValid("createIncomingCall")) {
+ mPendingIncomingCalls.add(call);
+ String callId = mCallIdMapper.getCallId(call);
+ logOutgoing("createIncomingCall %s %s", callId, extras);
+ ConnectionRequest request = new ConnectionRequest(
+ callId, call.getHandle(), extras);
+ try {
+ mServiceInterface.createIncomingCall(request);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @Override
+ public void onFailure() {
+ errorCallback.run();
+ }
+ };
+
+ mBinder.bind(callback);
+ }
+
+ /** @see ConnectionService#disconnect(String) */
+ void disconnect(Call call) {
+ if (isServiceValid("disconnect")) {
+ try {
+ logOutgoing("disconnect %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.disconnect(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#answer(String) */
+ void answer(Call call) {
+ if (isServiceValid("answer")) {
+ try {
+ logOutgoing("answer %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.answer(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#reject(String) */
+ void reject(Call call) {
+ if (isServiceValid("reject")) {
+ try {
+ logOutgoing("reject %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.reject(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#playDtmfTone(String,char) */
+ void playDtmfTone(Call call, char digit) {
+ if (isServiceValid("playDtmfTone")) {
+ try {
+ logOutgoing("playDtmfTone %s %c", mCallIdMapper.getCallId(call), digit);
+ mServiceInterface.playDtmfTone(mCallIdMapper.getCallId(call), digit);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /** @see ConnectionService#stopDtmfTone(String) */
+ void stopDtmfTone(Call call) {
+ if (isServiceValid("stopDtmfTone")) {
+ try {
+ logOutgoing("stopDtmfTone %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.stopDtmfTone(mCallIdMapper.getCallId(call));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ void addCall(Call call) {
+ if (mCallIdMapper.getCallId(call) == null) {
+ mCallIdMapper.addCall(call);
+ }
+ }
+
+ /**
+ * Associates newCall with this connection service by replacing callToReplace.
+ */
+ void replaceCall(Call newCall, Call callToReplace) {
+ Preconditions.checkState(callToReplace.getConnectionService() == this);
+ mCallIdMapper.replaceCall(newCall, callToReplace);
+ }
+
+ void removeCall(Call call) {
+ mPendingIncomingCalls.remove(call);
+
+ OutgoingCallResponse outgoingResultCallback =
+ mPendingOutgoingCalls.remove(mCallIdMapper.getCallId(call));
+ if (outgoingResultCallback != null) {
+ outgoingResultCallback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+ }
+
+ mCallIdMapper.removeCall(call);
+ }
+
+ void onPostDialContinue(Call call, boolean proceed) {
+ if (isServiceValid("onPostDialContinue")) {
+ try {
+ logOutgoing("onPostDialContinue %s %b", mCallIdMapper.getCallId(call), proceed);
+ mServiceInterface.onPostDialContinue(mCallIdMapper.getCallId(call), proceed);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ void onPhoneAccountClicked(Call call) {
+ if (isServiceValid("onPhoneAccountClicked")) {
+ try {
+ logOutgoing("onPhoneAccountClicked %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.onPhoneAccountClicked(mCallIdMapper.getCallId(call));
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ void conference(final Call conferenceCall, Call call) {
+ if (isServiceValid("conference")) {
+ try {
+ conferenceCall.setConnectionService(this);
+ mPendingConferenceCalls.add(conferenceCall);
+ mHandler.postDelayed(new Runnable() {
+ @Override public void run() {
+ if (mPendingConferenceCalls.remove(conferenceCall)) {
+ conferenceCall.expireConference();
+ Log.i(this, "Conference call expired: %s", conferenceCall);
+ }
+ }
+ }, Timeouts.getConferenceCallExpireMillis());
+
+ logOutgoing("conference %s %s",
+ mCallIdMapper.getCallId(conferenceCall),
+ mCallIdMapper.getCallId(call));
+ mServiceInterface.conference(
+ mCallIdMapper.getCallId(conferenceCall),
+ mCallIdMapper.getCallId(call));
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ void splitFromConference(Call call) {
+ if (isServiceValid("splitFromConference")) {
+ try {
+ logOutgoing("splitFromConference %s", mCallIdMapper.getCallId(call));
+ mServiceInterface.splitFromConference(mCallIdMapper.getCallId(call));
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void setServiceInterface(IBinder binder) {
+ if (binder == null) {
+ // We have lost our service connection. Notify the world that this service is done.
+ // We must notify the adapter before CallsManager. The adapter will force any pending
+ // outgoing calls to try the next service. This needs to happen before CallsManager
+ // tries to clean up any calls still associated with this service.
+ handleConnectionServiceDeath();
+ CallsManager.getInstance().handleConnectionServiceDeath(this);
+ mServiceInterface = null;
+ } else {
+ mServiceInterface = IConnectionService.Stub.asInterface(binder);
+ addConnectionServiceAdapter(mAdapter);
+ }
+ }
+
+ /**
+ * Called when the associated connection service dies.
+ */
+ private void handleConnectionServiceDeath() {
+ if (!mPendingOutgoingCalls.isEmpty()) {
+ for (OutgoingCallResponse callback : mPendingOutgoingCalls.values()) {
+ callback.onOutgoingCallFailure(DisconnectCause.ERROR_UNSPECIFIED, null);
+ }
+ mPendingOutgoingCalls.clear();
+ }
+
+ if (!mPendingIncomingCalls.isEmpty()) {
+ // Iterate through a copy because the code inside the loop will modify the original
+ // list.
+ for (Call call : ImmutableList.copyOf(mPendingIncomingCalls)) {
+ Preconditions.checkState(call.isIncoming());
+ mIncomingCallsManager.handleFailedIncomingCall(call);
+ }
+
+ if (!mPendingIncomingCalls.isEmpty()) {
+ Log.wtf(this, "Pending calls did not get cleared.");
+ mPendingIncomingCalls.clear();
+ }
+ }
+
+ mCallIdMapper.clear();
+ }
+
+ private void logIncoming(String msg, Object... params) {
+ Log.d(this, "ConnectionService -> Telecomm: " + msg, params);
+ }
+
+ private void logOutgoing(String msg, Object... params) {
+ Log.d(this, "Telecomm -> ConnectionService: " + msg, params);
+ }
+
+ private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
+ final List<IBinder> connectionServices = new ArrayList<>();
+ final List<ComponentName> components = new ArrayList<>();
+
+ mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
+ private int mRemainingResponses;
+
+ /** ${inheritDoc} */
+ @Override
+ public void onComplete(Collection<ConnectionServiceWrapper> services) {
+ mRemainingResponses = services.size() - 1;
+ for (ConnectionServiceWrapper cs : services) {
+ if (cs != ConnectionServiceWrapper.this) {
+ final ConnectionServiceWrapper currentConnectionService = cs;
+ cs.mBinder.bind(new BindCallback() {
+ @Override
+ public void onSuccess() {
+ Log.d(this, "Adding ***** %s",
+ currentConnectionService.getDescriptor());
+ connectionServices.add(
+ currentConnectionService.mServiceInterface.asBinder());
+ components.add(currentConnectionService.getComponentName());
+ maybeComplete();
+ }
+
+ @Override
+ public void onFailure() {
+ // add null so that we always add up to totalExpected even if
+ // some of the connection services fail to bind.
+ maybeComplete();
+ }
+
+ private void maybeComplete() {
+ if (--mRemainingResponses == 0) {
+ try {
+ callback.onResult(components, connectionServices);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index c1c8eaf..d1215ae 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -103,10 +103,10 @@
}
@Override
- public void onCallServiceChanged(
+ public void onConnectionServiceChanged(
Call call,
- CallServiceWrapper oldCallServiceWrapper,
- CallServiceWrapper newCallService) {
+ ConnectionServiceWrapper oldService,
+ ConnectionServiceWrapper newService) {
updateCall(call);
}
@@ -261,8 +261,8 @@
private InCallCall toInCallCall(Call call) {
String callId = mCallIdMapper.getCallId(call);
- CallServiceDescriptor descriptor =
- call.getCallService() != null ? call.getCallService().getDescriptor() : null;
+ CallServiceDescriptor descriptor = call.getConnectionService() != null ?
+ call.getConnectionService().getDescriptor() : null;
int capabilities = CallCapabilities.HOLD | CallCapabilities.MUTE;
if (CallsManager.getInstance().isAddCallCapable(call)) {
diff --git a/src/com/android/telecomm/IncomingCallsManager.java b/src/com/android/telecomm/IncomingCallsManager.java
index 5a874ea..197f699 100644
--- a/src/com/android/telecomm/IncomingCallsManager.java
+++ b/src/com/android/telecomm/IncomingCallsManager.java
@@ -17,8 +17,8 @@
package com.android.telecomm;
import android.os.Bundle;
-import android.telecomm.CallInfo;
-import android.telecomm.CallService;
+import android.telecomm.ConnectionService;
+import android.telecomm.ConnectionRequest;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
@@ -34,11 +34,12 @@
private final Set<Call> mPendingIncomingCalls = Sets.newLinkedHashSet();
/**
- * Retrieves details of an incoming call through its associated call service.
+ * Retrieves details of an incoming call through its associated connection service.
*
* @param call The call object.
* @param extras The optional extras passed with the incoming call intent (to be returned to
- * the call service via {@link CallService#setIncomingCallId(String, android.os.Bundle)}).
+ * the connection service via
+ * {@link ConnectionService#createIncomingCall(ConnectionRequest)}.
*/
void retrieveIncomingCall(final Call call, Bundle extras) {
ThreadUtil.checkOnMainThread();
@@ -55,22 +56,22 @@
}
};
- call.getCallService().setIncomingCallId(call, extras, errorCallback);
+ call.getConnectionService().createIncomingCall(call, extras, errorCallback);
}
/**
* Notifies the incoming call of success after removing it from the pending
* list.
*
- * @param callInfo The details of the call.
+ * @param request The details of the call.
*/
- void handleSuccessfulIncomingCall(Call call, CallInfo callInfo) {
+ void handleSuccessfulIncomingCall(Call call, ConnectionRequest request) {
ThreadUtil.checkOnMainThread();
if (mPendingIncomingCalls.contains(call)) {
Log.d(this, "Incoming call %s found.", call);
mPendingIncomingCalls.remove(call);
- call.handleVerifiedIncoming(callInfo);
+ call.handleVerifiedIncoming(request);
}
}
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index 9d1f008..c33b17e 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -35,11 +35,9 @@
import java.util.Set;
/**
- * Utility class to place a call using the specified set of call-services and ordered selectors.
- * Iterates through the selectors and gets a sorted list of supported call-service descriptors
- * for each selector. Upon receiving each sorted list (one list per selector), each of the
- * corresponding call services is then attempted until either the outgoing call is placed, the
- * attempted call is aborted, or the list is exhausted -- whichever occurs first.
+ * Utility class to place a call using the specified set of call-services. Each of the connection
+ * services is then attempted until either the outgoing call is placed, the attempted call is
+ * aborted, or the list is exhausted -- whichever occurs first.
*
* Except for the abort case, all other scenarios should terminate with the call notified
* of the result.
@@ -54,13 +52,13 @@
/**
* The map of currently-available call-service implementations keyed by call-service ID.
*/
- private final Map<String, CallServiceWrapper> mCallServicesById = Maps.newHashMap();
+ private final Map<String, ConnectionServiceWrapper> mConnectionServicesById = Maps.newHashMap();
/**
- * The set of attempted call services, used to ensure services are attempted at most once per
- * outgoing-call attempt.
+ * The set of attempted connection services, used to ensure services are attempted at most once
+ * per outgoing-call attempt.
*/
- private final Set<CallServiceWrapper> mAttemptedCallServices = Sets.newHashSet();
+ private final Set<ConnectionServiceWrapper> mAttemptedConnectionServices = Sets.newHashSet();
private final CallServiceRepository mCallServiceRepository;
@@ -84,8 +82,8 @@
/**
* Persists the specified parameters and iterates through the prioritized list of call
- * services. Stops once a matching call service is found. Calls with no matching
- * call service will eventually be killed by the cleanup/monitor switchboard handler.
+ * services. Stops once a matching connection service is found. Calls with no matching
+ * connection service will eventually be killed by the cleanup/monitor switchboard handler.
*
* @param call The call to place.
* @param callServiceRepository
@@ -109,11 +107,11 @@
void process() {
Log.v(this, "process, mIsAborted: %b", mIsAborted);
if (!mIsAborted) {
- // Lookup call services
- mCallServiceRepository.lookupServices(new LookupCallback<CallServiceWrapper>() {
+ // Lookup connection services
+ mCallServiceRepository.lookupServices(new LookupCallback<ConnectionServiceWrapper>() {
@Override
- public void onComplete(Collection<CallServiceWrapper> services) {
- setCallServices(services);
+ public void onComplete(Collection<ConnectionServiceWrapper> services) {
+ setConnectionServices(services);
}
});
}
@@ -129,14 +127,15 @@
if (!mIsAborted && mResultCallback != null) {
mIsAborted = true;
- // On an abort, we need to check if we already told the call service to place the
+ // On an abort, we need to check if we already told the connection service to place the
// call. If so, we need to tell it to abort.
- // TODO(santoscordon): The call service is saved with the call and so we have to query
- // the call to get it, which is a bit backwards. Ideally, the call service would be
- // saved inside this class until the whole thing is complete and then set on the call.
- CallServiceWrapper callService = mCall.getCallService();
- if (callService != null) {
- callService.abort(mCall);
+ // TODO(santoscordon): The conneciton service is saved with the call and so we have to
+ // query the call to get it, which is a bit backwards. Ideally, the connection service
+ // would be saved inside this class until the whole thing is complete and then set on
+ // the call.
+ ConnectionServiceWrapper service = mCall.getConnectionService();
+ if (service != null) {
+ service.abort(mCall);
}
// We consider a deliberate abort to be a "normal" disconnect, not
@@ -150,17 +149,16 @@
}
/**
- * Completes the outgoing call sequence by setting the call service on the call object. This is
- * invoked when the call service adapter receives positive confirmation that the call service
- * placed the call.
+ * Completes the outgoing call sequence by setting the connection service on the call object.
+ * This is invoked when the connection service adapter receives positive confirmation that the
+ * connection service placed the call.
*/
- void handleSuccessfulCallAttempt(CallServiceWrapper callService) {
+ void handleSuccessfulCallAttempt(ConnectionServiceWrapper service) {
Log.v(this, "handleSuccessfulCallAttempt");
ThreadUtil.checkOnMainThread();
if (mIsAborted) {
- // TODO(gilad): Ask the call service to drop the call?
- callService.abort(mCall);
+ service.abort(mCall);
return;
}
@@ -168,8 +166,8 @@
}
/**
- * Attempts the next call service if the specified call service is the one currently being
- * attempted.
+ * Attempts the next connection service if the specified connection service is the one currently
+ * being attempted.
*
* @param errorCode The reason for the failure, one of {@link DisconnectCause}.
* @param errorMsg Optional text reason for the failure.
@@ -182,91 +180,90 @@
mLastErrorMsg = errorMsg;
if (!mIsAborted) {
ThreadUtil.checkOnMainThread();
- attemptNextCallService();
+ attemptNextConnectionService();
}
}
/**
- * Sets the call services to attempt for this outgoing call.
+ * Sets the connection services to attempt for this outgoing call.
*
- * @param callServices The call services.
+ * @param services The connection services.
*/
- private void setCallServices(Collection<CallServiceWrapper> callServices) {
+ private void setConnectionServices(Collection<ConnectionServiceWrapper> services) {
mCallServiceDescriptors = new ArrayList<>();
- // Populate the list and map of call-service descriptors. The list is needed since
- // it's being passed down to selectors.
- for (CallServiceWrapper callService : callServices) {
- CallServiceDescriptor descriptor = callService.getDescriptor();
+ // Populate the list and map of call-service descriptors.
+ for (ConnectionServiceWrapper service : services) {
+ CallServiceDescriptor descriptor = service.getDescriptor();
// TODO(sail): Remove once there's a way to pick the service.
if (descriptor.getServiceComponent().getPackageName().equals(
"com.google.android.talk")) {
- Log.i(this, "Moving call service %s to top of list", descriptor);
+ Log.i(this, "Moving connection service %s to top of list", descriptor);
mCallServiceDescriptors.add(0, descriptor);
} else {
mCallServiceDescriptors.add(descriptor);
}
- mCallServicesById.put(descriptor.getCallServiceId(), callService);
+ mConnectionServicesById.put(descriptor.getConnectionServiceId(), service);
}
adjustCallServiceDescriptorsForEmergency();
mCallServiceDescriptorIterator = mCallServiceDescriptors.iterator();
- attemptNextCallService();
+ attemptNextConnectionService();
}
/**
- * Attempts to place the call using the call service specified by the next call-service
+ * Attempts to place the call using the connection service specified by the next call-service
* descriptor of mCallServiceDescriptorIterator.
*/
- private void attemptNextCallService() {
- Log.v(this, "attemptNextCallService, mIsAborted: %b", mIsAborted);
+ private void attemptNextConnectionService() {
+ Log.v(this, "attemptNextConnectionService, mIsAborted: %b", mIsAborted);
if (mIsAborted) {
return;
}
if (mCallServiceDescriptorIterator != null && mCallServiceDescriptorIterator.hasNext()) {
CallServiceDescriptor descriptor = mCallServiceDescriptorIterator.next();
- final CallServiceWrapper callService =
- mCallServicesById.get(descriptor.getCallServiceId());
+ final ConnectionServiceWrapper service =
+ mConnectionServicesById.get(descriptor.getConnectionServiceId());
- if (callService == null || mAttemptedCallServices.contains(callService)) {
- // The next call service is either null or has already been attempted, fast forward
- // to the next.
- attemptNextCallService();
+ if (service == null || mAttemptedConnectionServices.contains(service)) {
+ // The next connection service is either null or has already been attempted, fast
+ // forward to the next.
+ attemptNextConnectionService();
} else {
- mAttemptedCallServices.add(callService);
- mCall.setCallService(callService);
+ mAttemptedConnectionServices.add(service);
+ mCall.setConnectionService(service);
// Increment the associated call count until we get a result. This prevents the call
// service from unbinding while we are using it.
- callService.incrementAssociatedCallCount();
+ service.incrementAssociatedCallCount();
- Log.i(this, "Attempting to call from %s", callService.getDescriptor());
- callService.call(mCall, new OutgoingCallResponse() {
+ Log.i(this, "Attempting to call from %s", service.getDescriptor());
+ service.call(mCall, new OutgoingCallResponse() {
@Override
public void onOutgoingCallSuccess() {
- handleSuccessfulCallAttempt(callService);
- callService.decrementAssociatedCallCount();
+ handleSuccessfulCallAttempt(service);
+ service.decrementAssociatedCallCount();
}
@Override
public void onOutgoingCallFailure(int code, String msg) {
handleFailedCallAttempt(code, msg);
- callService.decrementAssociatedCallCount();
+ service.decrementAssociatedCallCount();
}
@Override
public void onOutgoingCallCancel() {
abort();
- callService.decrementAssociatedCallCount();
+ service.decrementAssociatedCallCount();
}
});
}
} else {
- Log.v(this, "attemptNextCallService, no more service descriptors, failing");
+ Log.v(this, "attemptNextConnectionService, no more service descriptors, failing");
mCallServiceDescriptorIterator = null;
- mCall.clearCallService();
+ mCall.clearConnectionService();
sendResult(false, mLastErrorCode, mLastErrorMsg);
}
}
@@ -287,11 +284,11 @@
}
// If we are possibly attempting to call a local emergency number, ensure that the
- // plain PSTN call service, if it exists, is attempted first.
+ // plain PSTN connection service, if it exists, is attempted first.
private void adjustCallServiceDescriptorsForEmergency() {
for (int i = 0; i < mCallServiceDescriptors.size(); i++) {
if (shouldProcessAsEmergency(mCall.getHandle())) {
- if (TelephonyUtil.isPstnCallService(mCallServiceDescriptors.get(i))) {
+ if (TelephonyUtil.isPstnConnectionService(mCallServiceDescriptors.get(i))) {
mCallServiceDescriptors.add(0, mCallServiceDescriptors.remove(i));
return;
}
diff --git a/src/com/android/telecomm/PhoneStateBroadcaster.java b/src/com/android/telecomm/PhoneStateBroadcaster.java
index d6f1a38..4dee4bb 100644
--- a/src/com/android/telecomm/PhoneStateBroadcaster.java
+++ b/src/com/android/telecomm/PhoneStateBroadcaster.java
@@ -18,8 +18,8 @@
import android.Manifest;
import android.content.Intent;
-import android.telecomm.CallService;
import android.telecomm.CallState;
+import android.telecomm.ConnectionService;
import android.telecomm.TelecommConstants;
import android.telephony.DisconnectCause;
import android.telephony.TelephonyManager;
@@ -68,9 +68,11 @@
}
// TODO: Replace these with real constants once this API has been vetted.
- CallServiceWrapper callService = call.getCallService();
- if (callService != null) {
- intent.putExtra(CallService.class.getName(), callService.getComponentName());
+ ConnectionServiceWrapper connectionService = call.getConnectionService();
+ if (connectionService != null) {
+ intent.putExtra(
+ TelecommConstants.EXTRA_CONNECTION_SERVICE,
+ connectionService.getComponentName());
}
// TODO: Replace these with real constants once this API has been vetted.
diff --git a/src/com/android/telecomm/RingbackPlayer.java b/src/com/android/telecomm/RingbackPlayer.java
index 8fd6697..bfd5f62 100644
--- a/src/com/android/telecomm/RingbackPlayer.java
+++ b/src/com/android/telecomm/RingbackPlayer.java
@@ -60,16 +60,15 @@
}
@Override
- public void onCallServiceChanged(
+ public void onConnectionServiceChanged(
Call call,
- CallServiceWrapper oldCallServiceWrapper,
- CallServiceWrapper newCallService) {
+ ConnectionServiceWrapper oldService,
+ ConnectionServiceWrapper newService) {
- super.onCallServiceChanged(call, oldCallServiceWrapper, newCallService);
// Treat as ending or begining dialing based on the state transition.
if (shouldStartRinging(call)) {
startRingbackForCall(call);
- } else if (newCallService == null) {
+ } else if (newService == null) {
stopRingbackForCall(call);
}
}
diff --git a/src/com/android/telecomm/ServiceBinder.java b/src/com/android/telecomm/ServiceBinder.java
index 55e39f0..e918593 100644
--- a/src/com/android/telecomm/ServiceBinder.java
+++ b/src/com/android/telecomm/ServiceBinder.java
@@ -81,7 +81,7 @@
Intent serviceIntent = new Intent(mServiceAction).setComponent(mComponentName);
ServiceConnection connection = new ServiceBinderConnection();
- Log.d(ServiceBinder.this, "Binding to call service with intent: %s", serviceIntent);
+ Log.d(ServiceBinder.this, "Binding to service with intent: %s", serviceIntent);
if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
handleFailedConnection();
return;
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 7c6d44d..b7a7e9e 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -20,7 +20,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.telecomm.CallInfo;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.TelecommConstants;
@@ -34,7 +33,7 @@
import java.util.Set;
/**
- * Switchboard is responsible for gathering the {@link CallServiceWrapper}s through
+ * Switchboard is responsible for gathering the {@link ConnectionServiceWrapper}s through
* which to place outgoing calls
*/
final class Switchboard {
@@ -75,8 +74,8 @@
*/
void retrieveIncomingCall(Call call, CallServiceDescriptor descriptor, Bundle extras) {
Log.d(this, "retrieveIncomingCall");
- CallServiceWrapper callService = mCallServiceRepository.getService(descriptor);
- call.setCallService(callService);
+ ConnectionServiceWrapper service = mCallServiceRepository.getService(descriptor);
+ call.setConnectionService(service);
mIncomingCallsManager.retrieveIncomingCall(call, extras);
}
}
diff --git a/src/com/android/telecomm/TelephonyUtil.java b/src/com/android/telecomm/TelephonyUtil.java
index 83303c7..783b427 100644
--- a/src/com/android/telecomm/TelephonyUtil.java
+++ b/src/com/android/telecomm/TelephonyUtil.java
@@ -35,7 +35,7 @@
private TelephonyUtil() {}
- static boolean isPstnCallService(CallServiceDescriptor descriptor) {
+ static boolean isPstnConnectionService(CallServiceDescriptor descriptor) {
final ComponentName pstnComponentName = new ComponentName(
TELEPHONY_PACKAGE_NAME, PSTN_CALL_SERVICE_CLASS_NAME);
return pstnComponentName.equals(descriptor.getServiceComponent());
@@ -47,26 +47,27 @@
*/
static boolean isCurrentlyPSTNCall(Call call) {
if (Log.DEBUG) {
- verifyCallServiceExists(PSTN_CALL_SERVICE_CLASS_NAME);
+ verifyConnectionServiceExists(PSTN_CALL_SERVICE_CLASS_NAME);
}
- CallServiceWrapper callService = call.getCallService();
- if (callService == null) {
+ ConnectionServiceWrapper service = call.getConnectionService();
+ if (service == null) {
return false;
}
- return isPstnCallService(callService.getDescriptor());
+ return isPstnConnectionService(service.getDescriptor());
}
- private static void verifyCallServiceExists(String serviceName) {
+ private static void verifyConnectionServiceExists(String serviceName) {
PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
try {
ServiceInfo info = packageManager.getServiceInfo(
new ComponentName(TELEPHONY_PACKAGE_NAME, serviceName), 0);
if (info == null) {
- Log.wtf(TAG, "Error, unable to find call service: %s", serviceName);
+ Log.wtf(TAG, "Error, unable to find connection service: %s", serviceName);
}
} catch (PackageManager.NameNotFoundException e) {
- Log.wtf(TAG, e, "Error, exception while trying to find call service: %s", serviceName);
+ Log.wtf(TAG, e, "Error, exception while trying to find connection service: %s",
+ serviceName);
}
}
}
diff --git a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index 6364377..ff52157 100644
--- a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -111,7 +111,7 @@
log("Creating incoming call pending intent.");
// Build descriptor for TestConnectionService.
CallServiceDescriptor.Builder descriptorBuilder = CallServiceDescriptor.newBuilder(context);
- descriptorBuilder.setCallService(TestConnectionService.class);
+ descriptorBuilder.setConnectionService(TestConnectionService.class);
descriptorBuilder.setNetworkType(CallServiceDescriptor.FLAG_WIFI);
// Create intent for adding an incoming call.
diff --git a/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java b/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
index b1d32a3..41a893e 100644
--- a/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallServiceProvider.java
@@ -24,7 +24,7 @@
import com.google.common.collect.Lists;
/**
- * Service which provides fake calls to test the ICallService interface.
+ * Service which provides fake calls to test the IConnectionService interface.
* TODO(santoscordon): Build more dummy providers for more CallServiceDescriptor.FLAG_* types.
*/
public class TestCallServiceProvider extends CallServiceProvider {
@@ -34,7 +34,7 @@
log("lookupCallServices");
CallServiceDescriptor.Builder builder = CallServiceDescriptor.newBuilder(this);
- builder.setCallService(TestConnectionService.class);
+ builder.setConnectionService(TestConnectionService.class);
builder.setNetworkType(CallServiceDescriptor.FLAG_WIFI);
response.setCallServiceDescriptors(Lists.newArrayList(builder.build()));
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionService.java b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
index 241f8ee..4ada090 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionService.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
@@ -74,6 +74,11 @@
}
@Override
+ public void onFeaturesChanged(RemoteConnection connection, int features) {
+ setFeatures(features);
+ }
+
+ @Override
public void onDestroyed(RemoteConnection connection) {
setDestroyed();
}