Telecomm implementation of CallServiceSelectorAdapter
Bug: 13643568
Change-Id: Ida5859a3b5b15c9fa1c533f27a3e14fd0d7c36af
diff --git a/src/com/android/telecomm/CallServiceAdapter.java b/src/com/android/telecomm/CallServiceAdapter.java
index 4bd7743..2db6255 100644
--- a/src/com/android/telecomm/CallServiceAdapter.java
+++ b/src/com/android/telecomm/CallServiceAdapter.java
@@ -66,7 +66,8 @@
clientCallInfo.getHandle());
mIncomingCallsManager.handleSuccessfulIncomingCall(call, callInfo);
} else {
- Log.w(this, "Unknown incoming call: %s, id: %s", call, msg.obj);
+ Log.w(this, "Unknown incoming call: %s, id: %s", call,
+ clientCallInfo.getId());
}
break;
case MSG_HANDLE_SUCCESSFUL_OUTGOING_CALL:
@@ -86,7 +87,7 @@
if (call != null && mPendingCalls.remove(call) && !call.isIncoming()) {
mOutgoingCallsManager.handleFailedCallAttempt(call, reason);
} else {
- Log.w(this, "Unknown outgoing call: %s, id: %s", call, msg.obj);
+ Log.w(this, "Unknown outgoing call: %s, id: %s", call, args.arg1);
}
} finally {
args.recycle();
@@ -127,7 +128,7 @@
mCallsManager.markCallAsDisconnected(call, disconnectCause,
disconnectMessage);
} else {
- Log.w(this, "Unknown call id: %s", msg.obj);
+ Log.w(this, "Unknown call id: %s", args.arg1);
}
} finally {
args.recycle();
diff --git a/src/com/android/telecomm/CallServiceSelectorAdapter.java b/src/com/android/telecomm/CallServiceSelectorAdapter.java
new file mode 100644
index 0000000..5c805c5
--- /dev/null
+++ b/src/com/android/telecomm/CallServiceSelectorAdapter.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.telecomm.CallServiceDescriptor;
+
+import com.android.internal.telecomm.ICallServiceSelectorAdapter;
+import com.android.internal.os.SomeArgs;
+
+import java.util.List;
+
+/**
+ * Used by call service selector to communicate with Telecomm.
+ */
+public final class CallServiceSelectorAdapter extends ICallServiceSelectorAdapter.Stub {
+ private static final int MSG_SET_SELECTED_CALL_SERVICES = 0;
+ private static final int MSG_SET_HANDOFF_INFO = 1;
+
+ private final class CallServiceSelectorAdapaterHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_SELECTED_CALL_SERVICES: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Call call = mCallIdMapper.getCall(args.arg1);
+ List<CallServiceDescriptor> descriptors =
+ (List<CallServiceDescriptor>) args.arg2;
+ if (call != null) {
+ mOutgoingCallsManager.processSelectedCallServices(call, descriptors);
+ } else {
+ Log.w(this, "Unknown call: %s, id: %s", call, args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_SET_HANDOFF_INFO: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ Call call = mCallIdMapper.getCall(args.arg1);
+ Uri handle = (Uri) args.arg2;
+ Bundle extras = (Bundle) args.arg3;
+ if (call != null) {
+ mCallsManager.setHandoffInfo(call, handle, extras);
+ } else {
+ Log.w(this, "Unknown call: %s, id: %s", call, args.arg1);
+ }
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private final Handler mHandler = new CallServiceSelectorAdapaterHandler();
+ private final CallsManager mCallsManager;
+ private final OutgoingCallsManager mOutgoingCallsManager;
+ private final CallIdMapper mCallIdMapper;
+
+ CallServiceSelectorAdapter(
+ CallsManager callsManager,
+ OutgoingCallsManager outgoingCallsManager,
+ CallIdMapper callIdMapper) {
+ ThreadUtil.checkOnMainThread();
+ mCallsManager = callsManager;
+ mOutgoingCallsManager = outgoingCallsManager;
+ mCallIdMapper = callIdMapper;
+ }
+
+ /**
+ * @see CallServiceSelectorAdapater#setSelectedCallServices(String,List<CallServiceDescriptor>)
+ */
+ @Override
+ public void setSelectedCallServices(String callId, List<CallServiceDescriptor> descriptors) {
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = descriptors;
+ mHandler.obtainMessage(MSG_SET_SELECTED_CALL_SERVICES, args).sendToTarget();
+ }
+
+ /** @see CallServiceSelectorAdapater#setHandoffInfo(String,Uri,Bundle) */
+ @Override
+ public void setHandoffInfo(String callId, Uri handle, Bundle extras) {
+ mCallIdMapper.checkValidCallId(callId);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = handle;
+ args.arg3 = extras;
+ mHandler.obtainMessage(MSG_SET_HANDOFF_INFO, args).sendToTarget();
+ }
+}
diff --git a/src/com/android/telecomm/CallServiceSelectorRepository.java b/src/com/android/telecomm/CallServiceSelectorRepository.java
index 0ec805f..50d26e8 100644
--- a/src/com/android/telecomm/CallServiceSelectorRepository.java
+++ b/src/com/android/telecomm/CallServiceSelectorRepository.java
@@ -39,9 +39,7 @@
final class CallServiceSelectorRepository {
private final Switchboard mSwitchboard;
-
- /** The application context. */
- private final Context mContext;
+ private final OutgoingCallsManager mOutgoingCallsManager;
/**
* The set of call-service selectors. Only populated via initiateLookup scenarios.
@@ -54,9 +52,11 @@
*
* @param switchboard The switchboard for this finer to work against.
*/
- CallServiceSelectorRepository(Switchboard switchboard) {
+ CallServiceSelectorRepository(
+ Switchboard switchboard,
+ OutgoingCallsManager outgoingCallsManager) {
mSwitchboard = switchboard;
- mContext = TelecommApp.getInstance();
+ mOutgoingCallsManager = outgoingCallsManager;
}
/**
@@ -70,7 +70,8 @@
List<ComponentName> selectorNames = getSelectorNames();
for (ComponentName name : selectorNames) {
if (!mCallServiceSelectors.containsKey(name)) {
- mCallServiceSelectors.put(name, new CallServiceSelectorWrapper(name));
+ mCallServiceSelectors.put(name, new CallServiceSelectorWrapper(name,
+ CallsManager.getInstance(), mOutgoingCallsManager));
}
}
@@ -86,7 +87,7 @@
// The list of selector names to return to the caller, may be populated below.
List<ComponentName> selectorNames = Lists.newArrayList();
- PackageManager packageManager = mContext.getPackageManager();
+ PackageManager packageManager = TelecommApp.getInstance().getPackageManager();
Intent intent = new Intent(TelecommConstants.ACTION_CALL_SERVICE_SELECTOR);
for (ResolveInfo entry : packageManager.queryIntentServices(intent, 0)) {
ServiceInfo serviceInfo = entry.serviceInfo;
diff --git a/src/com/android/telecomm/CallServiceSelectorWrapper.java b/src/com/android/telecomm/CallServiceSelectorWrapper.java
index 6db5c8f..f4ddf19 100644
--- a/src/com/android/telecomm/CallServiceSelectorWrapper.java
+++ b/src/com/android/telecomm/CallServiceSelectorWrapper.java
@@ -23,12 +23,11 @@
import android.telecomm.CallInfo;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.CallServiceSelector;
-import android.telecomm.CallServiceSelector.CallServiceSelectionResponse;
import android.telecomm.TelecommConstants;
import com.google.common.base.Preconditions;
-import com.android.internal.telecomm.ICallServiceSelectionResponse;
import com.android.internal.telecomm.ICallServiceSelector;
+import com.android.internal.telecomm.ICallServiceSelectorAdapter;
import java.util.List;
@@ -37,59 +36,53 @@
* safely be unbound.
*/
final class CallServiceSelectorWrapper extends ServiceBinder<ICallServiceSelector> {
- class SelectionResponseImpl extends ICallServiceSelectionResponse.Stub {
- private final CallServiceSelectionResponse mResponse;
-
- SelectionResponseImpl(CallServiceSelectionResponse response) {
- mResponse = response;
- }
-
- @Override
- public void setSelectedCallServiceDescriptors(
- final List<CallServiceDescriptor> descriptors) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mResponse.setSelectedCallServices(descriptors);
- }
- });
- }
- }
-
private ICallServiceSelector mSelectorInterface;
private final Binder mBinder = new Binder();
private final Handler mHandler = new Handler();
private final CallIdMapper mCallIdMapper = new CallIdMapper("CallServiceSelector");
+ private final CallServiceSelectorAdapter mAdapter;
/**
* Creates a call-service selector for the specified component.
*
* @param componentName The component name of the service.
*/
- CallServiceSelectorWrapper(ComponentName componentName) {
+ CallServiceSelectorWrapper(ComponentName componentName, CallsManager callsManager,
+ OutgoingCallsManager outgoingCallsManager) {
super(TelecommConstants.ACTION_CALL_SERVICE_SELECTOR, componentName);
+ mAdapter = new CallServiceSelectorAdapter(callsManager, outgoingCallsManager,
+ mCallIdMapper);
+ }
+
+ /** See {@link CallServiceSelector#setCallServiceSelectorAdapter}. */
+ private void setCallServiceSelectorAdapter(ICallServiceSelectorAdapter adapter) {
+ if (isServiceValid("setCallServiceSelectorAdapter")) {
+ try {
+ mSelectorInterface.setCallServiceSelectorAdapter(adapter);
+ } catch (RemoteException e) {
+ }
+ }
}
/**
* Retrieves the sorted set of call services that are preferred by this selector. Upon failure,
* the error callback is invoked. Can be invoked even when the call service is unbound.
*
- * @param selectionResponse The selection response callback to invoke upon success.
+ * @param call The call being placed using the {@link CallService}s.
+ * @param descriptors The descriptors of the available {@link CallService}s with which to place
+ * the call.
* @param errorCallback The callback to invoke upon failure.
*/
- void select(final Call call, final List<CallServiceDescriptor> callServiceDescriptors,
- final CallServiceSelectionResponse selectionResponse, final Runnable errorCallback) {
+ void select(final Call call, final List<CallServiceDescriptor> descriptors,
+ final Runnable errorCallback) {
BindCallback callback = new BindCallback() {
@Override
public void onSuccess() {
if (isServiceValid("select")) {
try {
CallInfo callInfo = call.toCallInfo(mCallIdMapper.getCallId(call));
- mSelectorInterface.select(callInfo, callServiceDescriptors,
- new SelectionResponseImpl(selectionResponse));
+ mSelectorInterface.select(callInfo, descriptors);
} catch (RemoteException e) {
- Log.e(CallServiceSelectorWrapper.this, e,
- "Failed calling select for selector: %s.", getComponentName());
}
}
}
@@ -114,6 +107,11 @@
/** {@inheritDoc} */
@Override
protected void setServiceInterface(IBinder binder) {
- mSelectorInterface = ICallServiceSelector.Stub.asInterface(binder);
+ if (binder == null) {
+ mSelectorInterface = null;
+ } else {
+ mSelectorInterface = ICallServiceSelector.Stub.asInterface(binder);
+ setCallServiceSelectorAdapter(mAdapter);
+ }
}
}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 0387fab..3e8a42e 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -403,6 +403,10 @@
removeCall(call);
}
+ void setHandoffInfo(Call call, Uri handle, Bundle extras) {
+ // TODO(sail): Implement this.
+ }
+
/**
* Cleans up any calls currently associated with the specified call service when the
* call-service binder disconnects unexpectedly.
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index ca4b33e..315a9bd 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -21,7 +21,6 @@
import android.os.RemoteException;
import android.telecomm.CallState;
import android.telecomm.CallServiceDescriptor;
-import android.telecomm.CallServiceSelector.CallServiceSelectionResponse;
import com.google.android.collect.Sets;
import com.google.common.collect.Maps;
@@ -237,6 +236,23 @@
}
/**
+ * Persists the ordered-list of call-service descriptor as selected by the current selector and
+ * starts iterating through the corresponding call services continuing the attempt to place the
+ * call.
+ *
+ * @param descriptors The (ordered) list of call-service descriptor.
+ */
+ void processSelectedCallServices(List<CallServiceDescriptor> descriptors) {
+ Log.v(this, "processSelectedCallServices");
+ if (descriptors == null || descriptors.isEmpty()) {
+ attemptNextSelector();
+ } else if (mCallServiceDescriptorIterator == null) {
+ mCallServiceDescriptorIterator = descriptors.iterator();
+ attemptNextCallService();
+ }
+ }
+
+ /**
* Attempts to place the call using the next selector, no-op if no other selectors
* are available.
*/
@@ -249,15 +265,7 @@
if (mSelectorIterator.hasNext()) {
CallServiceSelectorWrapper selector = mSelectorIterator.next();
mCall.setCallServiceSelector(selector);
-
- CallServiceSelectionResponse responseCallback = new CallServiceSelectionResponse() {
- @Override
- public void setSelectedCallServices(List<CallServiceDescriptor> callServices) {
- processSelectedCallServiceDescriptors(callServices);
- }
- };
- selector.select(mCall, mCallServiceDescriptors, responseCallback,
- mNextSelectorCallback);
+ selector.select(mCall, mCallServiceDescriptors, mNextSelectorCallback);
} else {
Log.v(this, "attemptNextSelector, no more selectors, failing");
mCall.clearCallServiceSelector();
@@ -266,25 +274,6 @@
}
/**
- * Persists the ordered-list of call-service descriptor as selected by the current selector and
- * starts iterating through the corresponding call services continuing the attempt to place the
- * call.
- *
- * @selectedCallServiceDescriptors The (ordered) list of call-service descriptor.
- */
- private void processSelectedCallServiceDescriptors(
- List<CallServiceDescriptor> selectedCallServiceDescriptors) {
-
- Log.v(this, "processSelectedCallServiceDescriptors");
- if (selectedCallServiceDescriptors == null || selectedCallServiceDescriptors.isEmpty()) {
- attemptNextSelector();
- } else if (mCallServiceDescriptorIterator == null) {
- mCallServiceDescriptorIterator = selectedCallServiceDescriptors.iterator();
- attemptNextCallService();
- }
- }
-
- /**
* Attempts to place the call using the call service specified by the next call-service
* descriptor of mCallServiceDescriptorIterator. If there are no more call services to
* attempt, the process continues to the next call-service selector via
diff --git a/src/com/android/telecomm/OutgoingCallsManager.java b/src/com/android/telecomm/OutgoingCallsManager.java
index 1a955ce..def5211 100644
--- a/src/com/android/telecomm/OutgoingCallsManager.java
+++ b/src/com/android/telecomm/OutgoingCallsManager.java
@@ -16,10 +16,13 @@
package com.android.telecomm;
+import android.telecomm.CallServiceDescriptor;
+
import com.android.internal.telecomm.ICallServiceSelector;
import com.google.common.collect.Maps;
import java.util.Collection;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -141,6 +144,21 @@
}
/**
+ * Forwards the selected call service from the selector to the corresponding outgoing-call
+ * processor.
+ */
+ void processSelectedCallServices(Call call, List<CallServiceDescriptor> descriptors) {
+ Log.v(this, "processSelectedCallServices, call %s, descriptors: %s", call, descriptors);
+ OutgoingCallProcessor processor = mOutgoingCallProcessors.get(call);
+ if (processor == null) {
+ // Shouldn't happen, so log a wtf if it does.
+ Log.wtf(this, "Received unexpected setSelectedCallServices notification.");
+ } else {
+ processor.processSelectedCallServices(descriptors);
+ }
+ }
+
+ /**
* Aborts any ongoing attempts to connect the specified (outgoing) call.
*
* @param call The call to be aborted.
diff --git a/src/com/android/telecomm/Switchboard.java b/src/com/android/telecomm/Switchboard.java
index 5a23f88..77c3c16 100644
--- a/src/com/android/telecomm/Switchboard.java
+++ b/src/com/android/telecomm/Switchboard.java
@@ -107,7 +107,7 @@
mCallsManager = callsManager;
mOutgoingCallsManager = new OutgoingCallsManager(this);
mIncomingCallsManager = new IncomingCallsManager(this);
- mSelectorRepository = new CallServiceSelectorRepository(this);
+ mSelectorRepository = new CallServiceSelectorRepository(this, mOutgoingCallsManager);
mCallServiceRepository =
new CallServiceRepository(this, mOutgoingCallsManager, mIncomingCallsManager);
@@ -258,8 +258,7 @@
*/
private boolean isTicking() {
// TODO(gilad): return true every time at least one outgoing call is pending (i.e. waiting
- // to be connected by a call service) and also when at least one active call is switch-able
- // between call services, see {@link ICallServiceSelector#isSwitchable}.
+ // to be connected by a call service).
return false;
}