Connection.java revision 8a2b1199a6db0c6f2493e96e25ec1d89e3f62769
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/*
2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2014 The Android Open Source Project
3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License.
6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at
7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber *
10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software
11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and
14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License.
15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */
16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huberpackage android.telecom;
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport com.android.internal.telecom.IVideoCallback;
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport com.android.internal.telecom.IVideoProvider;
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hungimport android.annotation.SystemApi;
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.net.Uri;
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huberimport android.os.Handler;
255bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.os.IBinder;
26a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wuimport android.os.Message;
2735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangimport android.os.RemoteException;
285833b6aad2c46ba516bdc8262f4fc4667e8018edWei Jiaimport android.view.Surface;
29bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
30bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jiaimport java.util.ArrayList;
313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhangimport java.util.Collections;
32a3725d7b0cb79ddb49f81cba00a0164d8e645acdLajos Molnarimport java.util.List;
33dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnarimport java.util.Set;
34095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnarimport java.util.concurrent.ConcurrentHashMap;
35095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/**
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Represents a connection to a remote endpoint that carries voice traffic.
38a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * <p>
39a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * Implementations create a custom subclass of {@code Connection} and return it to the framework
40a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * as the return value of
41a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * {@link ConnectionService#onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)}
42a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * or
43a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
44a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * Implementations are then responsible for updating the state of the {@code Connection}, and
45a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
46a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * longer used and associated resources may be recovered.
47a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung * @hide
48a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung */
49a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung@SystemApi
50288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hungpublic abstract class Connection implements IConferenceable {
51288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung
52288da02b1f074f9f3c191f1838f135d4633b3d34Andy Hung    public static final int STATE_INITIALIZING = 0;
53179652ee2a508361df1aa18e99000373886f0816Andy Hung
54179652ee2a508361df1aa18e99000373886f0816Andy Hung    public static final int STATE_NEW = 1;
55179652ee2a508361df1aa18e99000373886f0816Andy Hung
56a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    public static final int STATE_RINGING = 2;
57a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
58a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    public static final int STATE_DIALING = 3;
59a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
60a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    public static final int STATE_ACTIVE = 4;
61a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
62a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    public static final int STATE_HOLDING = 5;
63179652ee2a508361df1aa18e99000373886f0816Andy Hung
64179652ee2a508361df1aa18e99000373886f0816Andy Hung    public static final int STATE_DISCONNECTED = 6;
65179652ee2a508361df1aa18e99000373886f0816Andy Hung
66179652ee2a508361df1aa18e99000373886f0816Andy Hung    /** Connection can currently be put on hold or unheld. */
67179652ee2a508361df1aa18e99000373886f0816Andy Hung    public static final int CAPABILITY_HOLD = 0x00000001;
68f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu
69f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    /** Connection supports the hold feature. */
70a5d316fd802cfc92954527f27e6f32206a896113Eric Laurent    public static final int CAPABILITY_SUPPORT_HOLD = 0x00000002;
71f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu
7212b6265f1d4be368957f91104d5210cf604ac4ccWei Jia    /**
7312b6265f1d4be368957f91104d5210cf604ac4ccWei Jia     * Connections within a conference can be merged. A {@link ConnectionService} has the option to
7412b6265f1d4be368957f91104d5210cf604ac4ccWei Jia     * add a {@link Conference} before the child {@link Connection}s are merged. This is how
75714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber     * CDMA-based {@link Connection}s are implemented. For these unmerged {@link Conference}s, this
76f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     * capability allows a merge button to be shown while the conference is in the foreground
77f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     * of the in-call UI.
78f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     * <p>
79f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     * This is only intended for use by a {@link Conference}.
80f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     */
81f0e83644637bd05852c244df481f21a0d435ff66Andy Hung    public static final int CAPABILITY_MERGE_CONFERENCE = 0x00000004;
82f0e83644637bd05852c244df481f21a0d435ff66Andy Hung
83f0e83644637bd05852c244df481f21a0d435ff66Andy Hung    /**
84f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     * Connections within a conference can be swapped between foreground and background.
85714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber     * See {@link #CAPABILITY_MERGE_CONFERENCE} for additional information.
86714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber     * <p>
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * This is only intended for use by a {@link Conference}.
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
89d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    public static final int CAPABILITY_SWAP_CONFERENCE = 0x00000008;
90d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
93d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber     */
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public static final int CAPABILITY_UNUSED = 0x00000010;
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /** Connection supports responding via text option. */
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public static final int CAPABILITY_RESPOND_VIA_TEXT = 0x00000020;
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997b15cb33847e6282ea8352c98894683b796127f3Wei Jia    /** Connection can be muted. */
1007b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public static final int CAPABILITY_MUTE = 0x00000040;
1017c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia
1023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    /**
103a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu     * Connection supports conference management. This capability only applies to
104eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu     * {@link Conference}s which can have {@link Connection}s as children.
105f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar     */
106a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    public static final int CAPABILITY_MANAGE_CONFERENCE = 0x00000080;
107bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber
108bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber    /**
1097137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang     * Local device supports video telephony.
1107137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang     * @hide
111bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber     */
112714aa7b7c52ce07d5fb44870c0853b4d8e5a758eAndreas Huber    public static final int CAPABILITY_SUPPORTS_VT_LOCAL = 0x00000100;
113b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung
11409e0c3646362d29c78bc26c8b23b7a753c412e6cAndy Hung    /**
115f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong     * Remote device supports video telephony.
116cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     * @hide
117cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     */
118b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung    public static final int CAPABILITY_SUPPORTS_VT_REMOTE = 0x00000200;
1192995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia
120f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    /**
121faeb0f291330134dc4468359a36e099aae508449Ronghua Wu     * Connection is using high definition audio.
122d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar     * @hide
123f0e83644637bd05852c244df481f21a0d435ff66Andy Hung     */
124d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    public static final int CAPABILITY_HIGH_DEF_AUDIO = 0x00000400;
12535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
126a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    /**
12735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang     * Connection is using voice over WIFI.
1287b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * @hide
1293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     */
1303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public static final int CAPABILITY_VoWIFI = 0x00000800;
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Connection is able to be separated from its parent {@code Conference}, if any.
134bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
135bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public static final int CAPABILITY_SEPARATE_FROM_CONFERENCE = 0x00001000;
136bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
137bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
138bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * Connection is able to be individually disconnected when in a {@code Conference}.
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 0x00002000;
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Whether the call is a generic conference, where we do not know the precise state of
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * participants in the conference (eg. on CDMA).
1451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar     *
1467b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * @hide
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
1482d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    public static final int CAPABILITY_GENERIC_CONFERENCE = 0x00004000;
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Flag controlling whether PII is emitted into the logs
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private static final boolean PII_DEBUG = Log.isLoggable(android.util.Log.DEBUG);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Whether the given capabilities support the specified capability.
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
1561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar     * @param capabilities A capability bit field.
1577b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * @param capability The capability to check capabilities for.
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @return Whether the specified capability is supported.
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public static boolean can(int capabilities, int capability) {
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return (capabilities & capability) != 0;
1633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
1643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
1653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    /**
1663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * Whether the capabilities of this {@code Connection} supports the specified capability.
1673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     *
1683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @param capability The capability to check capabilities for.
1693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @return Whether the specified capability is supported.
1703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @hide
1713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     */
1723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public boolean can(int capability) {
1733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        return can(mConnectionCapabilities, capability);
1743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
1753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
1763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    /**
1773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * Removes the specified capability from the set of capabilities of this {@code Connection}.
1783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     *
1793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @param capability The capability to remove from the set.
1803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @hide
1813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     */
1823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public void removeCapability(int capability) {
1833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        mConnectionCapabilities &= ~capability;
1843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
1853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
18627ea08e3811dc8057685258af52a7d40474eba16Wei Jia    /**
1873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * Adds the specified capability to the set of capabilities of this {@code Connection}.
1883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     *
1893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @param capability The capability to add to the set.
1903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     * @hide
1913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar     */
1923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public void addCapability(int capability) {
1933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        mConnectionCapabilities |= capability;
1943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
1953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
1963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
1973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public static String capabilitiesToString(int capabilities) {
1983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        StringBuilder builder = new StringBuilder();
1993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        builder.append("[Capabilities:");
2003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_HOLD)) {
2013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_HOLD");
2023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2033a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_SUPPORT_HOLD)) {
2043a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_SUPPORT_HOLD");
2053a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2063a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_MERGE_CONFERENCE)) {
2073a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_MERGE_CONFERENCE");
2083a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2093a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_SWAP_CONFERENCE)) {
2103a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_SWAP_CONFERENCE");
2113a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
21227ea08e3811dc8057685258af52a7d40474eba16Wei Jia        if (can(capabilities, CAPABILITY_RESPOND_VIA_TEXT)) {
2133a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_RESPOND_VIA_TEXT");
2143a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2153a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_MUTE)) {
2163a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_MUTE");
2173a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2183a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_MANAGE_CONFERENCE)) {
2193a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_MANAGE_CONFERENCE");
2203a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2213a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_SUPPORTS_VT_LOCAL)) {
2223a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_SUPPORTS_VT_LOCAL");
2233a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2243a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_SUPPORTS_VT_REMOTE)) {
2253a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_SUPPORTS_VT_REMOTE");
2263a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2273a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_HIGH_DEF_AUDIO)) {
2283a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_HIGH_DEF_AUDIO");
2293a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2303a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_VoWIFI)) {
2313a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_VoWIFI");
2323a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2333a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        if (can(capabilities, CAPABILITY_GENERIC_CONFERENCE)) {
2343a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            builder.append(" CAPABILITY_GENERIC_CONFERENCE");
2353a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
2363a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        builder.append("]");
2373a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        return builder.toString();
2383a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
2393a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
2403a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    /** @hide */
2413a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public abstract static class Listener {
2423a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onStateChanged(Connection c, int state) {}
2433a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
2443a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onCallerDisplayNameChanged(
2453a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                Connection c, String callerDisplayName, int presentation) {}
2463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onVideoStateChanged(Connection c, int videoState) {}
2473a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onDisconnected(Connection c, DisconnectCause disconnectCause) {}
2483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onPostDialWait(Connection c, String remaining) {}
2493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onPostDialChar(Connection c, char nextChar) {}
2503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onRingbackRequested(Connection c, boolean ringback) {}
2513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onDestroyed(Connection c) {}
2523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
2533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onVideoProviderChanged(
2543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                Connection c, VideoProvider videoProvider) {}
2553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
2563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onStatusHintsChanged(Connection c, StatusHints statusHints) {}
2573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onConferenceablesChanged(
2583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                Connection c, List<IConferenceable> conferenceables) {}
2593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onConferenceChanged(Connection c, Conference conference) {}
2603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        /** @hide */
2613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onConferenceParticipantsChanged(Connection c,
2623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                List<ConferenceParticipant> participants) {}
2633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void onConferenceStarted() {}
2643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    }
2653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
2663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    /** @hide */
2673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar    public static abstract class VideoProvider {
2689816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia
2699816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        /**
2707137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang         * Video is not being received (no protocol pause was issued).
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
2727b15cb33847e6282ea8352c98894683b796127f3Wei Jia        public static final int SESSION_EVENT_RX_PAUSE = 1;
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        /**
2753b0cd26dbb0ce37d220db9ff0fa8172a7ef1c5cbWei Jia         * Video reception has resumed after a SESSION_EVENT_RX_PAUSE.
2767b15cb33847e6282ea8352c98894683b796127f3Wei Jia         */
2777b15cb33847e6282ea8352c98894683b796127f3Wei Jia        public static final int SESSION_EVENT_RX_RESUME = 2;
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        /**
2807b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Video transmission has begun. This occurs after a negotiated start of video transmission
2817b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * when the underlying protocol has actually begun transmitting video to the remote party.
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
2837b15cb33847e6282ea8352c98894683b796127f3Wei Jia        public static final int SESSION_EVENT_TX_START = 3;
2847b15cb33847e6282ea8352c98894683b796127f3Wei Jia
2857b15cb33847e6282ea8352c98894683b796127f3Wei Jia        /**
2867b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Video transmission has stopped. This occurs after a negotiated stop of video transmission
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * when the underlying protocol has actually stopped transmitting video to the remote party.
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
2891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        public static final int SESSION_EVENT_TX_STOP = 4;
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        /**
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * A camera failure has occurred for the selected camera.  The In-Call UI can use this as a
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * cue to inform the user the camera is not available.
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
29528a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia        public static final int SESSION_EVENT_CAMERA_FAILURE = 5;
29628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia
29728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia        /**
2981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar         * Issued after {@code SESSION_EVENT_CAMERA_FAILURE} when the camera is once again ready for
29928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia         * operation.  The In-Call UI can use this as a cue to inform the user that the camera has
30028a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia         * become available again.
301a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu         */
3021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        public static final int SESSION_EVENT_CAMERA_READY = 6;
303a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu
304a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu        /**
305b408222bd9479c291874b607acae1425d6154fe7Andreas Huber         * Session modify request was successful.
3061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar         */
307b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        public static final int SESSION_MODIFY_REQUEST_SUCCESS = 1;
308b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
309b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        /**
3101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar         * Session modify request failed.
311b408222bd9479c291874b607acae1425d6154fe7Andreas Huber         */
312b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        public static final int SESSION_MODIFY_REQUEST_FAIL = 2;
313c851b5de495169d7e9528644c2592746021bd968Lajos Molnar
3141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        /**
315c851b5de495169d7e9528644c2592746021bd968Lajos Molnar         * Session modify request ignored due to invalid parameters.
316c851b5de495169d7e9528644c2592746021bd968Lajos Molnar         */
317c851b5de495169d7e9528644c2592746021bd968Lajos Molnar        public static final int SESSION_MODIFY_REQUEST_INVALID = 3;
318c851b5de495169d7e9528644c2592746021bd968Lajos Molnar
3194ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_VIDEO_CALLBACK = 1;
3207b15cb33847e6282ea8352c98894683b796127f3Wei Jia        private static final int MSG_SET_CAMERA = 2;
3214ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_PREVIEW_SURFACE = 3;
3224ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_DISPLAY_SURFACE = 4;
3234ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_DEVICE_ORIENTATION = 5;
3244ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_ZOOM = 6;
3254ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SEND_SESSION_MODIFY_REQUEST = 7;
3264ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SEND_SESSION_MODIFY_RESPONSE = 8;
3274ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_REQUEST_CAMERA_CAPABILITIES = 9;
3284ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_REQUEST_CONNECTION_DATA_USAGE = 10;
3294ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private static final int MSG_SET_PAUSE_IMAGE = 11;
3304ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia
3314ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private final VideoProvider.VideoProviderHandler
3324ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                mMessageHandler = new VideoProvider.VideoProviderHandler();
3334ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private final VideoProvider.VideoProviderBinder mBinder;
3344ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private IVideoCallback mVideoCallback;
3354ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia
3364ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        /**
3374ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia         * Default handler used to consolidate binder method calls onto a single thread.
3384ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia         */
3394ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        private final class VideoProviderHandler extends Handler {
3404ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia            @Override
341d855a738735a3df8863b486f5d3b5e404cef15c1Wei Jia            public void handleMessage(Message msg) {
3424ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                switch (msg.what) {
3434ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                    case MSG_SET_VIDEO_CALLBACK:
3444ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                        mVideoCallback = IVideoCallback.Stub.asInterface((IBinder) msg.obj);
3454ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia                        break;
3469816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia                    case MSG_SET_CAMERA:
347a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSetCamera((String) msg.obj);
348a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
3497b15cb33847e6282ea8352c98894683b796127f3Wei Jia                    case MSG_SET_PREVIEW_SURFACE:
3507b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        onSetPreviewSurface((Surface) msg.obj);
3517b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        break;
352a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    case MSG_SET_DISPLAY_SURFACE:
353a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSetDisplaySurface((Surface) msg.obj);
3547b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        break;
355a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    case MSG_SET_DEVICE_ORIENTATION:
356a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSetDeviceOrientation(msg.arg1);
3577b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        break;
358a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    case MSG_SET_ZOOM:
359a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSetZoom((Float) msg.obj);
360a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
3617b15cb33847e6282ea8352c98894683b796127f3Wei Jia                    case MSG_SEND_SESSION_MODIFY_REQUEST:
3627b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        onSendSessionModifyRequest((VideoProfile) msg.obj);
3637b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        break;
3647b15cb33847e6282ea8352c98894683b796127f3Wei Jia                    case MSG_SEND_SESSION_MODIFY_RESPONSE:
365a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSendSessionModifyResponse((VideoProfile) msg.obj);
366a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
367a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    case MSG_REQUEST_CAMERA_CAPABILITIES:
3687b15cb33847e6282ea8352c98894683b796127f3Wei Jia                        onRequestCameraCapabilities();
369a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
370a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    case MSG_REQUEST_CONNECTION_DATA_USAGE:
371a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onRequestConnectionDataUsage();
372a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
3737b15cb33847e6282ea8352c98894683b796127f3Wei Jia                    case MSG_SET_PAUSE_IMAGE:
374a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        onSetPauseImage((String) msg.obj);
375a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                        break;
376a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu                    default:
377202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                        break;
3783b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                }
3793b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
3803b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        }
381202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
382202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung        /**
3831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar         * IVideoProvider stub implementation.
3843b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         */
3853b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        private final class VideoProviderBinder extends IVideoProvider.Stub {
3863b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void setVideoCallback(IBinder videoCallbackBinder) {
3873b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mMessageHandler.obtainMessage(
3883b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                        MSG_SET_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget();
3893b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
3903b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
3913b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void setCamera(String cameraId) {
392202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                mMessageHandler.obtainMessage(MSG_SET_CAMERA, cameraId).sendToTarget();
393202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            }
394202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
395202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            public void setPreviewSurface(Surface surface) {
396202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                mMessageHandler.obtainMessage(MSG_SET_PREVIEW_SURFACE, surface).sendToTarget();
397202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            }
398202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung
399202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            public void setDisplaySurface(Surface surface) {
400202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                mMessageHandler.obtainMessage(MSG_SET_DISPLAY_SURFACE, surface).sendToTarget();
4013b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4023b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4033b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void setDeviceOrientation(int rotation) {
4041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                mMessageHandler.obtainMessage(MSG_SET_DEVICE_ORIENTATION, rotation).sendToTarget();
4053b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4063b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4073b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void setZoom(float value) {
4083b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mMessageHandler.obtainMessage(MSG_SET_ZOOM, value).sendToTarget();
4093b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            public void sendSessionModifyRequest(VideoProfile requestProfile) {
4123b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mMessageHandler.obtainMessage(
4133b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                        MSG_SEND_SESSION_MODIFY_REQUEST, requestProfile).sendToTarget();
4143b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4153b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4163b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void sendSessionModifyResponse(VideoProfile responseProfile) {
4173b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mMessageHandler.obtainMessage(
4183b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                        MSG_SEND_SESSION_MODIFY_RESPONSE, responseProfile).sendToTarget();
4193b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4203b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4213b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void requestCameraCapabilities() {
4223b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang                mMessageHandler.obtainMessage(MSG_REQUEST_CAMERA_CAPABILITIES).sendToTarget();
4233b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4243b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4253b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            public void requestCallDataUsage() {
426202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget();
4273b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4283b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
429202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung            public void setPauseImage(String uri) {
430202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung                mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
4313b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            }
4323f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        }
4333b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4343b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        public VideoProvider() {
4353b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            mBinder = new VideoProvider.VideoProviderBinder();
4363b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        }
4373b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4383b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        /**
4393b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         * Returns binder object which can be used across IPC methods.
4403b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         * @hide
4413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar         */
4423b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        public final IVideoProvider getInterface() {
4433b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang            return mBinder;
4443b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        }
4453b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang
4463b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang        /**
4473b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         * Sets the camera to be used for video recording in a video connection.
4483b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         *
4493b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         * @param cameraId The id of the camera.
4503b9eb1f8629c6264d924ab7043f80d824cdd39e2Chong Zhang         */
451bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        public abstract void onSetCamera(String cameraId);
452bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
453bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        /**
454bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia         * Sets the surface to be used for displaying a preview of what the user's camera is
455bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia         * currently capturing.  When video transmission is enabled, this is the video signal which
456bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia         * is sent to the remote device.
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param surface The surface.
4593ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia         */
4603ab25457385dceb07205fc8ead86d7fb9e307588Wei Jia        public abstract void onSetPreviewSurface(Surface surface);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627b15cb33847e6282ea8352c98894683b796127f3Wei Jia        /**
4637b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Sets the surface to be used for displaying the video received from the remote device.
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param surface The surface.
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
467078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        public abstract void onSetDisplaySurface(Surface surface);
468078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
469078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        /**
470078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * Sets the device orientation, in degrees.  Assumes that a standard portrait orientation of
471078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * the device is 0 degrees.
472078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         *
473078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * @param rotation The device orientation, in degrees.
474078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         */
475078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        public abstract void onSetDeviceOrientation(int rotation);
476078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
477078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        /**
478078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * Sets camera zoom ratio.
479078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         *
480d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia         * @param value The camera zoom ratio.
481d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia         */
482d9c2e9c81a6f75c4dd6818a3d5075a875d25a2d4Wei Jia        public abstract void onSetZoom(float value);
483078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
484078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        /**
485078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * Issues a request to modify the properties of the current session.  The request is
4867b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * sent to the remote device where it it handled by the In-Call UI.
487bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia         * Some examples of session modification requests: upgrade connection from audio to video,
488078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         * downgrade connection from video to audio, pause video.
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param requestProfile The requested connection video properties.
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        public abstract void onSendSessionModifyRequest(VideoProfile requestProfile);
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        /**te
4957b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Provides a response to a request to change the current connection session video
4967b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * properties.
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * This is in response to a request the InCall UI has received via the InCall UI.
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param responseProfile The response connection video properties.
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        public abstract void onSendSessionModifyResponse(VideoProfile responseProfile);
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        /**
5047b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Issues a request to the video provider to retrieve the camera capabilities.
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * Camera capabilities are reported back to the caller via the In-Call UI.
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        public abstract void onRequestCameraCapabilities();
508d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar
509d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        /**
510d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar         * Issues a request to the video telephony framework to retrieve the cumulative data usage
5117b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * for the current connection.  Data usage is reported back to the caller via the
5127b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * InCall UI.
513d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar         */
514d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        public abstract void onRequestConnectionDataUsage();
515d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar
516d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        /**
5177b15cb33847e6282ea8352c98894683b796127f3Wei Jia         * Provides the video telephony framework with the URI of an image to be displayed to remote
518d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar         * devices when the video signal is paused.
519d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar         *
520d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar         * @param uri URI of image to display.
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        public abstract void onSetPauseImage(String uri);
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        /**
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * Invokes callback method defined in In-Call UI.
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param videoProfile The requested video connection profile.
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        public void receiveSessionModifyRequest(VideoProfile videoProfile) {
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mVideoCallback != null) {
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                try {
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mVideoCallback.receiveSessionModifyRequest(videoProfile);
5337c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia                } catch (RemoteException ignored) {
5347c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia                }
5357c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia            }
5367c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia        }
5377c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia
5387c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia        /**
5397c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         * Invokes callback method defined in In-Call UI.
5407c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         *
5417c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         * @param status Status of the session modify request.  Valid values are
5427c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         *               {@link VideoProvider#SESSION_MODIFY_REQUEST_SUCCESS},
5437c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         *               {@link VideoProvider#SESSION_MODIFY_REQUEST_FAIL},
5447c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         *               {@link VideoProvider#SESSION_MODIFY_REQUEST_INVALID}
5457c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia         * @param requestedProfile The original request which was sent to the remote device.
5463a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * @param responseProfile The actual profile changes made by the remote device.
5479816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia         */
5483a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void receiveSessionModifyResponse(int status,
5493a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                VideoProfile requestedProfile, VideoProfile responseProfile) {
5503a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            if (mVideoCallback != null) {
5513a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                try {
5523a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                    mVideoCallback.receiveSessionModifyResponse(
5533a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                            status, requestedProfile, responseProfile);
5543a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                } catch (RemoteException ignored) {
5553a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                }
5563a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            }
5573a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
5583a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
5593a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        /**
5603a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * Invokes callback method defined in In-Call UI.
5613a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         *
5623a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * Valid values are: {@link VideoProvider#SESSION_EVENT_RX_PAUSE},
5633a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * {@link VideoProvider#SESSION_EVENT_RX_RESUME},
5643a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * {@link VideoProvider#SESSION_EVENT_TX_START},
5653a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * {@link VideoProvider#SESSION_EVENT_TX_STOP}
5663a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         *
5673a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * @param event The event.
5683a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         */
5693a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void handleCallSessionEvent(int event) {
5703a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            if (mVideoCallback != null) {
5713a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                try {
5723a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                    mVideoCallback.handleCallSessionEvent(event);
5733a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                } catch (RemoteException ignored) {
5743a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                }
5753a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            }
5763a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
5773a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
5783a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        /**
5793a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * Invokes callback method defined in In-Call UI.
5803a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         *
5813a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * @param width  The updated peer video width.
5823a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * @param height The updated peer video height.
5833a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         */
5843a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void changePeerDimensions(int width, int height) {
5853a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            if (mVideoCallback != null) {
5863a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                try {
5873a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                    mVideoCallback.changePeerDimensions(width, height);
5883a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                } catch (RemoteException ignored) {
5893a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                }
5903a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            }
5913a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        }
5923a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar
5933a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        /**
5943a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * Invokes callback method defined in In-Call UI.
5953a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         *
5963a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         * @param dataUsage The updated data usage.
5973a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar         */
5983a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar        public void changeCallDataUsage(int dataUsage) {
5993a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar            if (mVideoCallback != null) {
6003a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                try {
6013a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                    mVideoCallback.changeCallDataUsage(dataUsage);
6023a474aa67fc31505740526dd249d96204c08bf79Lajos Molnar                } catch (RemoteException ignored) {
6039816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia                }
6049816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia            }
6059816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        }
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        /**
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * Invokes callback method defined in In-Call UI.
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         *
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         * @param cameraCapabilities The changed camera capabilities.
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         */
612bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
613bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia            if (mVideoCallback != null) {
614bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                try {
615bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                    mVideoCallback.changeCameraCapabilities(cameraCapabilities);
616bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                } catch (RemoteException ignored) {
617bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                }
618a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu            }
619a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu        }
620a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu    }
621a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu
622a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu    private final Listener mConnectionDeathListener = new Listener() {
623a10fd23bb9fcf16e778c639ea5638e2917dacd89Ronghua Wu        @Override
624b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        public void onDestroyed(Connection c) {
625b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            if (mConferenceables.remove(c)) {
626b408222bd9479c291874b607acae1425d6154fe7Andreas Huber                fireOnConferenceableConnectionsChanged();
627b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            }
628b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        }
629b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    };
630b408222bd9479c291874b607acae1425d6154fe7Andreas Huber
631b408222bd9479c291874b607acae1425d6154fe7Andreas Huber    private final Conference.Listener mConferenceDeathListener = new Conference.Listener() {
632b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        @Override
633b408222bd9479c291874b607acae1425d6154fe7Andreas Huber        public void onDestroyed(Conference c) {
634b408222bd9479c291874b607acae1425d6154fe7Andreas Huber            if (mConferenceables.remove(c)) {
635b408222bd9479c291874b607acae1425d6154fe7Andreas Huber                fireOnConferenceableConnectionsChanged();
636c851b5de495169d7e9528644c2592746021bd968Lajos Molnar            }
637c851b5de495169d7e9528644c2592746021bd968Lajos Molnar        }
638c851b5de495169d7e9528644c2592746021bd968Lajos Molnar    };
639c851b5de495169d7e9528644c2592746021bd968Lajos Molnar
640c851b5de495169d7e9528644c2592746021bd968Lajos Molnar    /**
641c851b5de495169d7e9528644c2592746021bd968Lajos Molnar     * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is
642c851b5de495169d7e9528644c2592746021bd968Lajos Molnar     * load factor before resizing, 1 means we only expect a single thread to
643c851b5de495169d7e9528644c2592746021bd968Lajos Molnar     * access the map so make only a single shard
644faeb0f291330134dc4468359a36e099aae508449Ronghua Wu     */
6453a2956d148d81194e297408179e84a47a309ef48Wei Jia    private final Set<Listener> mListeners = Collections.newSetFromMap(
646faeb0f291330134dc4468359a36e099aae508449Ronghua Wu            new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
6473a2956d148d81194e297408179e84a47a309ef48Wei Jia    private final List<IConferenceable> mConferenceables = new ArrayList<>();
6483a2956d148d81194e297408179e84a47a309ef48Wei Jia    private final List<IConferenceable> mUnmodifiableConferenceables =
6493a2956d148d81194e297408179e84a47a309ef48Wei Jia            Collections.unmodifiableList(mConferenceables);
650f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu
651f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private int mState = STATE_NEW;
652f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private AudioState mAudioState;
6537b15cb33847e6282ea8352c98894683b796127f3Wei Jia    private Uri mAddress;
654f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private int mAddressPresentation;
655f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private String mCallerDisplayName;
656f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private int mCallerDisplayNamePresentation;
6570852917279f79a94907e9906d0533ae409a30f6aRonghua Wu    private boolean mRingbackRequested = false;
658faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    private int mConnectionCapabilities;
65935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    private VideoProvider mVideoProvider;
660f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private boolean mAudioModeIsVoip;
661f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private StatusHints mStatusHints;
662f5b1db11734358d979a23a1ac4903872186ef60bRonghua Wu    private int mVideoState;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private DisconnectCause mDisconnectCause;
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private Conference mConference;
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private ConnectionService mConnectionService;
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Create a new Connection.
669bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
670005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung    public Connection() {}
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @return The address (e.g., phone number) to which this Connection is currently communicating.
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final Uri getAddress() {
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mAddress;
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
678b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung
679b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung    /**
680b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung     * @return The presentation requirements for the address.
681b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung     *         See {@link TelecomManager} for valid values.
682b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung     */
683b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung    public final int getAddressPresentation() {
684b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung        return mAddressPresentation;
685b03dcb34cd44d77e5fe1559e72323e03c59931dbAndy Hung    }
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    /**
6887b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * @return The caller display name (CNAP).
689078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     */
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final String getCallerDisplayName() {
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mCallerDisplayName;
6927b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
6937b15cb33847e6282ea8352c98894683b796127f3Wei Jia
6947b15cb33847e6282ea8352c98894683b796127f3Wei Jia    /**
695b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung     * @return The presentation requirements for the handle.
696cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     *         See {@link TelecomManager} for valid values.
697cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     */
6987b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public final int getCallerDisplayNamePresentation() {
6997b15cb33847e6282ea8352c98894683b796127f3Wei Jia        return mCallerDisplayNamePresentation;
7007b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
701b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung
702b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung    /**
703b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung     * @return The state of this Connection.
704b12ea0bbda453769584efcea69054b41d9b4c4c7Andy Hung     */
705cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar    public final int getState() {
706cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar        return mState;
707cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar    }
708cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar
709cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar    /**
710cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     * Returns the video state of the connection.
711cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
712cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     * {@link VideoProfile.VideoState#BIDIRECTIONAL},
713cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar     * {@link VideoProfile.VideoState#TX_ENABLED},
714bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * {@link VideoProfile.VideoState#RX_ENABLED}.
715bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *
716bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return The video state of the connection.
717bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @hide
718bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
719bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final int getVideoState() {
720bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return mVideoState;
721bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
722bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
723bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
724bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return The audio state of the connection, describing how its audio is currently
725bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *         being routed by the system. This is {@code null} if this Connection
726bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *         does not directly know about its audio state.
727bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
728bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final AudioState getAudioState() {
729bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return mAudioState;
730bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
731bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
732a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    /**
733bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return The conference that this connection is a part of.  Null if it is not part of any
734bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *         conference.
735bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
736bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final Conference getConference() {
737bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return mConference;
738bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
739a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
740faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    /**
741bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * Returns whether this connection is requesting that the system play a ringback tone
742bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * on its behalf.
743bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
744bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final boolean isRingbackRequested() {
745bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return mRingbackRequested;
746bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
747bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
748bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
749bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return True if the connection's audio mode is VOIP.
750bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
75185e48142f726770d3b65caa1f29d8b98f8d5db6bAndy Hung    public final boolean getAudioModeIsVoip() {
752bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return mAudioModeIsVoip;
753bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
754bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
755bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
756bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return The status hints for this connection.
757bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
7583e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu    public final StatusHints getStatusHints() {
759a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung        return mStatusHints;
760bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
761a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
762bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
763bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * Assign a listener to be notified of state changes.
764bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *
765bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @param l A listener.
766bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return This Connection.
767bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *
768bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @hide
7693e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu     */
7703e5efb37308aa1f54c2a72cd8a7a73d2d7921a90Ronghua Wu    public final Connection addConnectionListener(Listener l) {
771bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        mListeners.add(l);
772bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return this;
773a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    }
7747b15cb33847e6282ea8352c98894683b796127f3Wei Jia
775bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
776bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * Remove a previously assigned listener that was being notified of state changes.
777bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *
778bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @param l A Listener.
779bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return This Connection.
780bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     *
781bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @hide
782bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
783bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final Connection removeConnectionListener(Listener l) {
784bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        if (l != null) {
785bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia            mListeners.remove(l);
786bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        }
787bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        return this;
788bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
789bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
790bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
791bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     * @return The {@link DisconnectCause} for this connection.
792bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
793bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    public final DisconnectCause getDisconnectCause() {
7947b15cb33847e6282ea8352c98894683b796127f3Wei Jia        return mDisconnectCause;
7957b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
796bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia
797bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    /**
798f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar     * Inform this Connection that the state of its audio output has been changed externally.
799f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar     *
8009816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     * @param state The new audio state.
801c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia     * @hide
8027b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
8039816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    final void setAudioState(AudioState state) {
804f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar        checkImmutable();
805f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar        Log.d(this, "setAudioState %s", state);
806a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung        mAudioState = state;
807a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung        onAudioStateChanged(state);
808a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    }
809a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung
810a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung    /**
811a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung     * @param state An integer value of a {@code STATE_*} constant.
812a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung     * @return A string representation of the value.
813bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
8141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    public static String stateToString(int state) {
815a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung        switch (state) {
816a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_INITIALIZING:
817a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung                return "STATE_INITIALIZING";
818a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_NEW:
819a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung                return "STATE_NEW";
820a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_RINGING:
821a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung                return "STATE_RINGING";
822a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_DIALING:
823a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung                return "STATE_DIALING";
824a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_ACTIVE:
825a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung                return "STATE_ACTIVE";
826a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung            case STATE_HOLDING:
827bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                return "STATE_HOLDING";
828bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia            case STATE_DISCONNECTED:
829bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia                return "DISCONNECTED";
830bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia            default:
8319da0ce44f228408d73a4dea0be972c785095dcccChong Zhang                Log.wtf(Connection.class, "Unknown state %d", state);
8329da0ce44f228408d73a4dea0be972c785095dcccChong Zhang                return "UNKNOWN";
8339da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        }
8349da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    }
8359da0ce44f228408d73a4dea0be972c785095dcccChong Zhang
8369da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    /**
8379da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     * Returns the connection's capabilities, as a bit mask of the {@code CAPABILITY_*} constants.
8389da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     */
8399da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    public final int getConnectionCapabilities() {
8409da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        return mConnectionCapabilities;
8419da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    }
8429da0ce44f228408d73a4dea0be972c785095dcccChong Zhang
8439da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    /** @hide */
8449da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    @SystemApi @Deprecated public final int getCallCapabilities() {
8459da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        return getConnectionCapabilities();
8469da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    }
8479da0ce44f228408d73a4dea0be972c785095dcccChong Zhang
8489da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    /**
8499da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     * Sets the value of the {@link #getAddress()} property.
8509da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     *
8519da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     * @param address The new address.
8529da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     * @param presentation The presentation requirements for the address.
8539da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     *        See {@link TelecomManager} for valid values.
8549da0ce44f228408d73a4dea0be972c785095dcccChong Zhang     */
8559da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    public final void setAddress(Uri address, int presentation) {
8569da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        checkImmutable();
8579da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        Log.d(this, "setAddress %s", address);
858078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        mAddress = address;
85958d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung        mAddressPresentation = presentation;
86058d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung        for (Listener l : mListeners) {
86158d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung            l.onAddressChanged(this, address, presentation);
86258d315cae745aae2c87eb3e7cac2da5e25a57d4cAndy Hung        }
863230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia    }
864230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia
865230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia    /**
866230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     * Sets the caller display name (CNAP).
867230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     *
868230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     * @param callerDisplayName The new display name.
869230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     * @param presentation The presentation requirements for the handle.
870230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     *        See {@link TelecomManager} for valid values.
871230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     */
872230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia    public final void setCallerDisplayName(String callerDisplayName, int presentation) {
873078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        checkImmutable();
8742bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber        Log.d(this, "setCallerDisplayName %s", callerDisplayName);
8759da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        mCallerDisplayName = callerDisplayName;
8769da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        mCallerDisplayNamePresentation = presentation;
8779da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        for (Listener l : mListeners) {
8789da0ce44f228408d73a4dea0be972c785095dcccChong Zhang            l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
8799da0ce44f228408d73a4dea0be972c785095dcccChong Zhang        }
8809da0ce44f228408d73a4dea0be972c785095dcccChong Zhang    }
8819da0ce44f228408d73a4dea0be972c785095dcccChong Zhang
8822bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber    /**
8832bfdd428c56c7524d1a11979f200a1762866032dAndreas Huber     * Set the video state for the connection.
884078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
885230b188b2c2ed74aa017cb93f847e9a558feba95Wei Jia     * {@link VideoProfile.VideoState#BIDIRECTIONAL},
886078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     * {@link VideoProfile.VideoState#TX_ENABLED},
887078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     * {@link VideoProfile.VideoState#RX_ENABLED}.
888078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     *
889078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     * @param videoState The new video state.
890df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block     * @hide
891078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     */
8923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    public final void setVideoState(int videoState) {
893078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        checkImmutable();
894078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        Log.d(this, "setVideoState %d", videoState);
895078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        mVideoState = videoState;
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (Listener l : mListeners) {
897005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung            l.onVideoStateChanged(this, mVideoState);
8987d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        }
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    /**
902d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar     * Sets state to active (e.g., an ongoing connection where two or more parties can actively
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * communicate).
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
9055095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu    public final void setActive() {
9065095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu        checkImmutable();
90706ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar        setRingbackRequested(false);
9085095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu        setState(STATE_ACTIVE);
9095095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu    }
9102995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Sets state to ringing (e.g., an inbound ringing connection).
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
9143491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung    public final void setRinging() {
9153491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung        checkImmutable();
9163491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung        setState(STATE_RINGING);
9173491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung    }
9183491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung
9193491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung    /**
9203491232a7c0d953fa021f6a81baee64c44f364f3Andy Hung     * Sets state to initializing (this Connection is not yet ready to be used).
921078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     */
922c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    public final void setInitializing() {
923c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        checkImmutable();
92481636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang        setState(STATE_INITIALIZING);
92581636761bead03f13b4ed9320a7f25ce1354f1aeChong Zhang    }
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
928a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung     * Sets state to initialized (the Connection has been set up and is now ready to be used).
929a0b397133bfce8a62198dfac9a2b970c8b20bcc5Andy Hung     */
930eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    public final void setInitialized() {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        checkImmutable();
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        setState(STATE_NEW);
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9357d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia    /**
9367d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia     * Sets state to dialing (e.g., dialing an outbound connection).
937a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     */
938202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung    public final void setDialing() {
9397d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        checkImmutable();
940df809479696725faf5d3424b11fa8a07bd94cb5eWei Jia        setState(STATE_DIALING);
9417d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia    }
9427d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia
9437665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu    /**
9447665f5886093e1aee07a5266b8c384e5d1186f34Ronghua Wu     * Sets state to be on hold.
945faeb0f291330134dc4468359a36e099aae508449Ronghua Wu     */
9467d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia    public final void setOnHold() {
947202bce11a7f66f27e6dbb6d154ddc123aa62513dAndy Hung        checkImmutable();
948a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung        setState(STATE_HOLDING);
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
950a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Sets the video connection provider.
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @param videoProvider The video provider.
9549b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent     * @hide
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final void setVideoProvider(VideoProvider videoProvider) {
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        checkImmutable();
958a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung        mVideoProvider = videoProvider;
959078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        for (Listener l : mListeners) {
960cbaffcffee6418d678806e63097c19fe26d48fe0Lajos Molnar            l.onVideoProviderChanged(this, videoProvider);
9617b15cb33847e6282ea8352c98894683b796127f3Wei Jia        }
9627b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
963d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia
964d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia    /** @hide */
965d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia    public final VideoProvider getVideoProvider() {
966d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia        return mVideoProvider;
967d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia    }
968d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia
969d005c5ddb4842369979df7b76f1d0f5f1380fcd9Wei Jia    /**
9707b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Sets state to disconnected.
9717b15cb33847e6282ea8352c98894683b796127f3Wei Jia     *
97243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber     * @param disconnectCause The reason for the disconnection, as specified by
973a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     *         {@link DisconnectCause}.
974a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     */
975a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung    public final void setDisconnected(DisconnectCause disconnectCause) {
9767d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        checkImmutable();
9777d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        mDisconnectCause = disconnectCause;
978a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung        setState(STATE_DISCONNECTED);
979a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung        Log.d(this, "Disconnected with cause %s", disconnectCause);
9807d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        for (Listener l : mListeners) {
9817d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia            l.onDisconnected(this, disconnectCause);
9827d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia        }
983a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung    }
984a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung
985a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung    /**
986a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     * Informs listeners that this {@code Connection} is in a post-dial wait state. This is done
987a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     * when (a) the {@code Connection} is issuing a DTMF sequence; (b) it has encountered a "wait"
988a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     * character; and (c) it wishes to inform the In-Call app that it is waiting for the end-user
9897d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia     * to send an {@link #onPostDialContinue(boolean)} signal.
990a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     *
991a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     * @param remaining The DTMF character sequence remaining to be emitted once the
9927d3f4df0a77e052a7d37de9268aff8c2ed0909ccWei Jia     *         {@link #onPostDialContinue(boolean)} is received, including any "wait" characters
993a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     *         that remaining sequence may contain.
994a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung     */
995a31335a4ec96ba351f25f3b26fa79a78c2723a13Andy Hung    public final void setPostDialWait(String remaining) {
996f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar        checkImmutable();
997005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung        for (Listener l : mListeners) {
998005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung            l.onPostDialWait(this, remaining);
999005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung        }
1000005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung    }
1001005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung
1002005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung    /**
1003005e9d0300fc326a076ec17b7fa6dd4f51568f55Andy Hung     * Informs listeners that this {@code Connection} has processed a character in the post-dial
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * started state. This is done when (a) the {@code Connection} is issuing a DTMF sequence;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * (b) it has encountered a "wait" character; and (c) it wishes to signal Telecom to play
10069816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     * the corresponding DTMF tone locally.
10079816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     *
10089816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     * @param nextChar The DTMF character that was just processed by the {@code Connection}.
10094d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia     *
10104d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia     * @hide
10114d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia     */
10124d7ac854c5a45d0e3af3d0af78b5a8c9807cbec6Wei Jia    public final void setNextPostDialWaitChar(char nextChar) {
10139816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        checkImmutable();
10149816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        for (Listener l : mListeners) {
10159816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia            l.onPostDialChar(this, nextChar);
10169816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia        }
10179816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    }
101806ad1528e6dd4c866c085d3cad9235d2752eb3edLajos Molnar
10199816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    /**
1020c4ac8173f911aeac8d5006b19ba48fb51a865115Wei Jia     * Requests that the framework play a ringback tone. This is to be invoked by implementations
10215095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu     * that do not play a ringback tone themselves in the connection's audio stream.
10225095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu     *
1023a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu     * @param ringback Whether the ringback tone is to be played.
10249816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     */
10259816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    public final void setRingbackRequested(boolean ringback) {
10267b15cb33847e6282ea8352c98894683b796127f3Wei Jia        checkImmutable();
10277b15cb33847e6282ea8352c98894683b796127f3Wei Jia        if (mRingbackRequested != ringback) {
1028eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu            mRingbackRequested = ringback;
1029a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu            for (Listener l : mListeners) {
10309816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia                l.onRingbackRequested(this, ringback);
1031a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu            }
1032a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu        }
1033eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    }
10347b15cb33847e6282ea8352c98894683b796127f3Wei Jia
1035eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    /** @hide */
1036eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    @SystemApi @Deprecated public final void setCallCapabilities(int connectionCapabilities) {
1037eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu        setConnectionCapabilities(connectionCapabilities);
1038eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    }
1039eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu
10407b15cb33847e6282ea8352c98894683b796127f3Wei Jia    /**
10414ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia     * Sets the connection's capabilities as a bit mask of the {@code CAPABILITY_*} constants.
10424ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia     *
10434ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia     * @param connectionCapabilities The new connection capabilities.
104412b6265f1d4be368957f91104d5210cf604ac4ccWei Jia     */
10454ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia    public final void setConnectionCapabilities(int connectionCapabilities) {
10464ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        checkImmutable();
10474ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia        if (mConnectionCapabilities != connectionCapabilities) {
104812b6265f1d4be368957f91104d5210cf604ac4ccWei Jia            mConnectionCapabilities = connectionCapabilities;
104912b6265f1d4be368957f91104d5210cf604ac4ccWei Jia            for (Listener l : mListeners) {
105012b6265f1d4be368957f91104d5210cf604ac4ccWei Jia                l.onConnectionCapabilitiesChanged(this, mConnectionCapabilities);
105112b6265f1d4be368957f91104d5210cf604ac4ccWei Jia            }
105212b6265f1d4be368957f91104d5210cf604ac4ccWei Jia        }
105312b6265f1d4be368957f91104d5210cf604ac4ccWei Jia    }
105412b6265f1d4be368957f91104d5210cf604ac4ccWei Jia
105512b6265f1d4be368957f91104d5210cf604ac4ccWei Jia    /**
105612b6265f1d4be368957f91104d5210cf604ac4ccWei Jia     * Tears down the Connection object.
105712b6265f1d4be368957f91104d5210cf604ac4ccWei Jia     */
105812b6265f1d4be368957f91104d5210cf604ac4ccWei Jia    public final void destroy() {
105912b6265f1d4be368957f91104d5210cf604ac4ccWei Jia        for (Listener l : mListeners) {
106012b6265f1d4be368957f91104d5210cf604ac4ccWei Jia            l.onDestroyed(this);
106112b6265f1d4be368957f91104d5210cf604ac4ccWei Jia        }
106212b6265f1d4be368957f91104d5210cf604ac4ccWei Jia    }
10634ecbea3ae1fcefb082dc419cb663909536138ddbWei Jia
10648edb3f85f58e8738582e8f9abbc018c85100b712Wei Jia    /**
10657b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Requests that the framework use VOIP audio mode for this connection.
1066eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu     *
1067eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu     * @param isVoip True if the audio mode is VOIP.
10687b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
10697b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public final void setAudioModeIsVoip(boolean isVoip) {
1070fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang        checkImmutable();
10717b15cb33847e6282ea8352c98894683b796127f3Wei Jia        mAudioModeIsVoip = isVoip;
1072fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang        for (Listener l : mListeners) {
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            l.onAudioModeIsVoipChanged(this, isVoip);
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Sets the label and icon status to display in the in-call UI.
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @param statusHints The status label and icon to set.
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
10821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    public final void setStatusHints(StatusHints statusHints) {
10837b15cb33847e6282ea8352c98894683b796127f3Wei Jia        checkImmutable();
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mStatusHints = statusHints;
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (Listener l : mListeners) {
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            l.onStatusHintsChanged(this, statusHints);
1087dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        }
1088dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar    }
1089dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar
1090dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar    /**
1091dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar     * Sets the connections with which this connection can be conferenced.
109200541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     *
1093dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar     * @param conferenceableConnections The set of connections this connection can conference with.
1094dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar     */
1095dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar    public final void setConferenceableConnections(List<Connection> conferenceableConnections) {
1096dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        checkImmutable();
1097d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        clearConferenceableList();
1098d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        for (Connection c : conferenceableConnections) {
1099dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // small amount of items here.
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mConferenceables.contains(c)) {
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                c.addConnectionListener(mConnectionDeathListener);
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mConferenceables.add(c);
11047b15cb33847e6282ea8352c98894683b796127f3Wei Jia            }
11057b15cb33847e6282ea8352c98894683b796127f3Wei Jia        }
11067b15cb33847e6282ea8352c98894683b796127f3Wei Jia        fireOnConferenceableConnectionsChanged();
11077b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
11087b15cb33847e6282ea8352c98894683b796127f3Wei Jia
11097b15cb33847e6282ea8352c98894683b796127f3Wei Jia    /**
111025d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     * Similar to {@link #setConferenceableConnections(java.util.List)}, sets a list of connections
111125d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     * or conferences with which this connection can be conferenced.
111225d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     *
111300541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     * @param conferenceables The conferenceables.
111400541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     */
11157b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public final void setConferenceables(List<IConferenceable> conferenceables) {
111600541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih        clearConferenceableList();
111700541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih        for (IConferenceable c : conferenceables) {
111800541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih            // If statement checks for duplicates in input. It makes it N^2 but we're dealing with a
111900541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih            // small amount of items here.
112000541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih            if (!mConferenceables.contains(c)) {
11217b15cb33847e6282ea8352c98894683b796127f3Wei Jia                if (c instanceof Connection) {
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    Connection connection = (Connection) c;
1123f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar                    connection.addConnectionListener(mConnectionDeathListener);
11247b15cb33847e6282ea8352c98894683b796127f3Wei Jia                } else if (c instanceof Conference) {
11257b15cb33847e6282ea8352c98894683b796127f3Wei Jia                    Conference conference = (Conference) c;
1126f592671336be0a061799033e47ceeacb648ed3bfLajos Molnar                    conference.addListener(mConferenceDeathListener);
1127d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar                }
1128d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar                mConferenceables.add(c);
1129d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar            }
1130d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        }
1131d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        fireOnConferenceableConnectionsChanged();
1132d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    }
113300541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih
1134d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    /**
113500541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     * Returns the connections or conferences with which this connection can be conferenced.
1136d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar     */
1137d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    public final List<IConferenceable> getConferenceables() {
1138d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        return mUnmodifiableConferenceables;
113900541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih    }
114000541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih
114100541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih    /*
114200541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     * @hide
114300541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih     */
114400541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih    public final void setConnectionService(ConnectionService connectionService) {
114500541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih        checkImmutable();
114600541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih        if (mConnectionService != null) {
114700541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih            Log.e(this, new Exception(), "Trying to set ConnectionService on a connection " +
1148d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar                    "which is already associated with another ConnectionService.");
1149d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar        } else {
1150d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar            mConnectionService = connectionService;
115100541e293c250ea9e31b6ab2dc134802e34fe843Robert Shih        }
1152d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    }
1153d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar
1154d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar    /**
1155d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar     * @hide
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final void unsetConnectionService(ConnectionService connectionService) {
1158dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        if (mConnectionService != connectionService) {
1159dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar            Log.e(this, new Exception(), "Trying to remove ConnectionService from a Connection " +
1160dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar                    "that does not belong to the ConnectionService.");
1161dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        } else {
1162dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar            mConnectionService = null;
1163095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar        }
1164dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar    }
1165dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final ConnectionService getConnectionService() {
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mConnectionService;
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Sets the conference that this connection is a part of. This will fail if the connection is
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * already part of a conference. {@link #resetConference} to un-set the conference first.
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @param conference The conference.
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @return {@code true} if the conference was successfully set.
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
1180c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber     */
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public final boolean setConference(Conference conference) {
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        checkImmutable();
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // We check to see if it is already part of another conference.
11843fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber        if (mConference == null) {
1185a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu            mConference = conference;
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (mConnectionService != null && mConnectionService.containsConference(conference)) {
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                fireConferenceChanged();
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
118925d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia            return true;
1190d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber        }
11912995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia        return false;
1192d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    }
1193d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber
1194d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    /**
1195d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber     * Resets the conference that this connection is a part of.
1196d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber     * @hide
1197a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu     */
1198d5e56231a598b180a1d898bb7dc61b75580e59a4Andreas Huber    public final void resetConference() {
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mConference != null) {
1200fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang            Log.d(this, "Conference reset");
12013fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber            mConference = null;
1202fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang            fireConferenceChanged();
1203a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu        }
1204fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    }
1205fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang
1206fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    /**
1207fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang     * Notifies this Connection that the {@link #getAudioState()} property has a new value.
12086d339f1f764bbd32e3381dae7bfa7c6c575bb493Lajos Molnar     *
1209fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang     * @param state The new connection audio state.
12109816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     */
12119816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia    public void onAudioStateChanged(AudioState state) {}
1212fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang
1213fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    /**
12149816016afb2a13c6a866cd047d57020566a8b9a9Wei Jia     * Notifies this Connection of an internal state change. This method is called after the
12152995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia     * state is changed.
12162995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia     *
12172995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia     * @param state The new state, one of the {@code STATE_*} constants.
12182995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia     */
12192995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia    public void onStateChanged(int state) {}
12202995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia
12212995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia    /**
12222995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia     * Notifies this Connection of a request to play a DTMF tone.
1223fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang     *
1224078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber     * @param c A DTMF character.
1225a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu     */
1226eecb7805bbbb712925d4372c505f8c7f5c4fb5edRonghua Wu    public void onPlayDtmfTone(char c) {}
1227a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu
1228a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu    /**
12297b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Notifies this Connection of a request to stop any currently playing DTMF tones.
12307b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
123149966fff32b27f8821ebe280f25688b3c4f5f73fWei Jia    public void onStopDtmfTone() {}
1232078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
123425d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     * Notifies this Connection of a request to disconnect.
123525d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     */
123625d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia    public void onDisconnect() {}
123725d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia
123825d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia    /**
123925d696f31bfcbb24459f5d68c2288101bb5f7875Wei Jia     * Notifies this Connection of a request to disconnect a participant of the conference managed
1240dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar     * by the connection.
1241683525b61bc1b58b4fd9e1b3ef9ed3b0c3bf34aeGlenn Kasten     *
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @param endpoint the {@link Uri} of the participant to disconnect.
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
124543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber    public void onDisconnectConferenceParticipant(Uri endpoint) {}
1246fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang
1247f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong    /**
1248fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang     * Notifies this Connection of a request to separate from its parent conference.
1249fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang     */
1250fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    public void onSeparate() {}
1251fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang
1252fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    /**
12537b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Notifies this Connection of a request to abort.
12547b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
1255fbe8bef8bcf7aed97f0332908a817b0e6d91b9baChong Zhang    public void onAbort() {}
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1258f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong     * Notifies this Connection of a request to hold.
1259f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong     */
1260f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong    public void onHold() {}
1261f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong
1262f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong    /**
1263f57b4ea3e409537b1d5f9aaea93d356b1cebbc6aJames Dong     * Notifies this Connection of a request to exit a hold state.
12645095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu     */
12657c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia    public void onUnhold() {}
12667c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia
12677c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia    /**
12687c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia     * Notifies this Connection, which is in {@link #STATE_RINGING}, of
12697c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia     * a request to accept.
12707c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia     *
12717c8d0e0a896eb736ca4cec7fb796704a3c14ab66Wei Jia     * @param videoState The video state in which to answer the connection.
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public void onAnswer(int videoState) {}
1275c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
12765095d7091874cb9e9c95ecc4fe762076ed05e624Ronghua Wu    /**
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Notifies this Connection, which is in {@link #STATE_RINGING}, of
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * a request to accept.
1279faeb0f291330134dc4468359a36e099aae508449Ronghua Wu     */
1280faeb0f291330134dc4468359a36e099aae508449Ronghua Wu    public void onAnswer() {
12813a2956d148d81194e297408179e84a47a309ef48Wei Jia        onAnswer(VideoProfile.VideoState.AUDIO_ONLY);
12823a2956d148d81194e297408179e84a47a309ef48Wei Jia    }
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Notifies this Connection, which is in {@link #STATE_RINGING}, of
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * a request to reject.
12877b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
12887b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public void onReject() {}
12897b15cb33847e6282ea8352c98894683b796127f3Wei Jia
12907b15cb33847e6282ea8352c98894683b796127f3Wei Jia    /**
12917b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Notifies this Connection whether the user wishes to proceed with the post-dial DTMF codes.
12927b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
12937b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public void onPostDialContinue(boolean proceed) {}
12947b15cb33847e6282ea8352c98894683b796127f3Wei Jia
12957b15cb33847e6282ea8352c98894683b796127f3Wei Jia    static String toLogSafePhoneNumber(String number) {
1296a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu        // For unknown number, log empty string.
1297a73d9e0b3d171d2bfcd9eb07df9d6d36ae74df57Ronghua Wu        if (number == null) {
1298dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar            return "";
1299dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        }
1300dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar
1301dc43dfa1294470a4413c37e863ef3b621da8681fLajos Molnar        if (PII_DEBUG) {
1302bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            // When PII_DEBUG is true we emit PII.
1303bc7f5b2e56107cfeaeeab13cf8979379e3c2f139Andreas Huber            return number;
13042d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        }
13052d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // sanitized phone numbers.
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        StringBuilder builder = new StringBuilder();
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (int i = 0; i < number.length(); i++) {
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            char c = number.charAt(i);
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (c == '-' || c == '@' || c == '.') {
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                builder.append(c);
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                builder.append('x');
1315d5923409bbcbb22954a92c2b497ef4492d7cb6a5Lajos Molnar            }
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return builder.toString();
13187b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1320bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    private void setState(int state) {
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        checkImmutable();
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mState == STATE_DISCONNECTED && mState != state) {
13237b15cb33847e6282ea8352c98894683b796127f3Wei Jia            Log.d(this, "Connection already DISCONNECTED; cannot transition out of this state.");
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
13267b15cb33847e6282ea8352c98894683b796127f3Wei Jia        if (mState != state) {
1327cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            Log.d(this, "setState: %s", stateToString(state));
1328cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            mState = state;
1329cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            onStateChanged(state);
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            for (Listener l : mListeners) {
1331cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                l.onStateChanged(this, state);
1332cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            }
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1334cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
1335cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
1336bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    private static class FailureSignalingConnection extends Connection {
1337cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        private boolean mImmutable = false;
1338cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        public FailureSignalingConnection(DisconnectCause disconnectCause) {
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            setDisconnected(disconnectCause);
1340cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            mImmutable = true;
1341cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        }
1342cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
1343cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        public void checkImmutable() {
1344cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber            if (mImmutable) {
1345cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                throw new UnsupportedOperationException("Connection is immutable");
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1347cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        }
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block
1350cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    /**
1351cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * Return a {@code Connection} which represents a failed connection attempt. The returned
1352cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * {@code Connection} will have a {@link android.telecom.DisconnectCause} and as specified,
1353cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * and a {@link #getState()} of {@link #STATE_DISCONNECTED}.
1354cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * <p>
1355cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * The returned {@code Connection} can be assumed to {@link #destroy()} itself when appropriate,
1356cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * so users of this method need not maintain a reference to its return value to destroy it.
1357cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     *
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @param disconnectCause The disconnect cause, ({@see android.telecomm.DisconnectCause}).
1359cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber     * @return A {@code Connection} which indicates failure.
1360bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public static Connection createFailedConnection(DisconnectCause disconnectCause) {
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return new FailureSignalingConnection(disconnectCause);
1363bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Override to throw an {@link UnsupportedOperationException} if this {@code Connection} is
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * not intended to be mutated, e.g., if it is a marker for failure. Only for framework use;
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * this should never be un-@hide-den.
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @hide
1371bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia     */
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    public void checkImmutable() {}
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    /**
13757b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Return a {@code Connection} which represents a canceled connection attempt. The returned
13767b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * {@code Connection} will have state {@link #STATE_DISCONNECTED}, and cannot be moved out of
13777b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * that state. This connection should not be used for anything, and no other
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * {@code Connection}s should be attempted.
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * <p>
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * so users of this method need not maintain a reference to its return value to destroy it.
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * @return A {@code Connection} which indicates that the underlying connection should
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * be canceled.
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     */
13857b15cb33847e6282ea8352c98894683b796127f3Wei Jia    public static Connection createCanceledConnection() {
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return new FailureSignalingConnection(new DisconnectCause(DisconnectCause.CANCELED));
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private final void fireOnConferenceableConnectionsChanged() {
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (Listener l : mListeners) {
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            l.onConferenceablesChanged(this, getConferenceables());
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private final void fireConferenceChanged() {
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        for (Listener l : mListeners) {
13977b15cb33847e6282ea8352c98894683b796127f3Wei Jia            l.onConferenceChanged(this, mConference);
1398b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson        }
1399bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia    }
1400b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    private final void clearConferenceableList() {
1402bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia        for (IConferenceable c : mConferenceables) {
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (c instanceof Connection) {
14047b15cb33847e6282ea8352c98894683b796127f3Wei Jia                Connection connection = (Connection) c;
14057b15cb33847e6282ea8352c98894683b796127f3Wei Jia                connection.removeConnectionListener(mConnectionDeathListener);
1406bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia            } else if (c instanceof Conference) {
1407b50e83eca302a12f0fced6e7bab1b8617d63deaaRoger Jönsson                Conference conference = (Conference) c;
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                conference.removeListener(mConferenceDeathListener);
14097b15cb33847e6282ea8352c98894683b796127f3Wei Jia            }
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mConferenceables.clear();
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14147137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    /**
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     * Notifies listeners of a change to conference participant(s).
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber     *
141728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia     * @param conferenceParticipants The participants.
14187b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * @hide
141928a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia     */
14207137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    protected final void updateConferenceParticipants(
14217137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang            List<ConferenceParticipant> conferenceParticipants) {
14222995dc7afc23e42478969bf567aa3435f4d3b54dWei Jia        for (Listener l : mListeners) {
142328a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia            l.onConferenceParticipantsChanged(this, conferenceParticipants);
14247137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang        }
14257137ec7e005a5a6e3c0edb91cfacf16a31f4bf6aChong Zhang    }
142628a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia
142728a8a9ff2a2bfd5edbdbbadde50c6d804335ffdcWei Jia    /**
14287b15cb33847e6282ea8352c98894683b796127f3Wei Jia     * Notifies listeners that a conference call has been started.
14297b15cb33847e6282ea8352c98894683b796127f3Wei Jia     */
14307b15cb33847e6282ea8352c98894683b796127f3Wei Jia    protected void notifyConferenceStarted() {
14317b15cb33847e6282ea8352c98894683b796127f3Wei Jia        for (Listener l : mListeners) {
14327b15cb33847e6282ea8352c98894683b796127f3Wei Jia            l.onConferenceStarted();
14337b15cb33847e6282ea8352c98894683b796127f3Wei Jia        }
14347b15cb33847e6282ea8352c98894683b796127f3Wei Jia    }
14357b15cb33847e6282ea8352c98894683b796127f3Wei Jia}
14367b15cb33847e6282ea8352c98894683b796127f3Wei Jia