2014-06-17 19:08:45 -07:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
R* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package android.telecomm;
|
|
|
|
|
2014-07-18 14:49:18 -07:00
|
|
|
import android.app.PendingIntent;
|
2014-06-17 19:08:45 -07:00
|
|
|
import android.net.Uri;
|
2014-07-30 10:07:40 -07:00
|
|
|
import android.os.IBinder;
|
2014-07-21 01:28:28 -07:00
|
|
|
import android.os.IBinder.DeathRecipient;
|
2014-06-17 19:08:45 -07:00
|
|
|
import android.os.RemoteException;
|
|
|
|
import android.telephony.DisconnectCause;
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
import com.android.internal.telecomm.IConnectionService;
|
|
|
|
import com.android.internal.telecomm.IConnectionServiceAdapter;
|
2014-07-22 16:41:54 -07:00
|
|
|
import com.android.internal.telecomm.IVideoCallProvider;
|
2014-06-17 19:08:45 -07:00
|
|
|
import com.android.internal.telecomm.RemoteServiceCallback;
|
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
2014-07-28 18:15:48 -07:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
2014-06-17 19:08:45 -07:00
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remote connection service which other connection services can use to place calls on their behalf.
|
2014-06-30 15:15:23 -07:00
|
|
|
*
|
|
|
|
* @hide
|
2014-06-17 19:08:45 -07:00
|
|
|
*/
|
2014-07-30 10:07:40 -07:00
|
|
|
final class RemoteConnectionService {
|
2014-07-18 14:21:23 -07:00
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
private static final RemoteConnection NULL_CONNECTION = new RemoteConnection(null, null);
|
2014-06-17 19:08:45 -07:00
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
|
2014-07-18 14:21:23 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void handleCreateConnectionSuccessful(ConnectionRequest request,
|
|
|
|
ParcelableConnection parcel) {
|
|
|
|
RemoteConnection connection = findConnectionForAction(
|
|
|
|
request.getCallId(), "handleCreateConnectionSuccessful");
|
|
|
|
if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
|
|
|
|
mPendingConnections.remove(connection);
|
|
|
|
connection.setState(parcel.getState());
|
|
|
|
connection.setCallCapabilities(parcel.getCapabilities());
|
|
|
|
connection.setHandle(
|
|
|
|
parcel.getHandle(), parcel.getHandlePresentation());
|
|
|
|
connection.setCallerDisplayName(
|
|
|
|
parcel.getCallerDisplayName(),
|
|
|
|
parcel.getCallerDisplayNamePresentation());
|
|
|
|
// TODO: Do we need to support video providers for remote connections?
|
2014-07-18 14:21:23 -07:00
|
|
|
}
|
|
|
|
}
|
2014-07-18 14:49:18 -07:00
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void handleCreateConnectionFailed(ConnectionRequest request, int errorCode,
|
|
|
|
String errorMessage) {
|
|
|
|
// TODO: How do we propagate the failure codes?
|
|
|
|
findConnectionForAction(
|
|
|
|
request.getCallId(), "handleCreateConnectionFailed")
|
|
|
|
.setDestroyed();
|
2014-06-25 13:35:14 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-14 16:29:44 -07:00
|
|
|
public void handleCreateConnectionCancelled(ConnectionRequest request) {
|
2014-07-30 10:07:40 -07:00
|
|
|
findConnectionForAction(
|
|
|
|
request.getCallId(), "handleCreateConnectionCancelled")
|
|
|
|
.setDestroyed();
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setActive(String callId) {
|
|
|
|
findConnectionForAction(callId, "setActive")
|
|
|
|
.setState(Connection.State.ACTIVE);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setRinging(String callId) {
|
|
|
|
findConnectionForAction(callId, "setRinging")
|
|
|
|
.setState(Connection.State.RINGING);
|
2014-06-20 16:29:33 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setDialing(String callId) {
|
|
|
|
findConnectionForAction(callId, "setDialing")
|
|
|
|
.setState(Connection.State.DIALING);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setDisconnected(String callId, int disconnectCause,
|
|
|
|
String disconnectMessage) {
|
|
|
|
findConnectionForAction(callId, "setDisconnected")
|
|
|
|
.setDisconnected(disconnectCause, disconnectMessage);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setOnHold(String callId) {
|
|
|
|
findConnectionForAction(callId, "setOnHold")
|
|
|
|
.setState(Connection.State.HOLDING);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setRequestingRingback(String callId, boolean ringing) {
|
|
|
|
findConnectionForAction(callId, "setRequestingRingback")
|
|
|
|
.setRequestingRingback(ringing);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setCallCapabilities(String callId, int callCapabilities) {
|
|
|
|
findConnectionForAction("callId", "setCallCapabilities")
|
|
|
|
.setCallCapabilities(callCapabilities);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setIsConferenced(String callId, String conferenceCallId) {
|
2014-06-17 19:08:45 -07:00
|
|
|
// not supported for remote connections.
|
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void addConferenceCall(String callId) {
|
2014-06-17 19:08:45 -07:00
|
|
|
// not supported for remote connections.
|
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void removeCall(String callId) {
|
|
|
|
findConnectionForAction(callId, "removeCall")
|
|
|
|
.setDestroyed();
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void onPostDialWait(String callId, String remaining) {
|
|
|
|
findConnectionForAction(callId, "onPostDialWait")
|
|
|
|
.setPostDialWait(remaining);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
|
2014-07-30 10:07:40 -07:00
|
|
|
// Not supported from remote connection service.
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
2014-07-01 11:31:21 -07:00
|
|
|
|
2014-07-17 07:50:22 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setVideoCallProvider(String callId,
|
|
|
|
IVideoCallProvider videoCallProvider) {
|
|
|
|
// not supported for remote connections.
|
2014-07-18 14:21:23 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setVideoState(String callId, int videoState) {
|
|
|
|
findConnectionForAction(callId, "setVideoState")
|
|
|
|
.setVideoState(videoState);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setAudioModeIsVoip(String callId, boolean isVoip) {
|
|
|
|
findConnectionForAction(callId, "setAudioModeIsVoip")
|
|
|
|
.setAudioModeIsVoip(isVoip);
|
2014-07-17 07:50:22 -07:00
|
|
|
}
|
|
|
|
|
2014-07-01 11:31:21 -07:00
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setStatusHints(String callId, StatusHints statusHints) {
|
|
|
|
findConnectionForAction(callId, "setStatusHints")
|
|
|
|
.setStatusHints(statusHints);
|
2014-07-01 11:31:21 -07:00
|
|
|
}
|
2014-07-07 22:49:44 -07:00
|
|
|
|
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setHandle(String callId, Uri handle, int presentation) {
|
|
|
|
findConnectionForAction(callId, "setHandle")
|
|
|
|
.setHandle(handle, presentation);
|
2014-07-07 22:49:44 -07:00
|
|
|
}
|
2014-07-08 21:48:22 -07:00
|
|
|
|
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void setCallerDisplayName(String callId, String callerDisplayName,
|
|
|
|
int presentation) {
|
|
|
|
findConnectionForAction(callId, "setCallerDisplayName")
|
|
|
|
.setCallerDisplayName(callerDisplayName, presentation);
|
2014-07-11 14:50:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public void startActivityFromInCall(String callId, PendingIntent intent) {
|
|
|
|
findConnectionForAction(callId, "startActivityFromInCall")
|
|
|
|
.startActivityFromInCall(intent);
|
2014-07-08 21:48:22 -07:00
|
|
|
}
|
2014-07-18 14:49:18 -07:00
|
|
|
|
|
|
|
@Override
|
2014-07-30 10:07:40 -07:00
|
|
|
public IBinder asBinder() {
|
|
|
|
throw new UnsupportedOperationException();
|
2014-07-18 14:49:18 -07:00
|
|
|
}
|
2014-07-28 18:15:48 -07:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public final void setConferenceableConnections(
|
|
|
|
String callId, List<String> conferenceableConnectionIds) {
|
|
|
|
|
|
|
|
// TODO: When we support more than 1 remote connection, this should
|
|
|
|
// loop through the incoming list of connection IDs and acquire the list
|
|
|
|
// of remote connections which correspond to the IDs. That list should
|
|
|
|
// be set onto the remote connections.
|
|
|
|
findConnectionForAction(callId, "setConferenceableConnections")
|
|
|
|
.setConferenceableConnections(Collections.<RemoteConnection>emptyList());
|
|
|
|
}
|
2014-06-17 19:08:45 -07:00
|
|
|
};
|
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
private final ConnectionServiceAdapterServant mServant =
|
|
|
|
new ConnectionServiceAdapterServant(mServantDelegate);
|
|
|
|
|
|
|
|
private final DeathRecipient mDeathRecipient = new DeathRecipient() {
|
|
|
|
@Override
|
|
|
|
public void binderDied() {
|
|
|
|
for (RemoteConnection c : mConnectionById.values()) {
|
|
|
|
c.setDestroyed();
|
|
|
|
}
|
|
|
|
mConnectionById.clear();
|
|
|
|
mPendingConnections.clear();
|
|
|
|
mConnectionService.asBinder().unlinkToDeath(mDeathRecipient, 0);
|
|
|
|
}
|
|
|
|
};
|
2014-06-17 19:08:45 -07:00
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
private final IConnectionService mConnectionService;
|
|
|
|
private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
|
|
|
|
private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
|
|
|
|
|
|
|
|
RemoteConnectionService(IConnectionService connectionService) throws RemoteException {
|
|
|
|
mConnectionService = connectionService;
|
|
|
|
mConnectionService.addConnectionServiceAdapter(mServant.getStub());
|
|
|
|
mConnectionService.asBinder().linkToDeath(mDeathRecipient, 0);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2014-07-04 17:21:07 -07:00
|
|
|
return "[RemoteCS - " + mConnectionService.asBinder().toString() + "]";
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-25 15:14:01 -07:00
|
|
|
final RemoteConnection createRemoteConnection(
|
|
|
|
PhoneAccountHandle connectionManagerPhoneAccount,
|
|
|
|
ConnectionRequest request,
|
|
|
|
boolean isIncoming) {
|
2014-07-30 10:07:40 -07:00
|
|
|
ConnectionRequest newRequest = new ConnectionRequest(
|
|
|
|
request.getAccountHandle(),
|
|
|
|
UUID.randomUUID().toString(),
|
|
|
|
request.getHandle(),
|
|
|
|
request.getHandlePresentation(),
|
|
|
|
request.getExtras(),
|
|
|
|
request.getVideoState());
|
|
|
|
try {
|
|
|
|
mConnectionService.createConnection(
|
|
|
|
connectionManagerPhoneAccount,
|
|
|
|
newRequest,
|
|
|
|
isIncoming);
|
|
|
|
RemoteConnection connection =
|
|
|
|
new RemoteConnection(mConnectionService, request);
|
|
|
|
mPendingConnections.add(connection);
|
|
|
|
mConnectionById.put(newRequest.getCallId(), connection);
|
|
|
|
return connection;
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
return RemoteConnection.failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString());
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-30 10:07:40 -07:00
|
|
|
private RemoteConnection findConnectionForAction(String callId, String action) {
|
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
return mConnectionById.get(callId);
|
|
|
|
}
|
|
|
|
Log.w(this, "%s - Cannot find Connection %s", action, callId);
|
|
|
|
return NULL_CONNECTION;
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
}
|