Loading telecomm/java/android/telecom/Conference.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet; * @hide * @hide */ */ @SystemApi @SystemApi public abstract class Conference { public abstract class Conference implements IConferenceable { /** @hide */ /** @hide */ public abstract static class Listener { public abstract static class Listener { Loading telecomm/java/android/telecom/Connection.java +56 −16 Original line number Original line Diff line number Diff line Loading @@ -47,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap; * @hide * @hide */ */ @SystemApi @SystemApi public abstract class Connection { public abstract class Connection implements IConferenceable { public static final int STATE_INITIALIZING = 0; public static final int STATE_INITIALIZING = 0; Loading Loading @@ -82,8 +82,8 @@ public abstract class Connection { Connection c, VideoProvider videoProvider) {} Connection c, VideoProvider videoProvider) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onConferenceableConnectionsChanged( public void onConferenceablesChanged( Connection c, List<Connection> conferenceableConnections) {} Connection c, List<IConferenceable> conferenceables) {} public void onConferenceChanged(Connection c, Conference conference) {} public void onConferenceChanged(Connection c, Conference conference) {} /** @hide */ /** @hide */ public void onConferenceParticipantsChanged(Connection c, public void onConferenceParticipantsChanged(Connection c, Loading Loading @@ -449,7 +449,16 @@ public abstract class Connection { private final Listener mConnectionDeathListener = new Listener() { private final Listener mConnectionDeathListener = new Listener() { @Override @Override public void onDestroyed(Connection c) { 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(); fireOnConferenceableConnectionsChanged(); } } } } Loading @@ -462,9 +471,9 @@ public abstract class Connection { */ */ private final Set<Listener> mListeners = Collections.newSetFromMap( private final Set<Listener> mListeners = Collections.newSetFromMap( new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); private final List<Connection> mConferenceableConnections = new ArrayList<>(); private final List<IConferenceable> mConferenceables = new ArrayList<>(); private final List<Connection> mUnmodifiableConferenceableConnections = private final List<IConferenceable> mUnmodifiableConferenceables = Collections.unmodifiableList(mConferenceableConnections); Collections.unmodifiableList(mConferenceables); private int mState = STATE_NEW; private int mState = STATE_NEW; private AudioState mAudioState; private AudioState mAudioState; Loading Loading @@ -864,19 +873,44 @@ public abstract class Connection { for (Connection c : conferenceableConnections) { for (Connection c : conferenceableConnections) { // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a // small amount of items here. // small amount of items here. if (!mConferenceableConnections.contains(c)) { if (!mConferenceables.contains(c)) { c.addConnectionListener(mConnectionDeathListener); c.addConnectionListener(mConnectionDeathListener); mConferenceableConnections.add(c); mConferenceables.add(c); } } } } fireOnConferenceableConnectionsChanged(); 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() { public final void setConferenceables(List<IConferenceable> conferenceables) { return mUnmodifiableConferenceableConnections; 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; } } /* /* Loading Loading @@ -1109,7 +1143,7 @@ public abstract class Connection { private final void fireOnConferenceableConnectionsChanged() { private final void fireOnConferenceableConnectionsChanged() { for (Listener l : mListeners) { for (Listener l : mListeners) { l.onConferenceableConnectionsChanged(this, getConferenceableConnections()); l.onConferenceablesChanged(this, getConferenceables()); } } } } Loading @@ -1120,10 +1154,16 @@ public abstract class Connection { } } private final void clearConferenceableList() { private final void clearConferenceableList() { for (Connection c : mConferenceableConnections) { for (IConferenceable c : mConferenceables) { c.removeConnectionListener(mConnectionDeathListener); 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(); } } /** /** Loading telecomm/java/android/telecom/ConnectionService.java +58 −8 Original line number Original line Diff line number Diff line Loading @@ -515,11 +515,11 @@ public abstract class ConnectionService extends Service { } } @Override @Override public void onConferenceableConnectionsChanged( public void onConferenceablesChanged( Connection connection, List<Connection> conferenceableConnections) { Connection connection, List<IConferenceable> conferenceables) { mAdapter.setConferenceableConnections( mAdapter.setConferenceableConnections( mIdByConnection.get(connection), mIdByConnection.get(connection), createConnectionIdList(conferenceableConnections)); createIdList(conferenceables)); } } @Override @Override Loading Loading @@ -602,7 +602,7 @@ public abstract class ConnectionService extends Service { connection.getAudioModeIsVoip(), connection.getAudioModeIsVoip(), connection.getStatusHints(), connection.getStatusHints(), connection.getDisconnectCause(), connection.getDisconnectCause(), createConnectionIdList(connection.getConferenceableConnections()))); createIdList(connection.getConferenceables()))); } } private void abort(String callId) { private void abort(String callId) { Loading Loading @@ -682,12 +682,19 @@ public abstract class ConnectionService extends Service { private void conference(String callId1, String callId2) { private void conference(String callId1, String callId2) { Log.d(this, "conference %s, %s", callId1, callId2); Log.d(this, "conference %s, %s", callId1, callId2); // Attempt to get second connection or conference. Connection connection2 = findConnectionForAction(callId2, "conference"); Connection connection2 = findConnectionForAction(callId2, "conference"); Conference conference2 = getNullConference(); if (connection2 == getNullConnection()) { if (connection2 == getNullConnection()) { Log.w(this, "Connection2 missing in conference request %s.", callId2); conference2 = findConferenceForAction(callId2, "conference"); if (conference2 == getNullConference()) { Log.w(this, "Connection2 or Conference2 missing in conference request %s.", callId2); return; return; } } } // Attempt to get first connection or conference and perform merge. Connection connection1 = findConnectionForAction(callId1, "conference"); Connection connection1 = findConnectionForAction(callId1, "conference"); if (connection1 == getNullConnection()) { if (connection1 == getNullConnection()) { Conference conference1 = findConferenceForAction(callId1, "addConnection"); Conference conference1 = findConferenceForAction(callId1, "addConnection"); Loading @@ -696,12 +703,28 @@ public abstract class ConnectionService extends Service { "Connection1 or Conference1 missing in conference request %s.", "Connection1 or Conference1 missing in conference request %s.", callId1); callId1); } else { } else { // Call 1 is a conference. if (connection2 != getNullConnection()) { // Call 2 is a connection so merge via call 1 (conference). conference1.onMerge(connection2); 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 { } else { // 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); onConference(connection1, connection2); } } } } } private void splitFromConference(String callId) { private void splitFromConference(String callId) { Log.d(this, "splitFromConference(%s)", callId); Log.d(this, "splitFromConference(%s)", callId); Loading Loading @@ -1111,6 +1134,33 @@ public abstract class ConnectionService extends Service { return ids; 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() { private Conference getNullConference() { if (sNullConference == null) { if (sNullConference == null) { sNullConference = new Conference(null) {}; sNullConference = new Conference(null) {}; Loading telecomm/java/android/telecom/IConferenceable.java 0 → 100644 +31 −0 Original line number Original line Diff line number Diff line /* * 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 { } Loading
telecomm/java/android/telecom/Conference.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet; * @hide * @hide */ */ @SystemApi @SystemApi public abstract class Conference { public abstract class Conference implements IConferenceable { /** @hide */ /** @hide */ public abstract static class Listener { public abstract static class Listener { Loading
telecomm/java/android/telecom/Connection.java +56 −16 Original line number Original line Diff line number Diff line Loading @@ -47,7 +47,7 @@ import java.util.concurrent.ConcurrentHashMap; * @hide * @hide */ */ @SystemApi @SystemApi public abstract class Connection { public abstract class Connection implements IConferenceable { public static final int STATE_INITIALIZING = 0; public static final int STATE_INITIALIZING = 0; Loading Loading @@ -82,8 +82,8 @@ public abstract class Connection { Connection c, VideoProvider videoProvider) {} Connection c, VideoProvider videoProvider) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onStatusHintsChanged(Connection c, StatusHints statusHints) {} public void onConferenceableConnectionsChanged( public void onConferenceablesChanged( Connection c, List<Connection> conferenceableConnections) {} Connection c, List<IConferenceable> conferenceables) {} public void onConferenceChanged(Connection c, Conference conference) {} public void onConferenceChanged(Connection c, Conference conference) {} /** @hide */ /** @hide */ public void onConferenceParticipantsChanged(Connection c, public void onConferenceParticipantsChanged(Connection c, Loading Loading @@ -449,7 +449,16 @@ public abstract class Connection { private final Listener mConnectionDeathListener = new Listener() { private final Listener mConnectionDeathListener = new Listener() { @Override @Override public void onDestroyed(Connection c) { 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(); fireOnConferenceableConnectionsChanged(); } } } } Loading @@ -462,9 +471,9 @@ public abstract class Connection { */ */ private final Set<Listener> mListeners = Collections.newSetFromMap( private final Set<Listener> mListeners = Collections.newSetFromMap( new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); private final List<Connection> mConferenceableConnections = new ArrayList<>(); private final List<IConferenceable> mConferenceables = new ArrayList<>(); private final List<Connection> mUnmodifiableConferenceableConnections = private final List<IConferenceable> mUnmodifiableConferenceables = Collections.unmodifiableList(mConferenceableConnections); Collections.unmodifiableList(mConferenceables); private int mState = STATE_NEW; private int mState = STATE_NEW; private AudioState mAudioState; private AudioState mAudioState; Loading Loading @@ -864,19 +873,44 @@ public abstract class Connection { for (Connection c : conferenceableConnections) { for (Connection c : conferenceableConnections) { // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a // small amount of items here. // small amount of items here. if (!mConferenceableConnections.contains(c)) { if (!mConferenceables.contains(c)) { c.addConnectionListener(mConnectionDeathListener); c.addConnectionListener(mConnectionDeathListener); mConferenceableConnections.add(c); mConferenceables.add(c); } } } } fireOnConferenceableConnectionsChanged(); 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() { public final void setConferenceables(List<IConferenceable> conferenceables) { return mUnmodifiableConferenceableConnections; 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; } } /* /* Loading Loading @@ -1109,7 +1143,7 @@ public abstract class Connection { private final void fireOnConferenceableConnectionsChanged() { private final void fireOnConferenceableConnectionsChanged() { for (Listener l : mListeners) { for (Listener l : mListeners) { l.onConferenceableConnectionsChanged(this, getConferenceableConnections()); l.onConferenceablesChanged(this, getConferenceables()); } } } } Loading @@ -1120,10 +1154,16 @@ public abstract class Connection { } } private final void clearConferenceableList() { private final void clearConferenceableList() { for (Connection c : mConferenceableConnections) { for (IConferenceable c : mConferenceables) { c.removeConnectionListener(mConnectionDeathListener); 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(); } } /** /** Loading
telecomm/java/android/telecom/ConnectionService.java +58 −8 Original line number Original line Diff line number Diff line Loading @@ -515,11 +515,11 @@ public abstract class ConnectionService extends Service { } } @Override @Override public void onConferenceableConnectionsChanged( public void onConferenceablesChanged( Connection connection, List<Connection> conferenceableConnections) { Connection connection, List<IConferenceable> conferenceables) { mAdapter.setConferenceableConnections( mAdapter.setConferenceableConnections( mIdByConnection.get(connection), mIdByConnection.get(connection), createConnectionIdList(conferenceableConnections)); createIdList(conferenceables)); } } @Override @Override Loading Loading @@ -602,7 +602,7 @@ public abstract class ConnectionService extends Service { connection.getAudioModeIsVoip(), connection.getAudioModeIsVoip(), connection.getStatusHints(), connection.getStatusHints(), connection.getDisconnectCause(), connection.getDisconnectCause(), createConnectionIdList(connection.getConferenceableConnections()))); createIdList(connection.getConferenceables()))); } } private void abort(String callId) { private void abort(String callId) { Loading Loading @@ -682,12 +682,19 @@ public abstract class ConnectionService extends Service { private void conference(String callId1, String callId2) { private void conference(String callId1, String callId2) { Log.d(this, "conference %s, %s", callId1, callId2); Log.d(this, "conference %s, %s", callId1, callId2); // Attempt to get second connection or conference. Connection connection2 = findConnectionForAction(callId2, "conference"); Connection connection2 = findConnectionForAction(callId2, "conference"); Conference conference2 = getNullConference(); if (connection2 == getNullConnection()) { if (connection2 == getNullConnection()) { Log.w(this, "Connection2 missing in conference request %s.", callId2); conference2 = findConferenceForAction(callId2, "conference"); if (conference2 == getNullConference()) { Log.w(this, "Connection2 or Conference2 missing in conference request %s.", callId2); return; return; } } } // Attempt to get first connection or conference and perform merge. Connection connection1 = findConnectionForAction(callId1, "conference"); Connection connection1 = findConnectionForAction(callId1, "conference"); if (connection1 == getNullConnection()) { if (connection1 == getNullConnection()) { Conference conference1 = findConferenceForAction(callId1, "addConnection"); Conference conference1 = findConferenceForAction(callId1, "addConnection"); Loading @@ -696,12 +703,28 @@ public abstract class ConnectionService extends Service { "Connection1 or Conference1 missing in conference request %s.", "Connection1 or Conference1 missing in conference request %s.", callId1); callId1); } else { } else { // Call 1 is a conference. if (connection2 != getNullConnection()) { // Call 2 is a connection so merge via call 1 (conference). conference1.onMerge(connection2); 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 { } else { // 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); onConference(connection1, connection2); } } } } } private void splitFromConference(String callId) { private void splitFromConference(String callId) { Log.d(this, "splitFromConference(%s)", callId); Log.d(this, "splitFromConference(%s)", callId); Loading Loading @@ -1111,6 +1134,33 @@ public abstract class ConnectionService extends Service { return ids; 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() { private Conference getNullConference() { if (sNullConference == null) { if (sNullConference == null) { sNullConference = new Conference(null) {}; sNullConference = new Conference(null) {}; Loading
telecomm/java/android/telecom/IConferenceable.java 0 → 100644 +31 −0 Original line number Original line Diff line number Diff line /* * 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 { }