Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4340f89 authored by Tyler Gunn's avatar Tyler Gunn Committed by Android (Google) Code Review
Browse files

Merge "Change Connections to allow setting conferenceable with conferences." into lmp-mr1-dev

parents 70273e05 6d76ca04
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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 {
+56 −16
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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,
@@ -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();
            }
            }
        }
        }
@@ -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;
@@ -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;
    }
    }


    /*
    /*
@@ -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());
        }
        }
    }
    }


@@ -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();
    }
    }


    /**
    /**
+58 −8
Original line number Original line Diff line number Diff line
@@ -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
@@ -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) {
@@ -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");
@@ -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);
@@ -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) {};
+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 {

}