Connection creation and service wiring for WiFi call managers (2/3)
Bug: 16469413
Change-Id: Id6d495c20aa57ffc961336d49693c1a7f91d4cb3
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index 4238d61..c791932 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -29,6 +29,8 @@
import android.telecomm.ConnectionService;
import android.telecomm.GatewayInfo;
import android.telecomm.ParcelableConnection;
+import android.telecomm.PhoneAccount;
+import android.telecomm.PhoneAccountHandle;
import android.telecomm.StatusHints;
import android.telephony.DisconnectCause;
@@ -39,8 +41,10 @@
import com.android.internal.telecomm.RemoteServiceCallback;
import com.google.common.base.Preconditions;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -534,11 +538,18 @@
*
* @param componentName The component name of the service with which to bind.
* @param connectionServiceRepository Connection service repository.
+ * @param phoneAccountRegistrar Phone account registrar
*/
ConnectionServiceWrapper(
- ComponentName componentName, ConnectionServiceRepository connectionServiceRepository) {
+ ComponentName componentName,
+ ConnectionServiceRepository connectionServiceRepository,
+ PhoneAccountRegistrar phoneAccountRegistrar) {
super(ConnectionService.SERVICE_INTERFACE, componentName);
mConnectionServiceRepository = connectionServiceRepository;
+ phoneAccountRegistrar.addListener(new PhoneAccountRegistrar.Listener() {
+ // TODO -- Upon changes to PhoneAccountRegistrar, need to re-wire connections
+ // To do this, we must proxy remote ConnectionService objects
+ });
}
/** See {@link IConnectionService#addConnectionServiceAdapter}. */
@@ -575,16 +586,18 @@
NewOutgoingCallIntentBroadcaster.EXTRA_GATEWAY_ORIGINAL_URI,
gatewayInfo.getOriginalHandle());
}
- ConnectionRequest request = new ConnectionRequest(
- call.getPhoneAccount(),
- callId,
- call.getHandle(),
- call.getHandlePresentation(),
- extras,
- call.getVideoState());
try {
- mServiceInterface.createConnection(request, call.isIncoming());
+ mServiceInterface.createConnection(
+ call.getConnectionManagerPhoneAccount(),
+ new ConnectionRequest(
+ call.getTargetPhoneAccount(),
+ callId,
+ call.getHandle(),
+ call.getHandlePresentation(),
+ extras,
+ call.getVideoState()),
+ call.isIncoming());
} catch (RemoteException e) {
Log.e(this, e, "Failure to createConnection -- %s", getComponentName());
mPendingResponses.remove(callId).handleCreateConnectionFailed(
@@ -665,7 +678,7 @@
}
}
- /** @see ConnectionService#answer(String) */
+ /** @see ConnectionService#answer(String,int) */
void answer(Call call, int videoState) {
if (isServiceValid("answer")) {
try {
@@ -842,43 +855,86 @@
}
private void queryRemoteConnectionServices(final RemoteServiceCallback callback) {
- final List<IBinder> connectionServices = new ArrayList<>();
- final List<ComponentName> components = new ArrayList<>();
- final List<ConnectionServiceWrapper> servicesAttempted = new ArrayList<>();
- final Collection<ConnectionServiceWrapper> services =
- mConnectionServiceRepository.lookupServices();
+ PhoneAccountRegistrar registrar = TelecommApp.getInstance().getPhoneAccountRegistrar();
- Log.v(this, "queryRemoteConnectionServices, services: " + services.size());
+ // Only give remote connection services to this connection service if it is listed as
+ // the connection manager.
+ PhoneAccountHandle simCallManager = registrar.getSimCallManager();
+ if (simCallManager == null ||
+ !simCallManager.getComponentName().equals(getComponentName())) {
+ noRemoteServices(callback);
+ return;
+ }
- for (ConnectionServiceWrapper cs : services) {
- if (cs != this) {
- final ConnectionServiceWrapper currentConnectionService = cs;
- cs.mBinder.bind(new BindCallback() {
- @Override
- public void onSuccess() {
- Log.d(this, "Adding ***** %s", currentConnectionService.getComponentName());
- connectionServices.add(
- currentConnectionService.mServiceInterface.asBinder());
- components.add(currentConnectionService.getComponentName());
- maybeComplete();
- }
-
- @Override
- public void onFailure() {
- maybeComplete();
- }
-
- private void maybeComplete() {
- servicesAttempted.add(currentConnectionService);
- if (servicesAttempted.size() == services.size() - 1) {
- try {
- callback.onResult(components, connectionServices);
- } catch (RemoteException ignored) {
- }
- }
- }
- });
+ // Make a list of ConnectionServices that are listed as being associated with SIM accounts
+ final Set<ConnectionServiceWrapper> simServices = new HashSet<>();
+ for (PhoneAccountHandle handle : registrar.getEnabledPhoneAccounts()) {
+ PhoneAccount account = registrar.getPhoneAccount(handle);
+ if ((account.getCapabilities() & PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION) != 0) {
+ ConnectionServiceWrapper service =
+ mConnectionServiceRepository.getService(handle.getComponentName());
+ if (service != null) {
+ simServices.add(service);
+ }
}
}
+
+ final List<ComponentName> simServiceComponentNames = new ArrayList<>();
+ final List<IBinder> simServiceBinders = new ArrayList<>();
+
+ Log.v(this, "queryRemoteConnectionServices, simServices = %s", simServices);
+
+ for (ConnectionServiceWrapper simService : simServices) {
+ if (simService == this) {
+ // Only happens in the unlikely case that a SIM service is also a SIM call manager
+ continue;
+ }
+
+ final ConnectionServiceWrapper currentSimService = simService;
+
+ currentSimService.mBinder.bind(new BindCallback() {
+ @Override
+ public void onSuccess() {
+ Log.d(this, "Adding simService %s", currentSimService.getComponentName());
+ simServiceComponentNames.add(currentSimService.getComponentName());
+ simServiceBinders.add(currentSimService.mServiceInterface.asBinder());
+ maybeComplete();
+ }
+
+ @Override
+ public void onFailure() {
+ Log.d(this, "Failed simService %s", currentSimService.getComponentName());
+ // We know maybeComplete() will always be a no-op from now on, so go ahead and
+ // signal failure of the entire request
+ noRemoteServices(callback);
+ }
+
+ private void maybeComplete() {
+ if (simServiceComponentNames.size() == simServices.size()) {
+ setRemoteServices(callback, simServiceComponentNames, simServiceBinders);
+ }
+ }
+ });
+ }
+ }
+
+ private void setRemoteServices(
+ RemoteServiceCallback callback,
+ List<ComponentName> componentNames,
+ List<IBinder> binders) {
+ try {
+ callback.onResult(componentNames, binders);
+ } catch (RemoteException e) {
+ Log.e(this, e, "Contacting ConnectionService %s",
+ ConnectionServiceWrapper.this.getComponentName());
+ }
+ }
+
+ private void noRemoteServices(RemoteServiceCallback callback) {
+ try {
+ callback.onResult(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+ } catch (RemoteException e) {
+ Log.e(this, e, "Contacting ConnectionService %s", this.getComponentName());
+ }
}
}