Renaming Telecomm to Telecom.
- Changing package from android.telecomm to android.telecom - Changing package from com.android.telecomm to com.android.server.telecomm. - Renaming TelecommManager to TelecomManager. Bug: 17364651 Change-Id: I192cb5d189f55db012ea72ee82ccc5aedbc21638
This commit is contained in:
385
telecomm/java/android/telecom/RemoteConnectionService.java
Normal file
385
telecomm/java/android/telecom/RemoteConnectionService.java
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* 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 android.telecom;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.IBinder.DeathRecipient;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.DisconnectCause;
|
||||
|
||||
import com.android.internal.telecom.IConnectionService;
|
||||
import com.android.internal.telecom.IConnectionServiceAdapter;
|
||||
import com.android.internal.telecom.IVideoProvider;
|
||||
import com.android.internal.telecom.RemoteServiceCallback;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Remote connection service which other connection services can use to place calls on their behalf.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
final class RemoteConnectionService {
|
||||
|
||||
private static final RemoteConnection NULL_CONNECTION =
|
||||
new RemoteConnection("NULL", null, null);
|
||||
|
||||
private static final RemoteConference NULL_CONFERENCE =
|
||||
new RemoteConference("NULL", null);
|
||||
|
||||
private final IConnectionServiceAdapter mServantDelegate = new IConnectionServiceAdapter() {
|
||||
@Override
|
||||
public void handleCreateConnectionComplete(
|
||||
String id,
|
||||
ConnectionRequest request,
|
||||
ParcelableConnection parcel) {
|
||||
RemoteConnection connection =
|
||||
findConnectionForAction(id, "handleCreateConnectionSuccessful");
|
||||
if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
|
||||
mPendingConnections.remove(connection);
|
||||
// Unconditionally initialize the connection ...
|
||||
connection.setCallCapabilities(parcel.getCapabilities());
|
||||
connection.setAddress(
|
||||
parcel.getHandle(), parcel.getHandlePresentation());
|
||||
connection.setCallerDisplayName(
|
||||
parcel.getCallerDisplayName(),
|
||||
parcel.getCallerDisplayNamePresentation());
|
||||
// Set state after handle so that the client can identify the connection.
|
||||
connection.setState(parcel.getState());
|
||||
List<RemoteConnection> conferenceable = new ArrayList<>();
|
||||
for (String confId : parcel.getConferenceableConnectionIds()) {
|
||||
if (mConnectionById.containsKey(confId)) {
|
||||
conferenceable.add(mConnectionById.get(confId));
|
||||
}
|
||||
}
|
||||
connection.setConferenceableConnections(conferenceable);
|
||||
connection.setVideoState(parcel.getVideoState());
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActive(String callId) {
|
||||
if (mConnectionById.containsKey(callId)) {
|
||||
findConnectionForAction(callId, "setActive")
|
||||
.setState(Connection.STATE_ACTIVE);
|
||||
} else {
|
||||
findConferenceForAction(callId, "setActive")
|
||||
.setState(Connection.STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRinging(String callId) {
|
||||
findConnectionForAction(callId, "setRinging")
|
||||
.setState(Connection.STATE_RINGING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDialing(String callId) {
|
||||
findConnectionForAction(callId, "setDialing")
|
||||
.setState(Connection.STATE_DIALING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisconnected(String callId, int disconnectCause,
|
||||
String disconnectMessage) {
|
||||
if (mConnectionById.containsKey(callId)) {
|
||||
findConnectionForAction(callId, "setDisconnected")
|
||||
.setDisconnected(disconnectCause, disconnectMessage);
|
||||
} else {
|
||||
findConferenceForAction(callId, "setDisconnected")
|
||||
.setDisconnected(disconnectCause, disconnectMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnHold(String callId) {
|
||||
if (mConnectionById.containsKey(callId)) {
|
||||
findConnectionForAction(callId, "setOnHold")
|
||||
.setState(Connection.STATE_HOLDING);
|
||||
} else {
|
||||
findConferenceForAction(callId, "setOnHold")
|
||||
.setState(Connection.STATE_HOLDING);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRingbackRequested(String callId, boolean ringing) {
|
||||
findConnectionForAction(callId, "setRingbackRequested")
|
||||
.setRingbackRequested(ringing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCallCapabilities(String callId, int callCapabilities) {
|
||||
if (mConnectionById.containsKey(callId)) {
|
||||
findConnectionForAction(callId, "setCallCapabilities")
|
||||
.setCallCapabilities(callCapabilities);
|
||||
} else {
|
||||
findConferenceForAction(callId, "setCallCapabilities")
|
||||
.setCallCapabilities(callCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsConferenced(String callId, String conferenceCallId) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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());
|
||||
conference.setCallCapabilities(parcel.getCapabilities());
|
||||
mConferenceById.put(callId, conference);
|
||||
conference.registerCallback(new RemoteConference.Callback() {
|
||||
@Override
|
||||
public void onDestroyed(RemoteConference c) {
|
||||
mConferenceById.remove(callId);
|
||||
maybeDisconnectAdapter();
|
||||
}
|
||||
});
|
||||
|
||||
mOurConnectionServiceImpl.addRemoteConference(conference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCall(String callId) {
|
||||
if (mConnectionById.containsKey(callId)) {
|
||||
findConnectionForAction(callId, "removeCall")
|
||||
.setDestroyed();
|
||||
} else {
|
||||
findConferenceForAction(callId, "removeCall")
|
||||
.setDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostDialWait(String callId, String remaining) {
|
||||
findConnectionForAction(callId, "onPostDialWait")
|
||||
.setPostDialWait(remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryRemoteConnectionServices(RemoteServiceCallback callback) {
|
||||
// Not supported from remote connection service.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoProvider(String callId, IVideoProvider videoProvider) {
|
||||
findConnectionForAction(callId, "setVideoProvider")
|
||||
.setVideoProvider(new RemoteConnection.VideoProvider(videoProvider));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoState(String callId, int videoState) {
|
||||
findConnectionForAction(callId, "setVideoState")
|
||||
.setVideoState(videoState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIsVoipAudioMode(String callId, boolean isVoip) {
|
||||
findConnectionForAction(callId, "setIsVoipAudioMode")
|
||||
.setIsVoipAudioMode(isVoip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatusHints(String callId, StatusHints statusHints) {
|
||||
findConnectionForAction(callId, "setStatusHints")
|
||||
.setStatusHints(statusHints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAddress(String callId, Uri address, int presentation) {
|
||||
findConnectionForAction(callId, "setAddress")
|
||||
.setAddress(address, presentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCallerDisplayName(String callId, String callerDisplayName,
|
||||
int presentation) {
|
||||
findConnectionForAction(callId, "setCallerDisplayName")
|
||||
.setCallerDisplayName(callerDisplayName, presentation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setConferenceableConnections(
|
||||
String callId, List<String> conferenceableConnectionIds) {
|
||||
List<RemoteConnection> conferenceable = new ArrayList<>();
|
||||
for (String id : conferenceableConnectionIds) {
|
||||
if (mConnectionById.containsKey(id)) {
|
||||
conferenceable.add(mConnectionById.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
findConnectionForAction(callId, "setConferenceableConnections")
|
||||
.setConferenceableConnections(conferenceable);
|
||||
}
|
||||
};
|
||||
|
||||
private final ConnectionServiceAdapterServant mServant =
|
||||
new ConnectionServiceAdapterServant(mServantDelegate);
|
||||
|
||||
private final DeathRecipient mDeathRecipient = new DeathRecipient() {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
for (RemoteConnection c : mConnectionById.values()) {
|
||||
c.setDestroyed();
|
||||
}
|
||||
for (RemoteConference c : mConferenceById.values()) {
|
||||
c.setDestroyed();
|
||||
}
|
||||
mConnectionById.clear();
|
||||
mConferenceById.clear();
|
||||
mPendingConnections.clear();
|
||||
mOutgoingConnectionServiceRpc.asBinder().unlinkToDeath(mDeathRecipient, 0);
|
||||
}
|
||||
};
|
||||
|
||||
private final IConnectionService mOutgoingConnectionServiceRpc;
|
||||
private final ConnectionService mOurConnectionServiceImpl;
|
||||
private final Map<String, RemoteConnection> mConnectionById = new HashMap<>();
|
||||
private final Map<String, RemoteConference> mConferenceById = new HashMap<>();
|
||||
private final Set<RemoteConnection> mPendingConnections = new HashSet<>();
|
||||
|
||||
RemoteConnectionService(
|
||||
IConnectionService outgoingConnectionServiceRpc,
|
||||
ConnectionService ourConnectionServiceImpl) throws RemoteException {
|
||||
mOutgoingConnectionServiceRpc = outgoingConnectionServiceRpc;
|
||||
mOutgoingConnectionServiceRpc.asBinder().linkToDeath(mDeathRecipient, 0);
|
||||
mOurConnectionServiceImpl = ourConnectionServiceImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[RemoteCS - " + mOutgoingConnectionServiceRpc.asBinder().toString() + "]";
|
||||
}
|
||||
|
||||
final RemoteConnection createRemoteConnection(
|
||||
PhoneAccountHandle connectionManagerPhoneAccount,
|
||||
ConnectionRequest request,
|
||||
boolean isIncoming) {
|
||||
final String id = UUID.randomUUID().toString();
|
||||
final ConnectionRequest newRequest = new ConnectionRequest(
|
||||
request.getAccountHandle(),
|
||||
request.getAddress(),
|
||||
request.getExtras(),
|
||||
request.getVideoState());
|
||||
try {
|
||||
if (mConnectionById.isEmpty()) {
|
||||
mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub());
|
||||
}
|
||||
RemoteConnection connection =
|
||||
new RemoteConnection(id, mOutgoingConnectionServiceRpc, newRequest);
|
||||
mPendingConnections.add(connection);
|
||||
mConnectionById.put(id, connection);
|
||||
mOutgoingConnectionServiceRpc.createConnection(
|
||||
connectionManagerPhoneAccount,
|
||||
id,
|
||||
newRequest,
|
||||
isIncoming);
|
||||
connection.registerCallback(new RemoteConnection.Callback() {
|
||||
@Override
|
||||
public void onDestroyed(RemoteConnection connection) {
|
||||
mConnectionById.remove(id);
|
||||
maybeDisconnectAdapter();
|
||||
}
|
||||
});
|
||||
return connection;
|
||||
} catch (RemoteException e) {
|
||||
return RemoteConnection
|
||||
.failure(DisconnectCause.ERROR_UNSPECIFIED, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user