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

Commit 18c2906a authored by Grant Menke's avatar Grant Menke Committed by Android (Google) Code Review
Browse files

Merge "Add framework support for multi-party anchor conf." into main

parents 313e2f17 d0d1d45c
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -44333,6 +44333,7 @@ package android.telecom {
    method public final void destroy();
    method @Deprecated public final android.telecom.CallAudioState getCallAudioState();
    method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
    method @FlaggedApi("com.android.server.telecom.flags.multi_party_anchor_conf") @NonNull public final java.util.List<android.telecom.Conferenceable> getConferenceables();
    method public final int getConnectionCapabilities();
    method public final int getConnectionProperties();
    method public final long getConnectionStartElapsedRealtimeMillis();
@@ -44357,6 +44358,7 @@ package android.telecom {
    method public void onExtrasChanged(android.os.Bundle);
    method public void onHold();
    method public void onMerge(android.telecom.Connection);
    method @FlaggedApi("com.android.server.telecom.flags.multi_party_anchor_conf") public void onMerge(@NonNull android.telecom.Conference);
    method public void onMerge();
    method public void onMuteStateChanged(boolean);
    method public void onPlayDtmfTone(char);
@@ -44371,7 +44373,8 @@ package android.telecom {
    method public final void removeExtras(java.lang.String...);
    method public void sendConferenceEvent(@NonNull String, @Nullable android.os.Bundle);
    method public final void setActive();
    method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
    method @Deprecated @FlaggedApi("com.android.server.telecom.flags.multi_party_anchor_conf") public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
    method @FlaggedApi("com.android.server.telecom.flags.multi_party_anchor_conf") public final void setConferenceables(@NonNull java.util.List<android.telecom.Conferenceable>);
    method public final void setConnectionCapabilities(int);
    method public final void setConnectionProperties(int);
    method @Deprecated public final void setConnectionStartElapsedRealTime(long);
@@ -45724,6 +45727,7 @@ package android.telephony {
    field public static final String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
    field public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool";
    field public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool";
    field @FlaggedApi("com.android.server.telecom.flags.multi_party_anchor_conf") public static final String KEY_SUPPORT_MULTI_PARTY_ANCHOR_CONFERENCE_BOOL = "support_multi_anchor_conf_bool";
    field public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
    field @Deprecated public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
    field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
+118 −12
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.telecom;
import static android.Manifest.permission.MODIFY_PHONE_STATE;

import android.annotation.ElapsedRealtimeLong;
import android.annotation.FlaggedApi;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,6 +31,8 @@ import android.os.SystemClock;
import android.telecom.Connection.VideoProvider;
import android.util.ArraySet;

import com.android.server.telecom.flags.Flags;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -56,7 +59,9 @@ public abstract class Conference extends Conferenceable {
        public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {}
        public void onConnectionAdded(Conference conference, Connection connection) {}
        public void onConnectionRemoved(Conference conference, Connection connection) {}
        public void onConferenceableConnectionsChanged(
        public void onConferenceablesChanged(
                Conference conference, List<Conferenceable> conferenceables) {}
        public void onConferenceableConnectionsChangedLegacy(
                Conference conference, List<Connection> conferenceableConnections) {}
        public void onDestroyed(Conference conference) {}
        public void onConnectionCapabilitiesChanged(
@@ -81,6 +86,9 @@ public abstract class Conference extends Conferenceable {
    private final List<Connection> mChildConnections = new CopyOnWriteArrayList<>();
    private final List<Connection> mUnmodifiableChildConnections =
            Collections.unmodifiableList(mChildConnections);
    private final List<Conferenceable> mConferenceables = new ArrayList<>();
    private final List<Conferenceable> mUnmodifiableConferenceables =
            Collections.unmodifiableList(mConferenceables);
    private final List<Connection> mConferenceableConnections = new ArrayList<>();
    private final List<Connection> mUnmodifiableConferenceableConnections =
            Collections.unmodifiableList(mConferenceableConnections);
@@ -108,13 +116,28 @@ public abstract class Conference extends Conferenceable {
    private boolean mRingbackRequested = false;
    private boolean mIsMultiparty = true;

    private final Listener mConferenceDeathListener = new Listener() {
        @Override
        public void onDestroyed(Conference c) {
            if (mConferenceables.remove(c)) {
                fireOnConferenceableConnectionsChanged();
            }
        }
    };

    private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
        @Override
        public void onDestroyed(Connection c) {
            if (Flags.multiPartyAnchorConf()) {
                if (mConferenceables.remove(c)) {
                    fireOnConferenceableConnectionsChanged();
                }
            } else {
                if (mConferenceableConnections.remove(c)) {
                    fireOnConferenceableConnectionsChanged();
                }
            }
        }
    };

    /**
@@ -279,6 +302,16 @@ public abstract class Conference extends Conferenceable {
     */
    public void onMerge(Connection connection) {}

    /**
     * Notifies the {@link Conference} when the specified {@link Conference} should be merged with
     * the conference call.
     *
     * @param conference The {@code Conference} to merge.
     */
    @FlaggedApi(Flags.FLAG_MULTI_PARTY_ANCHOR_CONF)

    public void onMerge(@NonNull Conference conference) {}

    /**
     * Notifies the {@link Conference} when it should be put on hold.
     */
@@ -520,18 +553,55 @@ public abstract class Conference extends Conferenceable {
    /**
     * Sets the connections with which this connection can be conferenced.
     *
     * @param conferenceableConnections The set of connections this connection can conference with.
     * @param conferenceableConnections The set of connections this conference can conference with.
     *
     * @deprecated Use {@link #setConferenceables} instead.
     */
    @FlaggedApi(Flags.FLAG_MULTI_PARTY_ANCHOR_CONF)
    @Deprecated
    public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
        clearConferenceableList();
        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 (Flags.multiPartyAnchorConf()) {
                if (!mConferenceables.contains(c)) {
                    c.addConnectionListener(mConnectionDeathListener);
                    mConferenceables.add(c);
                }
            } else {
                if (!mConferenceableConnections.contains(c)) {
                    c.addConnectionListener(mConnectionDeathListener);
                    mConferenceableConnections.add(c);
                }
            }

        }
        fireOnConferenceableConnectionsChanged();
    }

    /**
     * Sets a list of connections or conferences with which this conference can be conferenced.
     *
     * @param conferenceables The set of conferenceables this conference can conference with.
     */
    @FlaggedApi(Flags.FLAG_MULTI_PARTY_ANCHOR_CONF)
    public final void setConferenceables(@NonNull List<Conferenceable> conferenceables) {
        clearConferenceableList();
        for (Conferenceable 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();
    }

@@ -582,16 +652,39 @@ public abstract class Conference extends Conferenceable {

    private final void fireOnConferenceableConnectionsChanged() {
        for (Listener l : mListeners) {
            l.onConferenceableConnectionsChanged(this, getConferenceableConnections());
            if (Flags.multiPartyAnchorConf()) {
                l.onConferenceablesChanged(this, getConferenceables());
            } else {
                l.onConferenceableConnectionsChangedLegacy(this,
                        getConferenceableConnections());
            }
        }
    }

    /**
     * Returns the {@link Connection}s or {@link Conference}s with which this {@link Conference}
     * can be merged / conferenced.
     */
    @FlaggedApi(Flags.FLAG_MULTI_PARTY_ANCHOR_CONF)
    public final @NonNull List<Conferenceable> getConferenceables() {
        return mUnmodifiableConferenceables;
    }

    /**
     * Returns the connections with which this connection can be conferenced.
     */
    public final List<Connection> getConferenceableConnections() {
        if (Flags.multiPartyAnchorConf()) {
            // return the list of Connection instances from mUnmodifiableConferenceables
            List<Connection> connections = new ArrayList<>();
            for (Conferenceable c : mUnmodifiableConferenceables) {
                if (c instanceof Connection) connections.add((Connection) c);
            }
            return connections;
        } else {
            return mUnmodifiableConferenceableConnections;
        }
    }

    /**
     * Tears down the conference object and any of its current connections.
@@ -846,11 +939,24 @@ public abstract class Conference extends Conferenceable {
    }

    private final void clearConferenceableList() {
        if (Flags.multiPartyAnchorConf()) {
            for (Conferenceable 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);
                }
            }
            mConferenceables.clear();
        } else {
            for (Connection c : mConferenceableConnections) {
                c.removeConnectionListener(mConnectionDeathListener);
            }
            mConferenceableConnections.clear();
        }
    }

    @Override
    public String toString() {
+20 −5
Original line number Diff line number Diff line
@@ -1891,7 +1891,15 @@ public abstract class ConnectionService extends Service {
        }

        @Override
        public void onConferenceableConnectionsChanged(
        public void onConferenceablesChanged(
                Conference conference, List<Conferenceable> conferenceables) {
            mAdapter.setConferenceableConnections(
                    mIdByConference.get(conference),
                    createIdList(conferenceables));
        }

        @Override
        public void onConferenceableConnectionsChangedLegacy(
                Conference conference, List<Connection> conferenceableConnections) {
            mAdapter.setConferenceableConnections(
                    mIdByConference.get(conference),
@@ -2751,12 +2759,19 @@ public abstract class ConnectionService extends Service {
                    // 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.");
                    if (Flags.multiPartyAnchorConf()) {
                        // Call 2 is ALSO a conference, so merge together.
                        Log.i(this, "conference: merging 2 conferences into a "
                                + "multi-party anchor conference call. conference1 = [%s] "
                                + "conference2 = [%s]");
                        conference1.onMerge(conference2);
                    } else {
                        Log.wtf(this, "There can only be one conference and an "
                                + "attempt was made to merge two conferences.");
                        return;
                    }
                }
            }
        } else {
            // Call 1 is a connection.
            if (conference2 != getNullConference()) {
+10 −0
Original line number Diff line number Diff line
@@ -1478,6 +1478,15 @@ public class CarrierConfigManager {
    public static final String KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL =
            "is_ims_conference_size_enforced_bool";
    /**
     * Determine whether multi-party anchor conference calls are supported by a carrier. When
     * {@code true}, merging a locally hosted conference call with a remotely hosted conference
     * into a multi-party anchor conference call is permitted, {@code false otherwise}.
     */
    @FlaggedApi(com.android.server.telecom.flags.Flags.FLAG_MULTI_PARTY_ANCHOR_CONF)
    public static final String KEY_SUPPORT_MULTI_PARTY_ANCHOR_CONFERENCE_BOOL =
            "support_multi_anchor_conf_bool";
    /**
     * Determines the maximum number of participants the carrier supports for a conference call.
     * This number is exclusive of the current device. A conference between 3 devices, for example,
@@ -11106,6 +11115,7 @@ public class CarrierConfigManager {
        sDefaults.putBoolean(KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_DTMF_BOOL, false);
        sDefaults.putBoolean(KEY_SUPPORT_VIDEO_CONFERENCE_CALL_BOOL, false);
        sDefaults.putBoolean(KEY_IS_IMS_CONFERENCE_SIZE_ENFORCED_BOOL, false);
        sDefaults.putBoolean(KEY_SUPPORT_MULTI_PARTY_ANCHOR_CONFERENCE_BOOL, false);
        sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
        sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
        sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);