1823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon/*
2823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * Copyright (C) 2014 The Android Open Source Project
3823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon *
4823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * you may not use this file except in compliance with the License.
6823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * You may obtain a copy of the License at
7823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon *
8823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon *
10823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * Unless required by applicable law or agreed to in writing, software
11823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * See the License for the specific language governing permissions and
14823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * limitations under the License.
15823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon */
16823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
17ef9f6f957d897ea0ed82114185b8fa3fefd4917bTyler Gunnpackage android.telecom;
18823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
19dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunnimport android.annotation.NonNull;
206b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordonimport android.annotation.Nullable;
215d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordonimport android.annotation.SystemApi;
226b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordonimport android.os.Bundle;
2307366813cdf3768dcd69a1f744023747564d654aRekha Kumarimport android.telecom.Connection.VideoProvider;
24dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunnimport android.util.ArraySet;
250e094d926c306c3667bcdf6f23c52cc7181f25f3Evan Charlton
2650e3506533478fa273cbc92c2919470d1889f1edIhab Awadimport java.util.ArrayList;
27071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunnimport java.util.Arrays;
28823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordonimport java.util.Collections;
29823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordonimport java.util.List;
3007366813cdf3768dcd69a1f744023747564d654aRekha Kumarimport java.util.Locale;
31823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordonimport java.util.Set;
32823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordonimport java.util.concurrent.CopyOnWriteArrayList;
33823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordonimport java.util.concurrent.CopyOnWriteArraySet;
34823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
35823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon/**
36823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon * Represents a conference call which can contain any number of {@link Connection} objects.
37823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon */
38abfcfdc0444c48dd161e425c8417dab87de1cb69Yorke Leepublic abstract class Conference extends Conferenceable {
39823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
40cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    /**
41cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     * Used to indicate that the conference connection time is not specified.  If not specified,
42cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     * Telecom will set the connect time.
43cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     */
44164a0acf53a3496c974a97ed35834e6195c14e4bJay Shrauner    public static final long CONNECT_TIME_NOT_SPECIFIED = 0;
45cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn
46823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /** @hide */
47823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public abstract static class Listener {
48823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        public void onStateChanged(Conference conference, int oldState, int newState) {}
497f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee        public void onDisconnected(Conference conference, DisconnectCause disconnectCause) {}
50823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        public void onConnectionAdded(Conference conference, Connection connection) {}
51823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        public void onConnectionRemoved(Conference conference, Connection connection) {}
5250e3506533478fa273cbc92c2919470d1889f1edIhab Awad        public void onConferenceableConnectionsChanged(
5350e3506533478fa273cbc92c2919470d1889f1edIhab Awad                Conference conference, List<Connection> conferenceableConnections) {}
54823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        public void onDestroyed(Conference conference) {}
555c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        public void onConnectionCapabilitiesChanged(
565c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                Conference conference, int connectionCapabilities) {}
57720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        public void onConnectionPropertiesChanged(
58720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                Conference conference, int connectionProperties) {}
5907366813cdf3768dcd69a1f744023747564d654aRekha Kumar        public void onVideoStateChanged(Conference c, int videoState) { }
6007366813cdf3768dcd69a1f744023747564d654aRekha Kumar        public void onVideoProviderChanged(Conference c, Connection.VideoProvider videoProvider) {}
61edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee        public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {}
62dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        public void onExtrasChanged(Conference c, Bundle extras) {}
63dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        public void onExtrasRemoved(Conference c, List<String> keys) {}
64823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
65823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
66823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    private final Set<Listener> mListeners = new CopyOnWriteArraySet<>();
67823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    private final List<Connection> mChildConnections = new CopyOnWriteArrayList<>();
68b8e85c74e5910a461078704048d67f82b216508cIhab Awad    private final List<Connection> mUnmodifiableChildConnections =
69823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            Collections.unmodifiableList(mChildConnections);
7050e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private final List<Connection> mConferenceableConnections = new ArrayList<>();
7150e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private final List<Connection> mUnmodifiableConferenceableConnections =
7250e3506533478fa273cbc92c2919470d1889f1edIhab Awad            Collections.unmodifiableList(mConferenceableConnections);
73823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
746714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    private String mTelecomCallId;
75164a0acf53a3496c974a97ed35834e6195c14e4bJay Shrauner    private PhoneAccountHandle mPhoneAccount;
764af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    private CallAudioState mCallAudioState;
77823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    private int mState = Connection.STATE_NEW;
787f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee    private DisconnectCause mDisconnectCause;
795c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    private int mConnectionCapabilities;
80720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    private int mConnectionProperties;
81823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    private String mDisconnectMessage;
82cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    private long mConnectTimeMillis = CONNECT_TIME_NOT_SPECIFIED;
83edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    private StatusHints mStatusHints;
846b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    private Bundle mExtras;
85dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    private Set<String> mPreviousExtraKeys;
864fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger    private final Object mExtrasLock = new Object();
87823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
8850e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private final Connection.Listener mConnectionDeathListener = new Connection.Listener() {
8950e3506533478fa273cbc92c2919470d1889f1edIhab Awad        @Override
9050e3506533478fa273cbc92c2919470d1889f1edIhab Awad        public void onDestroyed(Connection c) {
9150e3506533478fa273cbc92c2919470d1889f1edIhab Awad            if (mConferenceableConnections.remove(c)) {
9250e3506533478fa273cbc92c2919470d1889f1edIhab Awad                fireOnConferenceableConnectionsChanged();
9350e3506533478fa273cbc92c2919470d1889f1edIhab Awad            }
9450e3506533478fa273cbc92c2919470d1889f1edIhab Awad        }
9550e3506533478fa273cbc92c2919470d1889f1edIhab Awad    };
9650e3506533478fa273cbc92c2919470d1889f1edIhab Awad
9756fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen    /**
9856fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * Constructs a new Conference with a mandatory {@link PhoneAccountHandle}
9956fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
10056fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * @param phoneAccount The {@code PhoneAccountHandle} associated with the conference.
10156fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     */
102823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public Conference(PhoneAccountHandle phoneAccount) {
103823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        mPhoneAccount = phoneAccount;
104823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
105823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
10656fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen    /**
1076714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * Returns the telecom internal call ID associated with this conference.
1086714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     *
1096714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * @return The telecom call ID.
1106714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * @hide
1116714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     */
1126714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    public final String getTelecomCallId() {
1136714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu        return mTelecomCallId;
1146714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    }
1156714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu
1166714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    /**
1176714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * Sets the telecom internal call ID associated with this conference.
1186714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     *
1196714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * @param telecomCallId The telecom call ID.
1206714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     * @hide
1216714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu     */
1226714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    public final void setTelecomCallId(String telecomCallId) {
1236714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu        mTelecomCallId = telecomCallId;
1246714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    }
1256714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu
1266714030083b1d8ec5b2df6dfef08034d0d30c2feJack Yu    /**
12756fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * Returns the {@link PhoneAccountHandle} the conference call is being placed through.
12856fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
12956fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * @return A {@code PhoneAccountHandle} object representing the PhoneAccount of the conference.
13056fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     */
131ea38cca14964a5ee658899b0bafbc48017d556cdNancy Chen    public final PhoneAccountHandle getPhoneAccountHandle() {
132823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        return mPhoneAccount;
133823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
134823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
13556fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen    /**
13656fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * Returns the list of connections currently associated with the conference call.
13756fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
13856fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * @return A list of {@code Connection} objects which represent the children of the conference.
13956fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     */
140823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final List<Connection> getConnections() {
141b8e85c74e5910a461078704048d67f82b216508cIhab Awad        return mUnmodifiableChildConnections;
142823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
143823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
14456fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen    /**
14556fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * Gets the state of the conference call. See {@link Connection} for valid values.
14656fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
14756fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     * @return A constant representing the state the conference call is currently in.
14856fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     */
149823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final int getState() {
150823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        return mState;
151823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
152823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
1535c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    /**
1545d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
1555c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * {@link Connection} for valid values.
1565c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     *
1575c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @return A bitmask of the capabilities of the conference call.
1585c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     */
1595c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public final int getConnectionCapabilities() {
1605c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        return mConnectionCapabilities;
1615c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    }
1625c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad
1635c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    /**
164720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * Returns the properties of the conference. See {@code PROPERTY_*} constants in class
165720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * {@link Connection} for valid values.
166720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     *
167720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * @return A bitmask of the properties of the conference call.
168720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     */
169720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    public final int getConnectionProperties() {
170720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        return mConnectionProperties;
171720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    }
172720c664401081ca00e56c7eef12641ae792da530Tyler Gunn
173720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    /**
1745c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * Whether the given capabilities support the specified capability.
1755c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     *
1765c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @param capabilities A capability bit field.
1775c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @param capability The capability to check capabilities for.
1785c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @return Whether the specified capability is supported.
1795c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @hide
1805c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     */
1815c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public static boolean can(int capabilities, int capability) {
1825c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        return (capabilities & capability) != 0;
1835c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    }
1845c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad
18556fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen    /**
1865c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * Whether the capabilities of this {@code Connection} supports the specified capability.
18756fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
1885c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @param capability The capability to check capabilities for.
1895c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @return Whether the specified capability is supported.
1905c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @hide
19156fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     */
1925c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public boolean can(int capability) {
1935c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        return can(mConnectionCapabilities, capability);
1945c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    }
1955c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad
1965c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    /**
1975c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * Removes the specified capability from the set of capabilities of this {@code Conference}.
1985c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     *
1995c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @param capability The capability to remove from the set.
2005c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @hide
2015c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     */
2025c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public void removeCapability(int capability) {
203a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        int newCapabilities = mConnectionCapabilities;
204a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        newCapabilities &= ~capability;
205a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade
206a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        setConnectionCapabilities(newCapabilities);
2075c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    }
2085c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad
2095c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    /**
2105c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * Adds the specified capability to the set of capabilities of this {@code Conference}.
2115c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     *
2125c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @param capability The capability to add to the set.
2135c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * @hide
2145c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     */
2155c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public void addCapability(int capability) {
216a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        int newCapabilities = mConnectionCapabilities;
217a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        newCapabilities |= capability;
218a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade
219a0f46a9e7d445852e1746594f0e90ea985f7d5bfOmkar Kolangade        setConnectionCapabilities(newCapabilities);
220823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
221823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
222823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
223a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * @return The audio state of the conference, describing how its audio is currently
224a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     *         being routed by the system. This is {@code null} if this Conference
225a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     *         does not directly know about its audio state.
2264af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @deprecated Use {@link #getCallAudioState()} instead.
2274af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @hide
228a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     */
2294af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    @Deprecated
2304af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    @SystemApi
231a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    public final AudioState getAudioState() {
2324af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        return new AudioState(mCallAudioState);
2334af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    }
2344af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee
2354af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    /**
2364af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @return The audio state of the conference, describing how its audio is currently
2374af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     *         being routed by the system. This is {@code null} if this Conference
2384af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     *         does not directly know about its audio state.
2394af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     */
2404af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    public final CallAudioState getCallAudioState() {
2414af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        return mCallAudioState;
242a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    }
243a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee
244a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    /**
24507366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * Returns VideoProvider of the primary call. This can be null.
24607366813cdf3768dcd69a1f744023747564d654aRekha Kumar     */
24707366813cdf3768dcd69a1f744023747564d654aRekha Kumar    public VideoProvider getVideoProvider() {
24807366813cdf3768dcd69a1f744023747564d654aRekha Kumar        return null;
24907366813cdf3768dcd69a1f744023747564d654aRekha Kumar    }
25007366813cdf3768dcd69a1f744023747564d654aRekha Kumar
25107366813cdf3768dcd69a1f744023747564d654aRekha Kumar    /**
25207366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * Returns video state of the primary call.
25307366813cdf3768dcd69a1f744023747564d654aRekha Kumar     */
25407366813cdf3768dcd69a1f744023747564d654aRekha Kumar    public int getVideoState() {
25587b73f370e2b8a76b0540580f43edba6ec21c6cfTyler Gunn        return VideoProfile.STATE_AUDIO_ONLY;
25607366813cdf3768dcd69a1f744023747564d654aRekha Kumar    }
25707366813cdf3768dcd69a1f744023747564d654aRekha Kumar
25807366813cdf3768dcd69a1f744023747564d654aRekha Kumar    /**
2599c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when the Conference and all it's {@link Connection}s should
2609c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * be disconnected.
261823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
262823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public void onDisconnect() {}
263823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
264823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
2659c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when the specified {@link Connection} should be separated
2669c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * from the conference call.
267823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
268823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @param connection The connection to separate.
269823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
270823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public void onSeparate(Connection connection) {}
271823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
272823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
2739c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when the specified {@link Connection} should merged with the
2749c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * conference call.
27550e3506533478fa273cbc92c2919470d1889f1edIhab Awad     *
27650e3506533478fa273cbc92c2919470d1889f1edIhab Awad     * @param connection The {@code Connection} to merge.
27750e3506533478fa273cbc92c2919470d1889f1edIhab Awad     */
27850e3506533478fa273cbc92c2919470d1889f1edIhab Awad    public void onMerge(Connection connection) {}
27950e3506533478fa273cbc92c2919470d1889f1edIhab Awad
28050e3506533478fa273cbc92c2919470d1889f1edIhab Awad    /**
2819c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when it should be put on hold.
282823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
283823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public void onHold() {}
284823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
285823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
2869c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when it should be moved from a held to active state.
287823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
288823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public void onUnhold() {}
289823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
290823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
2919c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when the child calls should be merged.  Only invoked if the
2929c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * conference contains the capability {@link Connection#CAPABILITY_MERGE_CONFERENCE}.
293a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon     */
294a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    public void onMerge() {}
295a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon
296a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    /**
2979c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} when the child calls should be swapped. Only invoked if the
2989c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * conference contains the capability {@link Connection#CAPABILITY_SWAP_CONFERENCE}.
299a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon     */
300a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    public void onSwap() {}
301a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon
302a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    /**
3039c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} of a request to play a DTMF tone.
304a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     *
305a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * @param c A DTMF character.
306a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     */
307a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    public void onPlayDtmfTone(char c) {}
308a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee
309a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    /**
3109c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} of a request to stop any currently playing DTMF tones.
311a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     */
312a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    public void onStopDtmfTone() {}
313a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee
314a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    /**
3159c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} that the {@link #getAudioState()} property has a new value.
316a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     *
317a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * @param state The new call audio state.
3184af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
3194af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @hide
320a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     */
3214af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    @SystemApi
3224af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    @Deprecated
323a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    public void onAudioStateChanged(AudioState state) {}
324a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee
325a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    /**
3269c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} that the {@link #getCallAudioState()} property has a new
3279c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * value.
3284af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     *
3294af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     * @param state The new call audio state.
3304af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee     */
3314af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    public void onCallAudioStateChanged(CallAudioState state) {}
3324af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee
3334af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    /**
3349c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Notifies the {@link Conference} that a {@link Connection} has been added to it.
33546f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee     *
33646f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee     * @param connection The newly added connection.
33746f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee     */
33846f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee    public void onConnectionAdded(Connection connection) {}
33946f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee
34046f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee    /**
341823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Sets state to be on hold.
342823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
343823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final void setOnHold() {
344823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        setState(Connection.STATE_HOLDING);
345823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
346823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
347823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
348d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn     * Sets state to be dialing.
349d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn     */
350d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn    public final void setDialing() {
351d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn        setState(Connection.STATE_DIALING);
352d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn    }
353d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn
354d46595a673eba0df624d9d92b6f981e3483e0d20Tyler Gunn    /**
355823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Sets state to be active.
356823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
357823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final void setActive() {
358823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        setState(Connection.STATE_ACTIVE);
359823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
360823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
361823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
362823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Sets state to disconnected.
363823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
3647f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee     * @param disconnectCause The reason for the disconnection, as described by
3657f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee     *     {@link android.telecom.DisconnectCause}.
366823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
3677f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee    public final void setDisconnected(DisconnectCause disconnectCause) {
3687f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee        mDisconnectCause = disconnectCause;;
369823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        setState(Connection.STATE_DISCONNECTED);
370823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        for (Listener l : mListeners) {
3717f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee            l.onDisconnected(this, mDisconnectCause);
372823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
373823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
374823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
375823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
3761cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley     * @return The {@link DisconnectCause} for this connection.
3771cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley     */
3781cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley    public final DisconnectCause getDisconnectCause() {
3791cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley        return mDisconnectCause;
3801cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley    }
3811cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley
3821cf14ac5dc5708fc31e6c987a5c7db465ff95533mike dooley    /**
3835c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * Sets the capabilities of a conference. See {@code CAPABILITY_*} constants of class
3845c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad     * {@link Connection} for valid values.
38556fc25deec15a32ea5f37d7c8c82f16d1bf9d275Nancy Chen     *
386720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * @param connectionCapabilities A bitmask of the {@code Capabilities} of the conference call.
387823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
3885c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad    public final void setConnectionCapabilities(int connectionCapabilities) {
3895c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad        if (connectionCapabilities != mConnectionCapabilities) {
3905c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad            mConnectionCapabilities = connectionCapabilities;
391823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
392823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            for (Listener l : mListeners) {
3935c9c86ec0f95d1f5e1aca212967f508fc736b895Ihab Awad                l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
394823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            }
395823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
396823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
397823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
398823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
399720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * Sets the properties of a conference. See {@code PROPERTY_*} constants of class
400720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * {@link Connection} for valid values.
401720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     *
402720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     * @param connectionProperties A bitmask of the {@code Properties} of the conference call.
403720c664401081ca00e56c7eef12641ae792da530Tyler Gunn     */
404720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    public final void setConnectionProperties(int connectionProperties) {
405720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        if (connectionProperties != mConnectionProperties) {
406720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            mConnectionProperties = connectionProperties;
407720c664401081ca00e56c7eef12641ae792da530Tyler Gunn
408720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            for (Listener l : mListeners) {
409720c664401081ca00e56c7eef12641ae792da530Tyler Gunn                l.onConnectionPropertiesChanged(this, mConnectionProperties);
410720c664401081ca00e56c7eef12641ae792da530Tyler Gunn            }
411720c664401081ca00e56c7eef12641ae792da530Tyler Gunn        }
412720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    }
413720c664401081ca00e56c7eef12641ae792da530Tyler Gunn
414720c664401081ca00e56c7eef12641ae792da530Tyler Gunn    /**
415823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Adds the specified connection as a child of this conference.
416823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
417823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @param connection The connection to add.
418823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @return True if the connection was successfully added.
419823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
420a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    public final boolean addConnection(Connection connection) {
42107366813cdf3768dcd69a1f744023747564d654aRekha Kumar        Log.d(this, "Connection=%s, connection=", connection);
422823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        if (connection != null && !mChildConnections.contains(connection)) {
423823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            if (connection.setConference(this)) {
424823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                mChildConnections.add(connection);
42546f7f5dce42d645353a0f3eb0dbdd25b3a6c72fbAndrew Lee                onConnectionAdded(connection);
426823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                for (Listener l : mListeners) {
427823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                    l.onConnectionAdded(this, connection);
428823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                }
429823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                return true;
430823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            }
431823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
432823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        return false;
433823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
434823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
435823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
436823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Removes the specified connection as a child of this conference.
437823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
438823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @param connection The connection to remove.
439823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
440a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    public final void removeConnection(Connection connection) {
4410159ac0cfe20e8f85ee4150e64d91392850f8a3fSantos Cordon        Log.d(this, "removing %s from %s", connection, mChildConnections);
442823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        if (connection != null && mChildConnections.remove(connection)) {
443823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            connection.resetConference();
444823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            for (Listener l : mListeners) {
445823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                l.onConnectionRemoved(this, connection);
446823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            }
447823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
448823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
449823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
450823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
45150e3506533478fa273cbc92c2919470d1889f1edIhab Awad     * Sets the connections with which this connection can be conferenced.
45250e3506533478fa273cbc92c2919470d1889f1edIhab Awad     *
45350e3506533478fa273cbc92c2919470d1889f1edIhab Awad     * @param conferenceableConnections The set of connections this connection can conference with.
45450e3506533478fa273cbc92c2919470d1889f1edIhab Awad     */
45550e3506533478fa273cbc92c2919470d1889f1edIhab Awad    public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
45650e3506533478fa273cbc92c2919470d1889f1edIhab Awad        clearConferenceableList();
45750e3506533478fa273cbc92c2919470d1889f1edIhab Awad        for (Connection c : conferenceableConnections) {
45850e3506533478fa273cbc92c2919470d1889f1edIhab Awad            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
45950e3506533478fa273cbc92c2919470d1889f1edIhab Awad            // small amount of items here.
46050e3506533478fa273cbc92c2919470d1889f1edIhab Awad            if (!mConferenceableConnections.contains(c)) {
46150e3506533478fa273cbc92c2919470d1889f1edIhab Awad                c.addConnectionListener(mConnectionDeathListener);
46250e3506533478fa273cbc92c2919470d1889f1edIhab Awad                mConferenceableConnections.add(c);
46350e3506533478fa273cbc92c2919470d1889f1edIhab Awad            }
46450e3506533478fa273cbc92c2919470d1889f1edIhab Awad        }
46550e3506533478fa273cbc92c2919470d1889f1edIhab Awad        fireOnConferenceableConnectionsChanged();
46650e3506533478fa273cbc92c2919470d1889f1edIhab Awad    }
46750e3506533478fa273cbc92c2919470d1889f1edIhab Awad
46807366813cdf3768dcd69a1f744023747564d654aRekha Kumar    /**
46907366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * Set the video state for the conference.
47032f24731604fd81289a39619bbc925b65184b505Yorke Lee     * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
47132f24731604fd81289a39619bbc925b65184b505Yorke Lee     * {@link VideoProfile#STATE_BIDIRECTIONAL},
47232f24731604fd81289a39619bbc925b65184b505Yorke Lee     * {@link VideoProfile#STATE_TX_ENABLED},
47332f24731604fd81289a39619bbc925b65184b505Yorke Lee     * {@link VideoProfile#STATE_RX_ENABLED}.
47407366813cdf3768dcd69a1f744023747564d654aRekha Kumar     *
47507366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * @param videoState The new video state.
47607366813cdf3768dcd69a1f744023747564d654aRekha Kumar     */
47707366813cdf3768dcd69a1f744023747564d654aRekha Kumar    public final void setVideoState(Connection c, int videoState) {
47807366813cdf3768dcd69a1f744023747564d654aRekha Kumar        Log.d(this, "setVideoState Conference: %s Connection: %s VideoState: %s",
47907366813cdf3768dcd69a1f744023747564d654aRekha Kumar                this, c, videoState);
48007366813cdf3768dcd69a1f744023747564d654aRekha Kumar        for (Listener l : mListeners) {
48107366813cdf3768dcd69a1f744023747564d654aRekha Kumar            l.onVideoStateChanged(this, videoState);
48207366813cdf3768dcd69a1f744023747564d654aRekha Kumar        }
48307366813cdf3768dcd69a1f744023747564d654aRekha Kumar    }
48407366813cdf3768dcd69a1f744023747564d654aRekha Kumar
48507366813cdf3768dcd69a1f744023747564d654aRekha Kumar    /**
48607366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * Sets the video connection provider.
48707366813cdf3768dcd69a1f744023747564d654aRekha Kumar     *
48807366813cdf3768dcd69a1f744023747564d654aRekha Kumar     * @param videoProvider The video provider.
48907366813cdf3768dcd69a1f744023747564d654aRekha Kumar     */
49007366813cdf3768dcd69a1f744023747564d654aRekha Kumar    public final void setVideoProvider(Connection c, Connection.VideoProvider videoProvider) {
49107366813cdf3768dcd69a1f744023747564d654aRekha Kumar        Log.d(this, "setVideoProvider Conference: %s Connection: %s VideoState: %s",
49207366813cdf3768dcd69a1f744023747564d654aRekha Kumar                this, c, videoProvider);
49307366813cdf3768dcd69a1f744023747564d654aRekha Kumar        for (Listener l : mListeners) {
49407366813cdf3768dcd69a1f744023747564d654aRekha Kumar            l.onVideoProviderChanged(this, videoProvider);
49507366813cdf3768dcd69a1f744023747564d654aRekha Kumar        }
49607366813cdf3768dcd69a1f744023747564d654aRekha Kumar    }
49707366813cdf3768dcd69a1f744023747564d654aRekha Kumar
49850e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private final void fireOnConferenceableConnectionsChanged() {
49950e3506533478fa273cbc92c2919470d1889f1edIhab Awad        for (Listener l : mListeners) {
50050e3506533478fa273cbc92c2919470d1889f1edIhab Awad            l.onConferenceableConnectionsChanged(this, getConferenceableConnections());
50150e3506533478fa273cbc92c2919470d1889f1edIhab Awad        }
50250e3506533478fa273cbc92c2919470d1889f1edIhab Awad    }
50350e3506533478fa273cbc92c2919470d1889f1edIhab Awad
50450e3506533478fa273cbc92c2919470d1889f1edIhab Awad    /**
50550e3506533478fa273cbc92c2919470d1889f1edIhab Awad     * Returns the connections with which this connection can be conferenced.
50650e3506533478fa273cbc92c2919470d1889f1edIhab Awad     */
50750e3506533478fa273cbc92c2919470d1889f1edIhab Awad    public final List<Connection> getConferenceableConnections() {
50850e3506533478fa273cbc92c2919470d1889f1edIhab Awad        return mUnmodifiableConferenceableConnections;
50950e3506533478fa273cbc92c2919470d1889f1edIhab Awad    }
51050e3506533478fa273cbc92c2919470d1889f1edIhab Awad
51150e3506533478fa273cbc92c2919470d1889f1edIhab Awad    /**
512ea38cca14964a5ee658899b0bafbc48017d556cdNancy Chen     * Tears down the conference object and any of its current connections.
513823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
514a48680427e022ab6eb73277faac6c57831ee6ff9Santos Cordon    public final void destroy() {
515823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        Log.d(this, "destroying conference : %s", this);
516823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        // Tear down the children.
5170159ac0cfe20e8f85ee4150e64d91392850f8a3fSantos Cordon        for (Connection connection : mChildConnections) {
518823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            Log.d(this, "removing connection %s", connection);
519823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            removeConnection(connection);
520823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
521823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
522823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        // If not yet disconnected, set the conference call as disconnected first.
523823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        if (mState != Connection.STATE_DISCONNECTED) {
524823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            Log.d(this, "setting to disconnected");
5257f3d41fd124dd7c4a8b72c1d48df08a8ee7209ecAndrew Lee            setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
526823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
527823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
528823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        // ...and notify.
529823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        for (Listener l : mListeners) {
530823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            l.onDestroyed(this);
531823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
532823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
533823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
534823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
535823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Add a listener to be notified of a state change.
536823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
537823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @param listener The new listener.
538823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @return This conference.
539823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @hide
540823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
541823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final Conference addListener(Listener listener) {
542823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        mListeners.add(listener);
543823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        return this;
544823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
545823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
546823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    /**
547823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * Removes the specified listener.
548823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     *
549823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @param listener The listener to remove.
550823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @return This conference.
551823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     * @hide
552823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon     */
553823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    public final Conference removeListener(Listener listener) {
554823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        mListeners.remove(listener);
555823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        return this;
556823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
557823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
558a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    /**
5594a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn     * Retrieves the primary connection associated with the conference.  The primary connection is
5604a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn     * the connection from which the conference will retrieve its current state.
5614a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn     *
5624a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn     * @return The primary connection.
5635d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @hide
5644a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn     */
5655d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    @SystemApi
5664055d648993c35be19487f7ab82e337197e25297Santos Cordon    public Connection getPrimaryConnection() {
5674a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn        if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) {
5684a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn            return null;
5694a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn        }
5704a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn        return mUnmodifiableChildConnections.get(0);
5714a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn    }
5724a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn
5734a57b9b59b74c97e559a301af0add13cd4c3331cTyler Gunn    /**
5745d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @hide
5755d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @deprecated Use {@link #setConnectionTime}.
5765d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     */
5775d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    @Deprecated
5785d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    @SystemApi
5795d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    public final void setConnectTimeMillis(long connectTimeMillis) {
5805d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon        setConnectionTime(connectTimeMillis);
5815d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    }
5825d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon
5835d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    /**
5845d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * Sets the connection start time of the {@code Conference}.
585cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     *
5865d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @param connectionTimeMillis The connection time, in milliseconds.
587cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     */
5885d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    public final void setConnectionTime(long connectionTimeMillis) {
5895d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon        mConnectTimeMillis = connectionTimeMillis;
590cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    }
591cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn
592cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    /**
5935d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @hide
5945d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @deprecated Use {@link #getConnectionTime}.
5955d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     */
5965d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    @Deprecated
5975d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    @SystemApi
5985d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    public final long getConnectTimeMillis() {
5995d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon        return getConnectionTime();
6005d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    }
6015d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon
6025d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    /**
6035d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * Retrieves the connection start time of the {@code Conference}, if specified.  A value of
604cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     * {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time
605cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     * of the conference.
606cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     *
6075d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon     * @return The time at which the {@code Conference} was connected.
608cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn     */
6095d2e4f20fee033a22fbadffb291c4e47f35b7633Santos Cordon    public final long getConnectionTime() {
610cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn        return mConnectTimeMillis;
611cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    }
612cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn
613cd5d33c89f25b3bfe8989d55f05702d0970c13b4Tyler Gunn    /**
614a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * Inform this Conference that the state of its audio output has been changed externally.
615a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     *
616a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * @param state The new audio state.
617a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     * @hide
618a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee     */
6194af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee    final void setCallAudioState(CallAudioState state) {
6204af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        Log.d(this, "setCallAudioState %s", state);
6214af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        mCallAudioState = state;
6224af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        onAudioStateChanged(getAudioState());
6234af5935c71f1e31ef1aec27661c4ef60545a0924Yorke Lee        onCallAudioStateChanged(state);
624a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee    }
625a0d3ca9746143d669fe9384babb9e1b9fca33dcfYorke Lee
626823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    private void setState(int newState) {
627823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        if (newState != Connection.STATE_ACTIVE &&
628823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                newState != Connection.STATE_HOLDING &&
629823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                newState != Connection.STATE_DISCONNECTED) {
630823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            Log.w(this, "Unsupported state transition for Conference call.",
631823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                    Connection.stateToString(newState));
632823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            return;
633823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
634823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon
635823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        if (mState != newState) {
636823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            int oldState = mState;
637823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            mState = newState;
638823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            for (Listener l : mListeners) {
639823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon                l.onStateChanged(this, oldState, newState);
640823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon            }
641823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon        }
642823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon    }
64350e3506533478fa273cbc92c2919470d1889f1edIhab Awad
64450e3506533478fa273cbc92c2919470d1889f1edIhab Awad    private final void clearConferenceableList() {
64550e3506533478fa273cbc92c2919470d1889f1edIhab Awad        for (Connection c : mConferenceableConnections) {
64650e3506533478fa273cbc92c2919470d1889f1edIhab Awad            c.removeConnectionListener(mConnectionDeathListener);
64750e3506533478fa273cbc92c2919470d1889f1edIhab Awad        }
64850e3506533478fa273cbc92c2919470d1889f1edIhab Awad        mConferenceableConnections.clear();
64950e3506533478fa273cbc92c2919470d1889f1edIhab Awad    }
65007366813cdf3768dcd69a1f744023747564d654aRekha Kumar
65107366813cdf3768dcd69a1f744023747564d654aRekha Kumar    @Override
65207366813cdf3768dcd69a1f744023747564d654aRekha Kumar    public String toString() {
65307366813cdf3768dcd69a1f744023747564d654aRekha Kumar        return String.format(Locale.US,
65407366813cdf3768dcd69a1f744023747564d654aRekha Kumar                "[State: %s,Capabilites: %s, VideoState: %s, VideoProvider: %s, ThisObject %s]",
65507366813cdf3768dcd69a1f744023747564d654aRekha Kumar                Connection.stateToString(mState),
65607366813cdf3768dcd69a1f744023747564d654aRekha Kumar                Call.Details.capabilitiesToString(mConnectionCapabilities),
65707366813cdf3768dcd69a1f744023747564d654aRekha Kumar                getVideoState(),
65807366813cdf3768dcd69a1f744023747564d654aRekha Kumar                getVideoProvider(),
65907366813cdf3768dcd69a1f744023747564d654aRekha Kumar                super.toString());
66007366813cdf3768dcd69a1f744023747564d654aRekha Kumar    }
6610f51da328d11f8709d99890a61d6b4021a2207a5Andrew Lee
662edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    /**
663edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     * Sets the label and icon status to display in the InCall UI.
664edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     *
665edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     * @param statusHints The status label and icon to set.
666edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     */
667edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    public final void setStatusHints(StatusHints statusHints) {
668edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee        mStatusHints = statusHints;
669edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee        for (Listener l : mListeners) {
670edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee            l.onStatusHintsChanged(this, statusHints);
671edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee        }
672edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    }
673edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee
674edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    /**
675edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     * @return The status hints for this conference.
676edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee     */
677edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    public final StatusHints getStatusHints() {
678edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee        return mStatusHints;
679edc625f52e5db5d0cb3d60387218f8f8365167f7Andrew Lee    }
6806b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon
6816b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    /**
682dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Replaces all the extras associated with this {@code Conference}.
683dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * <p>
684dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * New or existing keys are replaced in the {@code Conference} extras.  Keys which are no longer
685dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * in the new extras, but were present the last time {@code setExtras} was called are removed.
686dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * <p>
6879c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Alternatively you may use the {@link #putExtras(Bundle)}, and
6889c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * {@link #removeExtras(String...)} methods to modify the extras.
6899c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * <p>
690dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
6919c0eb0bd46dac113c39804335feeee7878a624ffTyler Gunn     * Keys should be fully qualified (e.g., com.example.extras.MY_EXTRA) to avoid conflicts.
6926b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon     *
693dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param extras The extras associated with this {@code Conference}.
6946b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon     */
6956b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    public final void setExtras(@Nullable Bundle extras) {
6964fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        // Keeping putExtras and removeExtras in the same lock so that this operation happens as a
6974fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        // block instead of letting other threads put/remove while this method is running.
6984fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        synchronized (mExtrasLock) {
6994fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            // Add/replace any new or changed extras values.
7004fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            putExtras(extras);
7014fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            // If we have used "setExtras" in the past, compare the key set from the last invocation
7024fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            // to the current one and remove any keys that went away.
7034fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (mPreviousExtraKeys != null) {
7044fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                List<String> toRemove = new ArrayList<String>();
7054fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                for (String oldKey : mPreviousExtraKeys) {
7064fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                    if (extras == null || !extras.containsKey(oldKey)) {
7074fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                        toRemove.add(oldKey);
7084fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                    }
709dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn                }
710dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
7114fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                if (!toRemove.isEmpty()) {
7124fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                    removeExtras(toRemove);
7134fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                }
714dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            }
715dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
7164fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            // Track the keys the last time set called setExtras.  This way, the next time setExtras
7174fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            // is called we can see if the caller has removed any extras values.
7184fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (mPreviousExtraKeys == null) {
7194fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                mPreviousExtraKeys = new ArraySet<String>();
7204fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            }
7214fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            mPreviousExtraKeys.clear();
7224fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (extras != null) {
7234fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                mPreviousExtraKeys.addAll(extras.keySet());
7244fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            }
725a8fb8aba7ce464a9d42f4e4ac42f76aa90d050e9Tyler Gunn        }
726dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
727dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
728dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
729dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Adds some extras to this {@link Conference}.  Existing keys are replaced and new ones are
730dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * added.
731dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * <p>
732dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * No assumptions should be made as to how an In-Call UI or service will handle these extras.
733dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Keys should be fully qualified (e.g., com.example.MY_EXTRA) to avoid conflicts.
734dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
735dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param extras The extras to add.
736dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
737dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public final void putExtras(@NonNull Bundle extras) {
738dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        if (extras == null) {
739dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            return;
740dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
741dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
7424fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        // Creating a Bundle clone so we don't have to synchronize on mExtrasLock while calling
7434fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        // onExtrasChanged.
7444fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        Bundle listenersBundle;
7454fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        synchronized (mExtrasLock) {
7464fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (mExtras == null) {
7474fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                mExtras = new Bundle();
7484fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            }
7494fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            mExtras.putAll(extras);
7504fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            listenersBundle = new Bundle(mExtras);
751dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
752dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
7536b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon        for (Listener l : mListeners) {
7544fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            l.onExtrasChanged(this, new Bundle(listenersBundle));
7556b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon        }
7566b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    }
7576b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon
7586b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    /**
759dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Adds a boolean extra to this {@link Conference}.
760dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
761dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param key The extra key.
762dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param value The value.
763dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @hide
764dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
765dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public final void putExtra(String key, boolean value) {
766dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        Bundle newExtras = new Bundle();
767dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        newExtras.putBoolean(key, value);
768dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        putExtras(newExtras);
769dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
770dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
771dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
772dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Adds an integer extra to this {@link Conference}.
773dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
774dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param key The extra key.
775dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param value The value.
776dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @hide
777dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
778dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public final void putExtra(String key, int value) {
779dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        Bundle newExtras = new Bundle();
780dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        newExtras.putInt(key, value);
781dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        putExtras(newExtras);
782dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
783dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
784dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
785dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Adds a string extra to this {@link Conference}.
786dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
787dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param key The extra key.
788dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param value The value.
789dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @hide
790dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
791dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public final void putExtra(String key, String value) {
792dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        Bundle newExtras = new Bundle();
793dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        newExtras.putString(key, value);
794dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        putExtras(newExtras);
795dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
796dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
797dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
798071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     * Removes extras from this {@link Conference}.
799dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
800071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     * @param keys The keys of the extras to remove.
801dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
802dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public final void removeExtras(List<String> keys) {
803dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        if (keys == null || keys.isEmpty()) {
804dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            return;
805dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
806dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
8074fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        synchronized (mExtrasLock) {
8084fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (mExtras != null) {
8094fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                for (String key : keys) {
8104fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                    mExtras.remove(key);
8114fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                }
812dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn            }
813dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
814dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
8154fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        List<String> unmodifiableKeys = Collections.unmodifiableList(keys);
816dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        for (Listener l : mListeners) {
8174fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            l.onExtrasRemoved(this, unmodifiableKeys);
818dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn        }
819dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
820dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
821dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
822071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     * Removes extras from this {@link Conference}.
823071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     *
824071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     * @param keys The keys of the extras to remove.
825071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn     */
826071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn    public final void removeExtras(String ... keys) {
827071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn        removeExtras(Arrays.asList(keys));
828071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn    }
829071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn
830071be6f42bfc18e2cc8b3f8ddbcf3d2f33ebd6baTyler Gunn    /**
831dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Returns the extras associated with this conference.
8322cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * <p>
8332cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * Extras should be updated using {@link #putExtras(Bundle)} and {@link #removeExtras(List)}.
8342cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * <p>
8352cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * Telecom or an {@link InCallService} can also update the extras via
8362cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * {@link android.telecom.Call#putExtras(Bundle)}, and
8372cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * {@link Call#removeExtras(List)}.
8382cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * <p>
8392cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * The conference is notified of changes to the extras made by Telecom or an
8402cbe2b5816c3a6b55144a3a731cab894761c780dTyler Gunn     * {@link InCallService} by {@link #onExtrasChanged(Bundle)}.
841dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
842dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @return The extras associated with this connection.
8436b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon     */
8446b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    public final Bundle getExtras() {
8456b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon        return mExtras;
8466b7f955c2d9b231660b8c54f8ef8e8e6ad802625Santos Cordon    }
847dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
848dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
849dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Notifies this {@link Conference} of a change to the extras made outside the
850dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * {@link ConnectionService}.
851dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * <p>
852dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * These extras changes can originate from Telecom itself, or from an {@link InCallService} via
853dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * {@link android.telecom.Call#putExtras(Bundle)}, and
854dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * {@link Call#removeExtras(List)}.
855dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
856dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param extras The new extras bundle.
857dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
858dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    public void onExtrasChanged(Bundle extras) {}
859dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn
860dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    /**
861dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * Handles a change to extras received from Telecom.
862dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     *
863dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @param extras The new extras.
864dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     * @hide
865dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn     */
866dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    final void handleExtrasChanged(Bundle extras) {
8674fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        Bundle b = null;
8684fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        synchronized (mExtrasLock) {
8694fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            mExtras = extras;
8704fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            if (mExtras != null) {
8714fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger                b = new Bundle(mExtras);
8724fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger            }
8734fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        }
8744fa6a01898be85999e12b62bb52debb838e1bd0cBrad Ebinger        onExtrasChanged(b);
875dee56a8a79f9daa1e597f5d4f399d3a5feedcac4Tyler Gunn    }
876823fd3c79dd4f762bbc778e0ce9e2204b6d3d454Santos Cordon}
877