summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2014-11-17 15:49:51 -0800
committerTyler Gunn <tgunn@google.com>2014-11-17 15:49:51 -0800
commit6d76ca0438c2cb7a7d5d91992db819c063c0a57b (patch)
tree74a11f2f8b5c7d736a3ff816c31d9a998f21cada
parent5aadd5b6fa8ee9f09cd4870c8f104c1e611aebcd (diff)
downloadframeworks_base-6d76ca0438c2cb7a7d5d91992db819c063c0a57b.zip
frameworks_base-6d76ca0438c2cb7a7d5d91992db819c063c0a57b.tar.gz
frameworks_base-6d76ca0438c2cb7a7d5d91992db819c063c0a57b.tar.bz2
Change Connections to allow setting conferenceable with conferences.
- Added IConferenceable interface used so that connections and conferences can both be considered candidates as "conferenceable" with a connection. - Fixed ConnectionService#conference to support cases where either call 1 or call 2 is a conference and the other is a connection. Previously did not support cases where call 2 is a conference. Bug: 18200934 Change-Id: I32a8dd30a154d6280f2ae89fd147817235998465
-rw-r--r--telecomm/java/android/telecom/Conference.java2
-rw-r--r--telecomm/java/android/telecom/Connection.java72
-rw-r--r--telecomm/java/android/telecom/ConnectionService.java66
-rw-r--r--telecomm/java/android/telecom/IConferenceable.java31
4 files changed, 146 insertions, 25 deletions
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index 215c682..6e404de 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -30,7 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
* @hide
*/
@SystemApi
-public abstract class Conference {
+public abstract class Conference implements IConferenceable {
/** @hide */
public abstract static class Listener {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 63b44a6..fb63c85 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -47,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @hide
*/
@SystemApi
-public abstract class Connection {
+public abstract class Connection implements IConferenceable {
public static final int STATE_INITIALIZING = 0;
@@ -82,8 +82,8 @@ public abstract class Connection {
Connection c, VideoProvider videoProvider) {}
public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
- public void onConferenceableConnectionsChanged(
- Connection c, List<Connection> conferenceableConnections) {}
+ public void onConferenceablesChanged(
+ Connection c, List<IConferenceable> conferenceables) {}
public void onConferenceChanged(Connection c, Conference conference) {}
/** @hide */
public void onConferenceParticipantsChanged(Connection c,
@@ -449,7 +449,16 @@ public abstract class Connection {
private final Listener mConnectionDeathListener = new Listener() {
@Override
public void onDestroyed(Connection c) {
- if (mConferenceableConnections.remove(c)) {
+ if (mConferenceables.remove(c)) {
+ fireOnConferenceableConnectionsChanged();
+ }
+ }
+ };
+
+ private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
+ @Override
+ public void onDestroyed(Conference c) {
+ if (mConferenceables.remove(c)) {
fireOnConferenceableConnectionsChanged();
}
}
@@ -462,9 +471,9 @@ public abstract class Connection {
*/
private final Set<Listener> mListeners = Collections.newSetFromMap(
new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
- private final List<Connection> mConferenceableConnections = new ArrayList<>();
- private final List<Connection> mUnmodifiableConferenceableConnections =
- Collections.unmodifiableList(mConferenceableConnections);
+ private final List<IConferenceable> mConferenceables = new ArrayList<>();
+ private final List<IConferenceable> mUnmodifiableConferenceables =
+ Collections.unmodifiableList(mConferenceables);
private int mState = STATE_NEW;
private AudioState mAudioState;
@@ -864,19 +873,44 @@ public abstract class Connection {
for (Connection c : conferenceableConnections) {
// If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
// small amount of items here.
- if (!mConferenceableConnections.contains(c)) {
+ if (!mConferenceables.contains(c)) {
c.addConnectionListener(mConnectionDeathListener);
- mConferenceableConnections.add(c);
+ mConferenceables.add(c);
}
}
fireOnConferenceableConnectionsChanged();
}
/**
- * Returns the connections with which this connection can be conferenced.
+ * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
+ * or conferences with which this connection can be conferenced.
+ *
+ * @param conferenceables The conferenceables.
*/
- public final List<Connection> getConferenceableConnections() {
- return mUnmodifiableConferenceableConnections;
+ public final void setConferenceables(List<IConferenceable> conferenceables) {
+ clearConferenceableList();
+ for (IConferenceable c : conferenceables) {
+ // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
+ // small amount of items here.
+ if (!mConferenceables.contains(c)) {
+ if (c instanceof Connection) {
+ Connection connection = (Connection) c;
+ connection.addConnectionListener(mConnectionDeathListener);
+ } else if (c instanceof Conference) {
+ Conference conference = (Conference) c;
+ conference.addListener(mConferenceDeathListener);
+ }
+ mConferenceables.add(c);
+ }
+ }
+ fireOnConferenceableConnectionsChanged();
+ }
+
+ /**
+ * Returns the connections or conferences with which this connection can be conferenced.
+ */
+ public final List<IConferenceable> getConferenceables() {
+ return mUnmodifiableConferenceables;
}
/*
@@ -1109,7 +1143,7 @@ public abstract class Connection {
private final void fireOnConferenceableConnectionsChanged() {
for (Listener l : mListeners) {
- l.onConferenceableConnectionsChanged(this, getConferenceableConnections());
+ l.onConferenceablesChanged(this, getConferenceables());
}
}
@@ -1120,10 +1154,16 @@ public abstract class Connection {
}
private final void clearConferenceableList() {
- for (Connection c : mConferenceableConnections) {
- c.removeConnectionListener(mConnectionDeathListener);
+ for (IConferenceable c : mConferenceables) {
+ if (c instanceof Connection) {
+ Connection connection = (Connection) c;
+ connection.removeConnectionListener(mConnectionDeathListener);
+ } else if (c instanceof Conference) {
+ Conference conference = (Conference) c;
+ conference.removeListener(mConferenceDeathListener);
+ }
}
- mConferenceableConnections.clear();
+ mConferenceables.clear();
}
/**
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 48e6ff3..08f3853 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -515,11 +515,11 @@ public abstract class ConnectionService extends Service {
}
@Override
- public void onConferenceableConnectionsChanged(
- Connection connection, List<Connection> conferenceableConnections) {
+ public void onConferenceablesChanged(
+ Connection connection, List<IConferenceable> conferenceables) {
mAdapter.setConferenceableConnections(
mIdByConnection.get(connection),
- createConnectionIdList(conferenceableConnections));
+ createIdList(conferenceables));
}
@Override
@@ -602,7 +602,7 @@ public abstract class ConnectionService extends Service {
connection.getAudioModeIsVoip(),
connection.getStatusHints(),
connection.getDisconnectCause(),
- createConnectionIdList(connection.getConferenceableConnections())));
+ createIdList(connection.getConferenceables())));
}
private void abort(String callId) {
@@ -682,12 +682,19 @@ public abstract class ConnectionService extends Service {
private void conference(String callId1, String callId2) {
Log.d(this, "conference %s, %s", callId1, callId2);
+ // Attempt to get second connection or conference.
Connection connection2 = findConnectionForAction(callId2, "conference");
+ Conference conference2 = getNullConference();
if (connection2 == getNullConnection()) {
- Log.w(this, "Connection2 missing in conference request %s.", callId2);
- return;
+ conference2 = findConferenceForAction(callId2, "conference");
+ if (conference2 == getNullConference()) {
+ Log.w(this, "Connection2 or Conference2 missing in conference request %s.",
+ callId2);
+ return;
+ }
}
+ // Attempt to get first connection or conference and perform merge.
Connection connection1 = findConnectionForAction(callId1, "conference");
if (connection1 == getNullConnection()) {
Conference conference1 = findConferenceForAction(callId1, "addConnection");
@@ -696,10 +703,26 @@ public abstract class ConnectionService extends Service {
"Connection1 or Conference1 missing in conference request %s.",
callId1);
} else {
- conference1.onMerge(connection2);
+ // Call 1 is a conference.
+ if (connection2 != getNullConnection()) {
+ // Call 2 is a connection so merge via call 1 (conference).
+ conference1.onMerge(connection2);
+ } else {
+ // Call 2 is ALSO a conference; this should never happen.
+ Log.wtf(this, "There can only be one conference and an attempt was made to " +
+ "merge two conferences.");
+ return;
+ }
}
} else {
- onConference(connection1, connection2);
+ // Call 1 is a connection.
+ if (conference2 != getNullConference()) {
+ // Call 2 is a conference, so merge via call 2.
+ conference2.onMerge(connection1);
+ } else {
+ // Call 2 is a connection, so merge together.
+ onConference(connection1, connection2);
+ }
}
}
@@ -1111,6 +1134,33 @@ public abstract class ConnectionService extends Service {
return ids;
}
+ /**
+ * Builds a list of {@link Connection} and {@link Conference} IDs based on the list of
+ * {@link IConferenceable}s passed in.
+ *
+ * @param conferenceables The {@link IConferenceable} connections and conferences.
+ * @return List of string conference and call Ids.
+ */
+ private List<String> createIdList(List<IConferenceable> conferenceables) {
+ List<String> ids = new ArrayList<>();
+ for (IConferenceable c : conferenceables) {
+ // Only allow Connection and Conference conferenceables.
+ if (c instanceof Connection) {
+ Connection connection = (Connection) c;
+ if (mIdByConnection.containsKey(connection)) {
+ ids.add(mIdByConnection.get(connection));
+ }
+ } else if (c instanceof Conference) {
+ Conference conference = (Conference) c;
+ if (mIdByConference.containsKey(conference)) {
+ ids.add(mIdByConference.get(conference));
+ }
+ }
+ }
+ Collections.sort(ids);
+ return ids;
+ }
+
private Conference getNullConference() {
if (sNullConference == null) {
sNullConference = new Conference(null) {};
diff --git a/telecomm/java/android/telecom/IConferenceable.java b/telecomm/java/android/telecom/IConferenceable.java
new file mode 100644
index 0000000..095d7cb
--- /dev/null
+++ b/telecomm/java/android/telecom/IConferenceable.java
@@ -0,0 +1,31 @@
+/*
+ * 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.annotation.SystemApi;
+
+/**
+ * Interface used to identify entities with which another entity can participate in a conference
+ * call with. The {@link ConnectionService} implementation will only recognize
+ * {@link IConferenceable}s which are {@link Connection}s or {@link Conference}s.
+ *
+ * @hide
+ */
+@SystemApi
+public interface IConferenceable {
+
+}