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
|
2014-08-07 19:46:01 -07:00
|
|
|
* limitations under the License.
|
2014-06-17 19:08:45 -07:00
|
|
|
*/
|
|
|
|
|
2014-09-12 22:16:17 -07:00
|
|
|
package android.telecom;
|
2014-06-17 19:08:45 -07:00
|
|
|
|
|
|
|
import android.net.Uri;
|
2015-05-27 17:21:45 -07:00
|
|
|
import android.os.Bundle;
|
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;
|
|
|
|
|
2014-09-12 22:16:17 -07:00
|
|
|
import com.android.internal.telecom.IConnectionService;
|
|
|
|
import com.android.internal.telecom.IConnectionServiceAdapter;
|
|
|
|
import com.android.internal.telecom.IVideoProvider;
|
|
|
|
import com.android.internal.telecom.RemoteServiceCallback;
|
2014-06-17 19:08:45 -07:00
|
|
|
|
2014-08-23 20:34:57 -07:00
|
|
|
import java.util.ArrayList;
|
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.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-10-30 14:27:48 -07:00
|
|
|
// Note: Casting null to avoid ambiguous constructor reference.
|
2014-08-23 20:34:57 -07:00
|
|
|
private static final RemoteConnection NULL_CONNECTION =
|
2014-10-30 14:27:48 -07:00
|
|
|
new RemoteConnection("NULL", null, (ConnectionRequest) null);
|
2014-08-23 20:34:57 -07:00
|
|
|
|
|
|
|
private static final RemoteConference NULL_CONFERENCE =
|
|
|
|
new RemoteConference("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-08-18 09:23:25 -07:00
|
|
|
public void handleCreateConnectionComplete(
|
2014-08-07 19:46:01 -07:00
|
|
|
String id,
|
|
|
|
ConnectionRequest request,
|
2014-07-30 10:07:40 -07:00
|
|
|
ParcelableConnection parcel) {
|
2014-08-07 19:46:01 -07:00
|
|
|
RemoteConnection connection =
|
|
|
|
findConnectionForAction(id, "handleCreateConnectionSuccessful");
|
2014-07-30 10:07:40 -07:00
|
|
|
if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
|
|
|
|
mPendingConnections.remove(connection);
|
2014-08-18 09:23:25 -07:00
|
|
|
// Unconditionally initialize the connection ...
|
2014-11-12 13:41:16 -08:00
|
|
|
connection.setConnectionCapabilities(parcel.getConnectionCapabilities());
|
2016-03-22 09:02:47 -07:00
|
|
|
connection.setConnectionProperties(parcel.getConnectionProperties());
|
2015-01-31 20:17:35 -08:00
|
|
|
if (parcel.getHandle() != null
|
|
|
|
|| parcel.getState() != Connection.STATE_DISCONNECTED) {
|
|
|
|
connection.setAddress(parcel.getHandle(), parcel.getHandlePresentation());
|
|
|
|
}
|
|
|
|
if (parcel.getCallerDisplayName() != null
|
|
|
|
|| parcel.getState() != Connection.STATE_DISCONNECTED) {
|
|
|
|
connection.setCallerDisplayName(
|
|
|
|
parcel.getCallerDisplayName(),
|
|
|
|
parcel.getCallerDisplayNamePresentation());
|
|
|
|
}
|
2014-09-09 21:49:14 -07:00
|
|
|
// Set state after handle so that the client can identify the connection.
|
2014-09-20 18:23:05 -07:00
|
|
|
if (parcel.getState() == Connection.STATE_DISCONNECTED) {
|
|
|
|
connection.setDisconnected(parcel.getDisconnectCause());
|
|
|
|
} else {
|
|
|
|
connection.setState(parcel.getState());
|
|
|
|
}
|
2014-08-23 20:34:57 -07:00
|
|
|
List<RemoteConnection> conferenceable = new ArrayList<>();
|
|
|
|
for (String confId : parcel.getConferenceableConnectionIds()) {
|
|
|
|
if (mConnectionById.containsKey(confId)) {
|
|
|
|
conferenceable.add(mConnectionById.get(confId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
connection.setConferenceableConnections(conferenceable);
|
2014-08-20 09:36:40 -07:00
|
|
|
connection.setVideoState(parcel.getVideoState());
|
2014-08-18 09:23:25 -07:00
|
|
|
if (connection.getState() == Connection.STATE_DISCONNECTED) {
|
|
|
|
// ... then, if it was created in a disconnected state, that indicates
|
|
|
|
// failure on the providing end, so immediately mark it destroyed
|
|
|
|
connection.setDestroyed();
|
|
|
|
}
|
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 setActive(String callId) {
|
2014-08-23 20:34:57 -07:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
findConnectionForAction(callId, "setActive")
|
|
|
|
.setState(Connection.STATE_ACTIVE);
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(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")
|
2014-08-07 19:46:01 -07:00
|
|
|
.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")
|
2014-08-07 19:46:01 -07:00
|
|
|
.setState(Connection.STATE_DIALING);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-09-11 17:33:16 -07:00
|
|
|
public void setDisconnected(String callId, DisconnectCause disconnectCause) {
|
2014-08-23 20:34:57 -07:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
findConnectionForAction(callId, "setDisconnected")
|
2014-09-11 17:33:16 -07:00
|
|
|
.setDisconnected(disconnectCause);
|
2014-08-23 20:34:57 -07:00
|
|
|
} else {
|
|
|
|
findConferenceForAction(callId, "setDisconnected")
|
2014-09-11 17:33:16 -07:00
|
|
|
.setDisconnected(disconnectCause);
|
2014-08-23 20:34:57 -07:00
|
|
|
}
|
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) {
|
2014-08-23 20:34:57 -07:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
findConnectionForAction(callId, "setOnHold")
|
|
|
|
.setState(Connection.STATE_HOLDING);
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(callId, "setOnHold")
|
|
|
|
.setState(Connection.STATE_HOLDING);
|
|
|
|
}
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-09-08 15:34:24 -07:00
|
|
|
public void setRingbackRequested(String callId, boolean ringing) {
|
|
|
|
findConnectionForAction(callId, "setRingbackRequested")
|
|
|
|
.setRingbackRequested(ringing);
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-11-12 13:41:16 -08:00
|
|
|
public void setConnectionCapabilities(String callId, int connectionCapabilities) {
|
2014-08-23 20:34:57 -07:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
2014-11-12 13:41:16 -08:00
|
|
|
findConnectionForAction(callId, "setConnectionCapabilities")
|
|
|
|
.setConnectionCapabilities(connectionCapabilities);
|
2014-08-23 20:34:57 -07:00
|
|
|
} else {
|
2014-11-12 13:41:16 -08:00
|
|
|
findConferenceForAction(callId, "setConnectionCapabilities")
|
|
|
|
.setConnectionCapabilities(connectionCapabilities);
|
2014-08-23 20:34:57 -07:00
|
|
|
}
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2016-03-22 09:02:47 -07:00
|
|
|
@Override
|
|
|
|
public void setConnectionProperties(String callId, int connectionProperties) {
|
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
findConnectionForAction(callId, "setConnectionProperties")
|
|
|
|
.setConnectionProperties(connectionProperties);
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(callId, "setConnectionProperties")
|
|
|
|
.setConnectionProperties(connectionProperties);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-08-23 20:34:57 -07:00
|
|
|
// Note: callId should not be null; conferenceCallId may be null
|
|
|
|
RemoteConnection connection =
|
|
|
|
findConnectionForAction(callId, "setIsConferenced");
|
|
|
|
if (connection != NULL_CONNECTION) {
|
|
|
|
if (conferenceCallId == null) {
|
|
|
|
// 'connection' is being split from its conference
|
|
|
|
if (connection.getConference() != null) {
|
|
|
|
connection.getConference().removeConnection(connection);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
RemoteConference conference =
|
|
|
|
findConferenceForAction(conferenceCallId, "setIsConferenced");
|
|
|
|
if (conference != NULL_CONFERENCE) {
|
|
|
|
conference.addConnection(connection);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
2015-04-24 15:25:29 -07:00
|
|
|
@Override
|
|
|
|
public void setConferenceMergeFailed(String callId) {
|
|
|
|
// Nothing to do here.
|
|
|
|
// The event has already been handled and there is no state to update
|
|
|
|
// in the underlying connection or conference objects
|
|
|
|
}
|
|
|
|
|
2014-07-04 17:21:07 -07:00
|
|
|
@Override
|
2014-08-23 20:34:57 -07:00
|
|
|
public void addConferenceCall(
|
|
|
|
final String callId,
|
|
|
|
ParcelableConference parcel) {
|
|
|
|
RemoteConference conference = new RemoteConference(callId,
|
|
|
|
mOutgoingConnectionServiceRpc);
|
|
|
|
|
|
|
|
for (String id : parcel.getConnectionIds()) {
|
|
|
|
RemoteConnection c = mConnectionById.get(id);
|
|
|
|
if (c != null) {
|
|
|
|
conference.addConnection(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conference.getConnections().size() == 0) {
|
|
|
|
// A conference was created, but none of its connections are ones that have been
|
|
|
|
// created by, and therefore being tracked by, this remote connection service. It
|
|
|
|
// is of no interest to us.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
conference.setState(parcel.getState());
|
2014-11-12 13:41:16 -08:00
|
|
|
conference.setConnectionCapabilities(parcel.getConnectionCapabilities());
|
2014-08-23 20:34:57 -07:00
|
|
|
mConferenceById.put(callId, conference);
|
2014-09-08 15:34:24 -07:00
|
|
|
conference.registerCallback(new RemoteConference.Callback() {
|
2014-08-23 20:34:57 -07:00
|
|
|
@Override
|
|
|
|
public void onDestroyed(RemoteConference c) {
|
|
|
|
mConferenceById.remove(callId);
|
|
|
|
maybeDisconnectAdapter();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
mOurConnectionServiceImpl.addRemoteConference(conference);
|
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 removeCall(String callId) {
|
2014-08-23 20:34:57 -07:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
|
|
|
findConnectionForAction(callId, "removeCall")
|
|
|
|
.setDestroyed();
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(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
|
|
|
}
|
|
|
|
|
2014-12-15 16:12:50 -08:00
|
|
|
@Override
|
|
|
|
public void onPostDialChar(String callId, char nextChar) {
|
|
|
|
findConnectionForAction(callId, "onPostDialChar")
|
|
|
|
.onPostDialChar(nextChar);
|
|
|
|
}
|
|
|
|
|
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-08-07 19:46:01 -07:00
|
|
|
public void setVideoProvider(String callId, IVideoProvider videoProvider) {
|
2015-01-28 16:54:09 -08:00
|
|
|
RemoteConnection.VideoProvider remoteVideoProvider = null;
|
|
|
|
if (videoProvider != null) {
|
|
|
|
remoteVideoProvider = new RemoteConnection.VideoProvider(videoProvider);
|
|
|
|
}
|
2014-08-20 09:36:40 -07:00
|
|
|
findConnectionForAction(callId, "setVideoProvider")
|
2015-01-28 16:54:09 -08:00
|
|
|
.setVideoProvider(remoteVideoProvider);
|
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
|
2014-09-08 15:34:24 -07:00
|
|
|
public void setIsVoipAudioMode(String callId, boolean isVoip) {
|
|
|
|
findConnectionForAction(callId, "setIsVoipAudioMode")
|
|
|
|
.setIsVoipAudioMode(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-09-08 15:34:24 -07:00
|
|
|
public void setAddress(String callId, Uri address, int presentation) {
|
|
|
|
findConnectionForAction(callId, "setAddress")
|
|
|
|
.setAddress(address, 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
|
|
|
}
|
|
|
|
|
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) {
|
2014-08-23 20:34:57 -07:00
|
|
|
List<RemoteConnection> conferenceable = new ArrayList<>();
|
|
|
|
for (String id : conferenceableConnectionIds) {
|
|
|
|
if (mConnectionById.containsKey(id)) {
|
|
|
|
conferenceable.add(mConnectionById.get(id));
|
|
|
|
}
|
|
|
|
}
|
2014-07-28 18:15:48 -07:00
|
|
|
|
2014-09-30 09:17:03 -07:00
|
|
|
if (hasConnection(callId)) {
|
|
|
|
findConnectionForAction(callId, "setConferenceableConnections")
|
|
|
|
.setConferenceableConnections(conferenceable);
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(callId, "setConferenceableConnections")
|
|
|
|
.setConferenceableConnections(conferenceable);
|
|
|
|
}
|
2014-07-28 18:15:48 -07:00
|
|
|
}
|
2014-10-30 14:27:48 -07:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addExistingConnection(String callId, ParcelableConnection connection) {
|
|
|
|
// TODO: add contents of this method
|
|
|
|
RemoteConnection remoteConnction = new RemoteConnection(callId,
|
|
|
|
mOutgoingConnectionServiceRpc, connection);
|
|
|
|
|
|
|
|
mOurConnectionServiceImpl.addRemoteExistingConnection(remoteConnction);
|
|
|
|
}
|
2015-05-27 17:21:45 -07:00
|
|
|
|
|
|
|
@Override
|
Expand call/connection extras API.
Currently, connection extras are propagated up to Telecom as an
entire bundle. This is not ideal, as any time a change is made to
the extras, the bundle needs to be fetched, changed, and then re-set on
the connection, where it is parceled to Telecom as a whole.
Using how extras on an Intent as inspiration, this CL adds separate
putExtras, putExtra, and removeExtra methods to allow manipulation of
the extras bundle without operating on it in its entirety.
This Cl also adds support for Calls modifying the extras bundle, with
changes propagated back down to ConnectionServices.
Bug: 27458894
Change-Id: I152340a3bca2dc03f170b06b172a6823410fb961
2016-03-23 16:06:34 -07:00
|
|
|
public void putExtras(String callId, Bundle extras) {
|
|
|
|
if (hasConnection(callId)) {
|
|
|
|
findConnectionForAction(callId, "putExtras").putExtras(extras);
|
|
|
|
} else {
|
|
|
|
findConferenceForAction(callId, "putExtras").putExtras(extras);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void removeExtras(String callId, List<String> keys) {
|
|
|
|
if (hasConnection(callId)) {
|
|
|
|
findConnectionForAction(callId, "removeExtra").removeExtras(keys);
|
2015-05-27 17:21:45 -07:00
|
|
|
} else {
|
Expand call/connection extras API.
Currently, connection extras are propagated up to Telecom as an
entire bundle. This is not ideal, as any time a change is made to
the extras, the bundle needs to be fetched, changed, and then re-set on
the connection, where it is parceled to Telecom as a whole.
Using how extras on an Intent as inspiration, this CL adds separate
putExtras, putExtra, and removeExtra methods to allow manipulation of
the extras bundle without operating on it in its entirety.
This Cl also adds support for Calls modifying the extras bundle, with
changes propagated back down to ConnectionServices.
Bug: 27458894
Change-Id: I152340a3bca2dc03f170b06b172a6823410fb961
2016-03-23 16:06:34 -07:00
|
|
|
findConferenceForAction(callId, "removeExtra").removeExtras(keys);
|
2015-05-27 17:21:45 -07:00
|
|
|
}
|
|
|
|
}
|
2016-02-16 14:36:20 -08:00
|
|
|
|
|
|
|
@Override
|
2016-03-14 15:18:07 -07:00
|
|
|
public void onConnectionEvent(String callId, String event, Bundle extras) {
|
2016-02-16 14:36:20 -08:00
|
|
|
if (mConnectionById.containsKey(callId)) {
|
2016-03-14 15:18:07 -07:00
|
|
|
findConnectionForAction(callId, "onConnectionEvent").onConnectionEvent(event,
|
|
|
|
extras);
|
2016-02-16 14:36:20 -08:00
|
|
|
}
|
|
|
|
}
|
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();
|
|
|
|
}
|
2014-08-23 20:34:57 -07:00
|
|
|
for (RemoteConference c : mConferenceById.values()) {
|
|
|
|
c.setDestroyed();
|
|
|
|
}
|
2014-07-30 10:07:40 -07:00
|
|
|
mConnectionById.clear();
|
2014-08-23 20:34:57 -07:00
|
|
|
mConferenceById.clear();
|
2014-07-30 10:07:40 -07:00
|
|
|
mPendingConnections.clear();
|
2014-08-23 20:34:57 -07:00
|
|
|
mOutgoingConnectionServiceRpc.asBinder().unlinkToDeath(mDeathRecipient, 0);
|
2014-07-30 10:07:40 -07:00
|
|
|
}
|
|
|
|
};
|
2014-06-17 19:08:45 -07:00
|
|
|
|
2014-08-23 20:34:57 -07:00
|
|
|
private final IConnectionService mOutgoingConnectionServiceRpc;
|
|
|
|
private final ConnectionService mOurConnectionServiceImpl;
|
2014-07-30 10:07:40 -07:00
|
|
|
private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
|
2014-08-23 20:34:57 -07:00
|
|
|
private final Map<String, RemoteConference> mConferenceById = new HashMap<>();
|
2014-07-30 10:07:40 -07:00
|
|
|
private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
|
|
|
|
|
2014-08-23 20:34:57 -07:00
|
|
|
RemoteConnectionService(
|
|
|
|
IConnectionService outgoingConnectionServiceRpc,
|
|
|
|
ConnectionService ourConnectionServiceImpl) throws RemoteException {
|
|
|
|
mOutgoingConnectionServiceRpc = outgoingConnectionServiceRpc;
|
|
|
|
mOutgoingConnectionServiceRpc.asBinder().linkToDeath(mDeathRecipient, 0);
|
|
|
|
mOurConnectionServiceImpl = ourConnectionServiceImpl;
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2014-08-23 20:34:57 -07:00
|
|
|
return "[RemoteCS - " + mOutgoingConnectionServiceRpc.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-08-07 19:46:01 -07:00
|
|
|
final String id = UUID.randomUUID().toString();
|
2014-08-08 17:06:11 -07:00
|
|
|
final ConnectionRequest newRequest = new ConnectionRequest(
|
2014-07-30 10:07:40 -07:00
|
|
|
request.getAccountHandle(),
|
2014-09-05 16:38:49 -07:00
|
|
|
request.getAddress(),
|
2014-07-30 10:07:40 -07:00
|
|
|
request.getExtras(),
|
|
|
|
request.getVideoState());
|
|
|
|
try {
|
2014-08-08 17:06:11 -07:00
|
|
|
if (mConnectionById.isEmpty()) {
|
2014-08-23 20:34:57 -07:00
|
|
|
mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub());
|
2014-08-08 17:06:11 -07:00
|
|
|
}
|
|
|
|
RemoteConnection connection =
|
2014-08-23 20:34:57 -07:00
|
|
|
new RemoteConnection(id, mOutgoingConnectionServiceRpc, newRequest);
|
2014-08-08 17:06:11 -07:00
|
|
|
mPendingConnections.add(connection);
|
2014-08-07 19:46:01 -07:00
|
|
|
mConnectionById.put(id, connection);
|
2014-08-23 20:34:57 -07:00
|
|
|
mOutgoingConnectionServiceRpc.createConnection(
|
2014-07-30 10:07:40 -07:00
|
|
|
connectionManagerPhoneAccount,
|
2014-08-07 19:46:01 -07:00
|
|
|
id,
|
2014-07-30 10:07:40 -07:00
|
|
|
newRequest,
|
2014-10-02 09:38:39 -07:00
|
|
|
isIncoming,
|
|
|
|
false /* isUnknownCall */);
|
2014-09-08 15:34:24 -07:00
|
|
|
connection.registerCallback(new RemoteConnection.Callback() {
|
2014-08-08 17:06:11 -07:00
|
|
|
@Override
|
|
|
|
public void onDestroyed(RemoteConnection connection) {
|
2014-08-07 19:46:01 -07:00
|
|
|
mConnectionById.remove(id);
|
2014-08-23 20:34:57 -07:00
|
|
|
maybeDisconnectAdapter();
|
2014-08-08 17:06:11 -07:00
|
|
|
}
|
|
|
|
});
|
2014-07-30 10:07:40 -07:00
|
|
|
return connection;
|
|
|
|
} catch (RemoteException e) {
|
2014-09-11 17:33:16 -07:00
|
|
|
return RemoteConnection.failure(
|
|
|
|
new DisconnectCause(DisconnectCause.ERROR, e.toString()));
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-30 09:17:03 -07:00
|
|
|
private boolean hasConnection(String callId) {
|
2014-10-08 13:39:28 -07:00
|
|
|
return mConnectionById.containsKey(callId);
|
2014-09-30 09:17:03 -07:00
|
|
|
}
|
|
|
|
|
2014-08-07 19:46:01 -07:00
|
|
|
private RemoteConnection findConnectionForAction(
|
|
|
|
String callId, String action) {
|
2014-07-30 10:07:40 -07:00
|
|
|
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
|
|
|
}
|
2014-08-23 20:34:57 -07:00
|
|
|
|
|
|
|
private RemoteConference findConferenceForAction(
|
|
|
|
String callId, String action) {
|
|
|
|
if (mConferenceById.containsKey(callId)) {
|
|
|
|
return mConferenceById.get(callId);
|
|
|
|
}
|
|
|
|
Log.w(this, "%s - Cannot find Conference %s", action, callId);
|
|
|
|
return NULL_CONFERENCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void maybeDisconnectAdapter() {
|
|
|
|
if (mConnectionById.isEmpty() && mConferenceById.isEmpty()) {
|
|
|
|
try {
|
|
|
|
mOutgoingConnectionServiceRpc.removeConnectionServiceAdapter(mServant.getStub());
|
|
|
|
} catch (RemoteException e) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-17 19:08:45 -07:00
|
|
|
}
|