Make creating the Connection synchronous

Get rid of CreateConnectionResponse and have the ConnectionService
return the built connection instead.

Change-Id: Ibbf896e5b188b98eb386d6624d3a5d5cacf49922
This commit is contained in:
Evan Charlton
2014-07-20 22:06:28 -07:00
parent ca7a229eab
commit bf11f98deb
7 changed files with 318 additions and 164 deletions

View File

@@ -28586,7 +28586,11 @@ package android.telecomm {
method public final int getCallCapabilities();
method public final java.lang.String getCallerDisplayName();
method public final int getCallerDisplayNamePresentation();
method public static android.telecomm.Connection getCanceledConnection();
method public final java.util.List<android.telecomm.Connection> getChildConnections();
method public static android.telecomm.Connection getFailedConnection(int, java.lang.String);
method public final int getFailureCode();
method public final java.lang.String getFailureMessage();
method public final android.net.Uri getHandle();
method public final int getHandlePresentation();
method public final android.telecomm.Connection getParentConnection();
@@ -28615,9 +28619,13 @@ package android.telecomm {
method public final void setAudioModeIsVoip(boolean);
method public final void setCallCapabilities(int);
method public final void setCallerDisplayName(java.lang.String, int);
method public final void setCanceled();
method public final void setDialing();
method public final void setDisconnected(int, java.lang.String);
method public final void setFailed(int, java.lang.String);
method public final void setHandle(android.net.Uri, int);
method public final void setInitialized();
method public final void setInitializing();
method public final void setOnHold();
method public final void setParentConnection(android.telecomm.Connection);
method public final void setPostDialWait(java.lang.String);
@@ -28632,12 +28640,15 @@ package android.telecomm {
}
public final class Connection.State {
field public static final int ACTIVE = 3; // 0x3
field public static final int DIALING = 2; // 0x2
field public static final int DISCONNECTED = 5; // 0x5
field public static final int HOLDING = 4; // 0x4
field public static final int NEW = 0; // 0x0
field public static final int RINGING = 1; // 0x1
field public static final int ACTIVE = 4; // 0x4
field public static final int CANCELED = 8; // 0x8
field public static final int DIALING = 3; // 0x3
field public static final int DISCONNECTED = 6; // 0x6
field public static final int FAILED = 7; // 0x7
field public static final int HOLDING = 5; // 0x5
field public static final int INITIALIZING = 0; // 0x0
field public static final int NEW = 1; // 0x1
field public static final int RINGING = 2; // 0x2
}
public final class ConnectionRequest implements android.os.Parcelable {
@@ -28655,17 +28666,16 @@ package android.telecomm {
public abstract class ConnectionService extends android.app.Service {
ctor public ConnectionService();
method public final void createRemoteIncomingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.RemoteConnection>);
method public final void createRemoteOutgoingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.RemoteConnection>);
method public final android.telecomm.RemoteConnection createRemoteIncomingConnection(android.telecomm.ConnectionRequest);
method public final android.telecomm.RemoteConnection createRemoteOutgoingConnection(android.telecomm.ConnectionRequest);
method public final java.util.Collection<android.telecomm.Connection> getAllConnections();
method public final void lookupRemoteAccounts(android.net.Uri, android.telecomm.SimpleResponse<android.net.Uri, java.util.List<android.telecomm.PhoneAccountHandle>>);
method public final void maybeRespondToAccountLookup();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnectionAdded(android.telecomm.Connection);
method public void onConnectionRemoved(android.telecomm.Connection);
method public void onCreateConferenceConnection(java.lang.String, android.telecomm.Connection, android.telecomm.Response<java.lang.String, android.telecomm.Connection>);
method public void onCreateIncomingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.Connection>);
method public void onCreateOutgoingConnection(android.telecomm.ConnectionRequest, android.telecomm.ConnectionService.CreateConnectionResponse<android.telecomm.Connection>);
method public android.telecomm.Connection onCreateIncomingConnection(android.telecomm.ConnectionRequest);
method public android.telecomm.Connection onCreateOutgoingConnection(android.telecomm.ConnectionRequest);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecomm.ConnectionService";
}
@@ -28796,6 +28806,8 @@ package android.telecomm {
method public int getCallerDisplayNamePresentation();
method public int getDisconnectCause();
method public java.lang.String getDisconnectMessage();
method public int getFailureCode();
method public java.lang.String getFailureMessage();
method public android.net.Uri getHandle();
method public int getHandlePresentation();
method public int getState();
@@ -28812,19 +28824,20 @@ package android.telecomm {
method public void unhold();
}
public static abstract interface RemoteConnection.Listener {
method public abstract void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
method public abstract void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
method public abstract void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
method public abstract void onDestroyed(android.telecomm.RemoteConnection);
method public abstract void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
method public abstract void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
method public abstract void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
method public abstract void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
method public abstract void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent);
method public abstract void onStateChanged(android.telecomm.RemoteConnection, int);
method public abstract void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
method public abstract void onVideoStateChanged(android.telecomm.RemoteConnection, int);
public static abstract class RemoteConnection.Listener {
ctor public RemoteConnection.Listener();
method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
method public void onDestroyed(android.telecomm.RemoteConnection);
method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
method public void onStartActivityFromInCall(android.telecomm.RemoteConnection, android.app.PendingIntent);
method public void onStateChanged(android.telecomm.RemoteConnection, int);
method public void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
method public void onVideoStateChanged(android.telecomm.RemoteConnection, int);
}
public abstract interface Response {

View File

@@ -48,17 +48,22 @@ public abstract class Connection {
public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
public void onStartActivityFromInCall(Connection c, PendingIntent intent) {}
public void onFailed(Connection c, int code, String msg) {}
}
public final class State {
private State() {}
public static final int NEW = 0;
public static final int RINGING = 1;
public static final int DIALING = 2;
public static final int ACTIVE = 3;
public static final int HOLDING = 4;
public static final int DISCONNECTED = 5;
public static final int INITIALIZING = 0;
public static final int NEW = 1;
public static final int RINGING = 2;
public static final int DIALING = 3;
public static final int ACTIVE = 4;
public static final int HOLDING = 5;
public static final int DISCONNECTED = 6;
public static final int FAILED = 7;
public static final int CANCELED = 8;
}
private final Set<Listener> mListeners = new HashSet<>();
@@ -77,6 +82,9 @@ public abstract class Connection {
private boolean mAudioModeIsVoip;
private StatusHints mStatusHints;
private int mVideoState;
private int mFailureCode;
private String mFailureMessage;
private boolean mIsCanceled;
/**
* Create a new Connection.
@@ -196,6 +204,20 @@ public abstract class Connection {
return this;
}
/**
* @return The failure code ({@see DisconnectCause}) associated with this failed connection.
*/
public final int getFailureCode() {
return mFailureCode;
}
/**
* @return The reason for the connection failure. This will not be displayed to the user.
*/
public final String getFailureMessage() {
return mFailureMessage;
}
/**
* Inform this Connection that the state of its audio output has been changed externally.
*
@@ -226,6 +248,10 @@ public abstract class Connection {
return "HOLDING";
case State.DISCONNECTED:
return "DISCONNECTED";
case State.FAILED:
return "FAILED";
case State.CANCELED:
return "CANCELED";
default:
Log.wtf(Connection.class, "Unknown state %d", state);
return "UNKNOWN";
@@ -299,6 +325,33 @@ public abstract class Connection {
}
}
/**
* Cancel the {@link Connection}. Once this is called, the {@link Connection} will not be used,
* and no subsequent {@link Connection}s will be attempted.
*/
public final void setCanceled() {
Log.d(this, "setCanceled");
setState(State.CANCELED);
}
/**
* Move the {@link Connection} to the {@link State#FAILED} state, with the given code
* ({@see DisconnectCause}) and message. This message is not shown to the user, but is useful
* for logging and debugging purposes.
* <p>
* After calling this, the {@link Connection} will not be used.
*
* @param code The {@link android.telephony.DisconnectCause} indicating why the connection
* failed.
* @param message A message explaining why the {@link Connection} failed.
*/
public final void setFailed(int code, String message) {
Log.d(this, "setFailed (%d: %s)", code, message);
mFailureCode = code;
mFailureMessage = message;
setState(State.FAILED);
}
/**
* Set the video state for the connection.
* Valid values: {@link android.telecomm.VideoCallProfile#VIDEO_STATE_AUDIO_ONLY},
@@ -332,6 +385,20 @@ public abstract class Connection {
setState(State.RINGING);
}
/**
* Sets state to initializing (this Connection is not yet ready to be used).
*/
public final void setInitializing() {
setState(State.INITIALIZING);
}
/**
* Sets state to initialized (the Connection has been set up and is now ready to be used).
*/
public final void setInitialized() {
setState(State.NEW);
}
/**
* Sets state to dialing (e.g., dialing an outbound call).
*/
@@ -485,8 +552,8 @@ public abstract class Connection {
public void onSetAudioState(CallAudioState state) {}
/**
* Notifies this Connection of an internal state change. This method is called before the
* state is actually changed.
* Notifies this Connection of an internal state change. This method is called after the
* state is changed.
*
* @param state The new state, a {@link Connection.State} member.
*/
@@ -577,11 +644,50 @@ public abstract class Connection {
}
private void setState(int state) {
Log.d(this, "setState: %s", stateToString(state));
this.mState = state;
for (Listener l : mListeners) {
l.onStateChanged(this, state);
if (mState == State.FAILED || mState == State.CANCELED) {
Log.d(this, "Connection already %s; cannot transition out of this state.",
stateToString(mState));
return;
}
onSetState(state);
if (mState != state) {
Log.d(this, "setState: %s", stateToString(state));
mState = state;
for (Listener l : mListeners) {
l.onStateChanged(this, state);
}
onSetState(state);
}
}
/**
* Return a {@link Connection} which represents a failed connection attempt. The returned
* {@link Connection} will have {@link #getFailureCode()}, {@link #getFailureMessage()}, and
* {@link #getState()} set appropriately, but the {@link Connection} itself should not be used
* for anything.
*
* @param code The failure code ({@see DisconnectCause}).
* @param message A reason for why the connection failed (not intended to be shown to the user).
* @return A {@link Connection} which indicates failure.
*/
public static Connection getFailedConnection(final int code, final String message) {
return new Connection() {{
setFailed(code, message);
}};
}
private static final Connection CANCELED_CONNECTION = new Connection() {{
setCanceled();
}};
/**
* Return a {@link Connection} which represents a canceled a connection attempt. The returned
* {@link Connection} will have state {@link State#CANCELED}, and cannot be moved out of that
* state. This connection should not be used for anything, and no other {@link Connection}s
* should be attempted.
*
* @return A {@link Connection} which indicates that the underlying call should be canceled.
*/
public static Connection getCanceledConnection() {
return CANCELED_CONNECTION;
}
}

View File

@@ -20,6 +20,8 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ResultReceiver;
import android.telephony.DisconnectCause;
/**
* Simple data container encapsulating a request to some entity to
@@ -110,6 +112,7 @@ public final class ConnectionRequest implements Parcelable {
return mVideoState;
}
@Override
public String toString() {
return String.format("PhoneConnectionRequest %s %s",
mHandle == null

View File

@@ -28,7 +28,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.telephony.DisconnectCause;
import com.android.internal.os.SomeArgs;
import com.android.internal.telecomm.IConnectionService;
import com.android.internal.telecomm.IConnectionServiceAdapter;
@@ -132,7 +132,7 @@ public abstract class ConnectionService extends Service {
public void answer(String callId, int videoState) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = callId;
args.arg2 = videoState;
args.argi1 = videoState;
mHandler.obtainMessage(MSG_ANSWER, args).sendToTarget();
}
@@ -224,7 +224,7 @@ public abstract class ConnectionService extends Service {
SomeArgs args = (SomeArgs) msg.obj;
try {
String callId = (String) args.arg1;
int videoState = (int) args.arg2;
int videoState = args.argi1;
answer(callId, videoState);
} finally {
args.recycle();
@@ -425,48 +425,76 @@ public abstract class ConnectionService extends Service {
* incoming call. In either case, telecomm will cycle through a set of services and call
* createConnection util a connection service cancels the process or completes it successfully.
*/
private void createConnection(ConnectionRequest originalRequest, boolean isIncoming) {
Log.d(this, "call %s", originalRequest);
CreateConnectionResponse response = new CreateConnectionResponse<Connection>() {
@Override
public void onSuccess(ConnectionRequest request, Connection connection) {
Log.d(this, "adapter handleCreateConnectionSuccessful %s",
request.getCallId());
addConnection(request.getCallId(), connection);
mAdapter.handleCreateConnectionSuccessful(
request,
new ParcelableConnection(
request.getAccountHandle(),
connection.getState(),
connection.getCallCapabilities(),
connection.getHandle(),
connection.getHandlePresentation(),
connection.getCallerDisplayName(),
connection.getCallerDisplayNamePresentation(),
connection.getVideoCallProvider() == null ?
null : connection.getVideoCallProvider().getInterface(),
connection.getVideoState()));
}
private void createConnection(final ConnectionRequest request, boolean isIncoming) {
Log.d(this, "call %s", request);
@Override
public void onFailure(ConnectionRequest request, int code, String msg) {
// Tell telecomm to try a different service.
mAdapter.handleCreateConnectionFailed(request, code, msg);
}
final Connection createdConnection;
if (isIncoming) {
createdConnection = onCreateIncomingConnection(request);
} else {
createdConnection = onCreateOutgoingConnection(request);
}
@Override
public void onCancel(ConnectionRequest request) {
if (createdConnection != null) {
Log.d(this, "adapter handleCreateConnectionSuccessful %s",
request.getCallId());
if (createdConnection.getState() == Connection.State.INITIALIZING) {
// Wait for the connection to become initialized.
createdConnection.addConnectionListener(new Connection.Listener() {
@Override
public void onStateChanged(Connection c, int state) {
switch (state) {
case Connection.State.FAILED:
Log.d(this, "Connection (%s) failed (%d: %s)", request,
c.getFailureCode(), c.getFailureMessage());
mAdapter.handleCreateConnectionFailed(request, c.getFailureCode(),
c.getFailureMessage());
break;
case Connection.State.CANCELED:
Log.d(this, "Connection (%s) canceled", request);
mAdapter.handleCreateConnectionCancelled(request);
break;
case Connection.State.INITIALIZING:
Log.d(this, "State changed to INITIALIZING; ignoring");
return; // Don't want to stop listening on this state transition.
default:
Log.d(this, "Connection created in state %s",
Connection.stateToString(state));
connectionCreated(request, createdConnection);
break;
}
c.removeConnectionListener(this);
}
});
} else if (createdConnection.getState() == Connection.State.CANCELED) {
// Tell telecomm not to attempt any more services.
mAdapter.handleCreateConnectionCancelled(request);
} else {
connectionCreated(request, createdConnection);
}
};
if (isIncoming) {
onCreateIncomingConnection(originalRequest, response);
} else {
onCreateOutgoingConnection(originalRequest, response);
// Tell telecomm to try a different service.
mAdapter.handleCreateConnectionFailed(request, DisconnectCause.ERROR_UNSPECIFIED, null);
}
}
private void connectionCreated(ConnectionRequest request, Connection connection) {
addConnection(request.getCallId(), connection);
mAdapter.handleCreateConnectionSuccessful(
request,
new ParcelableConnection(
request.getAccountHandle(),
connection.getState(),
connection.getCallCapabilities(),
connection.getHandle(),
connection.getHandlePresentation(),
connection.getCallerDisplayName(),
connection.getCallerDisplayNamePresentation(),
connection.getVideoCallProvider() == null ?
null : connection.getVideoCallProvider().getInterface(),
connection.getVideoState()));
}
private void abort(String callId) {
Log.d(this, "abort %s", callId);
findConnectionForAction(callId, "abort").onAbort();
@@ -609,13 +637,6 @@ public abstract class ConnectionService extends Service {
});
}
public final void lookupRemoteAccounts(
Uri handle, SimpleResponse<Uri, List<PhoneAccountHandle>> response) {
mAccountLookupResponse = response;
mAccountLookupHandle = handle;
maybeRespondToAccountLookup();
}
public final void maybeRespondToAccountLookup() {
if (mAreAccountsInitialized && mAccountLookupResponse != null) {
mAccountLookupResponse.onResult(
@@ -627,16 +648,12 @@ public abstract class ConnectionService extends Service {
}
}
public final void createRemoteIncomingConnection(
ConnectionRequest request,
CreateConnectionResponse<RemoteConnection> response) {
mRemoteConnectionManager.createRemoteConnection(request, response, true);
public final RemoteConnection createRemoteIncomingConnection(ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(request, true);
}
public final void createRemoteOutgoingConnection(
ConnectionRequest request,
CreateConnectionResponse<RemoteConnection> response) {
mRemoteConnectionManager.createRemoteConnection(request, response, false);
public final RemoteConnection createRemoteOutgoingConnection(ConnectionRequest request) {
return mRemoteConnectionManager.createRemoteConnection(request, false);
}
/**
@@ -649,23 +666,22 @@ public abstract class ConnectionService extends Service {
/**
* Create a Connection given an incoming request. This is used to attach to existing incoming
* calls.
*
* @param request Details about the incoming call.
* @param callback A callback for providing the result.
*
* @return The {@link Connection} object to satisfy this call, or {@code null} to not handle
* the call.
*/
public void onCreateIncomingConnection(
ConnectionRequest request,
CreateConnectionResponse<Connection> callback) {}
public Connection onCreateIncomingConnection(ConnectionRequest request) { return null; }
/**
* Create a Connection given an outgoing request. This is used to initiate new outgoing calls.
* @param request Details about the outgoing call.
*
* @return The {@link Connection} object to satisfy this request,
* or null to not handle the call.
*
* @param request Details about the outgoing call.
* @param callback A callback for providing the result.
*/
public void onCreateOutgoingConnection(
ConnectionRequest request,
CreateConnectionResponse<Connection> callback) {}
public Connection onCreateOutgoingConnection(ConnectionRequest request) { return null; }
/**
* Returns a new or existing conference connection when the the user elects to convert the

View File

@@ -18,7 +18,6 @@ package android.telecomm;
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.telephony.DisconnectCause;
@@ -31,23 +30,23 @@ import java.util.Set;
* RemoteConnection object used by RemoteConnectionService.
*/
public final class RemoteConnection {
public interface Listener {
void onStateChanged(RemoteConnection connection, int state);
void onDisconnected(RemoteConnection connection, int cause, String message);
void onRequestingRingback(RemoteConnection connection, boolean ringback);
void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities);
void onPostDialWait(RemoteConnection connection, String remainingDigits);
void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip);
void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints);
void onHandleChanged(RemoteConnection connection, Uri handle, int presentation);
void onCallerDisplayNameChanged(
RemoteConnection connection, String callerDisplayName, int presentation);
void onVideoStateChanged(RemoteConnection connection, int videoState);
void onStartActivityFromInCall(RemoteConnection connection, PendingIntent intent);
void onDestroyed(RemoteConnection connection);
public static abstract class Listener {
public void onStateChanged(RemoteConnection connection, int state) {}
public void onDisconnected(RemoteConnection connection, int cause, String message) {}
public void onRequestingRingback(RemoteConnection connection, boolean ringback) {}
public void onCallCapabilitiesChanged(RemoteConnection connection, int callCapabilities) {}
public void onPostDialWait(RemoteConnection connection, String remainingDigits) {}
public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {}
public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {}
public void onCallerDisplayNameChanged(
RemoteConnection connection, String callerDisplayName, int presentation) {}
public void onVideoStateChanged(RemoteConnection connection, int videoState) {}
public void onStartActivityFromInCall(RemoteConnection connection, PendingIntent intent) {}
public void onDestroyed(RemoteConnection connection) {}
}
private final IConnectionService mConnectionService;
private IConnectionService mConnectionService;
private final String mConnectionId;
private final Set<Listener> mListeners = new HashSet<>();
@@ -64,15 +63,35 @@ public final class RemoteConnection {
private int mHandlePresentation;
private String mCallerDisplayName;
private int mCallerDisplayNamePresentation;
private int mFailureCode;
private String mFailureMessage;
/**
* @hide
*/
RemoteConnection(IConnectionService connectionService, String connectionId) {
RemoteConnection(IConnectionService connectionService, ConnectionRequest request,
boolean isIncoming) {
mConnectionService = connectionService;
mConnectionId = connectionId;
mConnectionId = request.getCallId();
mConnected = true;
mState = Connection.State.INITIALIZING;
}
/**
* Create a RemoteConnection which is used for failed connections. Note that using it for any
* "real" purpose will almost certainly fail. Callers should note the failure and act
* accordingly (moving on to another RemoteConnection, for example)
*
* @param failureCode
* @param failureMessage
*/
private RemoteConnection(int failureCode, String failureMessage) {
this(null, null, true);
mConnected = false;
mState = Connection.State.FAILED;
mFailureCode = failureCode;
mFailureMessage = failureMessage;
}
public void addListener(Listener listener) {
@@ -127,6 +146,14 @@ public final class RemoteConnection {
return mVideoState;
}
public int getFailureCode() {
return mFailureCode;
}
public String getFailureMessage() {
return mFailureMessage;
}
public void abort() {
try {
if (mConnected) {
@@ -354,4 +381,24 @@ public final class RemoteConnection {
l.onStartActivityFromInCall(this, intent);
}
}
/** @hide */
void setConnectionService(IConnectionService connectionService) {
mConnectionService = connectionService;
mConnectionService = null;
setState(Connection.State.NEW);
}
/**
* Create a RemoteConnection which is in the {@link Connection.State#FAILED} state. Attempting
* to use it for anything will almost certainly result in bad things happening. Do not do this.
*
* @return a failed {@link RemoteConnection}
*
* @hide
*
*/
public static RemoteConnection failure(int failureCode, String failureMessage) {
return new RemoteConnection(failureCode, failureMessage);
}
}

View File

@@ -46,17 +46,11 @@ public class RemoteConnectionManager {
List<PhoneAccountHandle> getAccounts(Uri handle) {
List<PhoneAccountHandle> accountHandles = new LinkedList<>();
Log.d(this, "Getting accountHandles: " + mRemoteConnectionServices.keySet());
for (RemoteConnectionService remoteService : mRemoteConnectionServices.values()) {
// TODO(santoscordon): Eventually this will be async.
accountHandles.addAll(remoteService.lookupAccounts(handle));
}
return accountHandles;
}
public void createRemoteConnection(
public RemoteConnection createRemoteConnection(
ConnectionRequest request,
ConnectionService.CreateConnectionResponse response,
boolean isIncoming) {
PhoneAccountHandle accountHandle = request.getAccountHandle();
if (accountHandle == null) {
@@ -67,9 +61,12 @@ public class RemoteConnectionManager {
if (!mRemoteConnectionServices.containsKey(componentName)) {
throw new UnsupportedOperationException("accountHandle not supported: "
+ componentName);
} else {
RemoteConnectionService remoteService = mRemoteConnectionServices.get(componentName);
remoteService.createRemoteConnection(request, response, isIncoming);
}
RemoteConnectionService remoteService = mRemoteConnectionServices.get(componentName);
if (remoteService != null) {
return remoteService.createRemoteConnection(request, isIncoming);
}
return null;
}
}

View File

@@ -69,8 +69,6 @@ final class RemoteConnectionService implements DeathRecipient {
private final ComponentName mComponentName;
private String mConnectionId;
private ConnectionRequest mPendingRequest;
private ConnectionService.CreateConnectionResponse<RemoteConnection> mPendingResponse;
// Remote connection services only support a single connection.
private RemoteConnection mConnection;
@@ -84,8 +82,6 @@ final class RemoteConnectionService implements DeathRecipient {
ConnectionRequest request = (ConnectionRequest) args.arg1;
if (isPendingConnection(request.getCallId())) {
ParcelableConnection parcel = (ParcelableConnection) args.arg2;
mConnection = new RemoteConnection(
mConnectionService, request.getCallId());
mConnection.setState(parcel.getState());
mConnection.setCallCapabilities(parcel.getCapabilities());
mConnection.setHandle(
@@ -94,9 +90,6 @@ final class RemoteConnectionService implements DeathRecipient {
parcel.getCallerDisplayName(),
parcel.getCallerDisplayNamePresentation());
// TODO: Do we need to support video providers for remote connections?
mPendingResponse.onSuccess(request, mConnection);
clearPendingInformation();
}
} finally {
args.recycle();
@@ -108,9 +101,8 @@ final class RemoteConnectionService implements DeathRecipient {
try {
ConnectionRequest request = (ConnectionRequest) args.arg1;
if (isPendingConnection(request.getCallId())) {
mPendingResponse.onFailure(request, args.argi1, (String) args.arg2);
mConnectionId = null;
clearPendingInformation();
// TODO: How do we propogate the failure codes?
destroyConnection();
}
} finally {
args.recycle();
@@ -120,9 +112,7 @@ final class RemoteConnectionService implements DeathRecipient {
case MSG_HANDLE_CREATE_CONNECTION_CANCELLED: {
ConnectionRequest request = (ConnectionRequest) msg.obj;
if (isPendingConnection(request.getCallId())) {
mPendingResponse.onCancel(request);
mConnectionId = null;
clearPendingInformation();
destroyConnection();
}
break;
}
@@ -431,11 +421,7 @@ final class RemoteConnectionService implements DeathRecipient {
release();
}
final void createRemoteConnection(
ConnectionRequest request,
ConnectionService.CreateConnectionResponse<RemoteConnection> response,
boolean isIncoming) {
final RemoteConnection createRemoteConnection(ConnectionRequest request, boolean isIncoming) {
if (mConnectionId == null) {
String id = UUID.randomUUID().toString();
ConnectionRequest newRequest = new ConnectionRequest(
@@ -445,29 +431,20 @@ final class RemoteConnectionService implements DeathRecipient {
request.getHandlePresentation(),
request.getExtras(),
request.getVideoState());
mConnection = new RemoteConnection(mConnectionService, request, isIncoming);
try {
mConnectionService.createConnection(newRequest, isIncoming);
mConnectionId = id;
mPendingResponse = response;
mPendingRequest = request;
} catch (RemoteException e) {
response.onFailure(request, DisconnectCause.ERROR_UNSPECIFIED, e.toString());
mConnection = RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED,
e.toString());
}
return mConnection;
} else {
response.onFailure(request, DisconnectCause.ERROR_UNSPECIFIED, null);
return RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED, null);
}
}
final List<PhoneAccountHandle> lookupAccounts(Uri handle) {
// TODO(santoscordon): Update this so that is actually calls into the RemoteConnection
// each time.
List<PhoneAccountHandle> accounts = new LinkedList<>();
accounts.add(new PhoneAccountHandle(
mComponentName,
null /* id */));
return accounts;
}
/**
* Releases the resources associated with this Remote connection service. Should be called when
* the remote service is no longer being used.
@@ -477,7 +454,7 @@ final class RemoteConnectionService implements DeathRecipient {
}
private boolean isPendingConnection(String id) {
return TextUtils.equals(mConnectionId, id) && mPendingResponse != null;
return TextUtils.equals(mConnectionId, id);
}
private boolean isCurrentConnection(Object obj) {
@@ -485,11 +462,6 @@ final class RemoteConnectionService implements DeathRecipient {
TextUtils.equals(mConnectionId, (String) obj);
}
private void clearPendingInformation() {
mPendingRequest = null;
mPendingResponse = null;
}
private void destroyConnection() {
mConnection.setDestroyed();
mConnection = null;