blob: 44595b5bc1fd4169591cdef8841885d62efaa27b [file] [log] [blame]
Wink Savillef8458ff2014-06-25 16:08:02 -07001/*
Brad Ebinger0e370b42018-01-22 13:51:52 -08002 * Copyright (C) 2018 The Android Open Source Project
Wink Savillef8458ff2014-06-25 16:08:02 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
Brad Ebinger0e370b42018-01-22 13:51:52 -080014 * limitations under the License
Wink Savillef8458ff2014-06-25 16:08:02 -070015 */
16
Brad Ebinger0e370b42018-01-22 13:51:52 -080017package android.telephony.ims;
Wink Savillef8458ff2014-06-25 16:08:02 -070018
Brad Ebinger0e370b42018-01-22 13:51:52 -080019import android.annotation.SystemApi;
Wink Savillef8458ff2014-06-25 16:08:02 -070020import android.os.Bundle;
21import android.os.Parcel;
22import android.os.Parcelable;
Tyler Gunn3bffcf72014-10-28 13:51:27 -070023import android.telecom.Call;
24import android.telecom.Connection;
Shi Yuanjieafea7de2018-07-19 20:30:10 +090025import android.telecom.Log;
26
27import java.util.HashMap;
28import java.util.Iterator;
29import java.util.Map.Entry;
30import java.util.Set;
Wink Savillef8458ff2014-06-25 16:08:02 -070031
32/**
33 * Provides the conference information (defined in RFC 4575) for IMS conference call.
34 *
35 * @hide
36 */
Brad Ebinger0e370b42018-01-22 13:51:52 -080037@SystemApi
38public final class ImsConferenceState implements Parcelable {
Wink Savillef8458ff2014-06-25 16:08:02 -070039 /**
40 * conference-info : user
41 */
42 // user (String) : Tel or SIP URI
43 public static final String USER = "user";
44 // user > display text (String)
45 public static final String DISPLAY_TEXT = "display-text";
46 // user > endpoint (String) : URI or GRUU or Phone number
47 public static final String ENDPOINT = "endpoint";
48 // user > endpoint > status
49 public static final String STATUS = "status";
50
51 /**
52 * status-type (String) :
53 * "pending" : Endpoint is not yet in the session, but it is anticipated that he/she will
54 * join in the near future.
55 * "dialing-out" : Focus has dialed out to connect the endpoint to the conference,
56 * but the endpoint is not yet in the roster (probably being authenticated).
57 * "dialing-in" : Endpoint is dialing into the conference, not yet in the roster
58 * (probably being authenticated).
59 * "alerting" : PSTN alerting or SIP 180 Ringing was returned for the outbound call;
60 * endpoint is being alerted.
61 * "on-hold" : Active signaling dialog exists between an endpoint and a focus,
62 * but endpoint is "on-hold" for this conference, i.e., he/she is neither "hearing"
63 * the conference mix nor is his/her media being mixed in the conference.
64 * "connected" : Endpoint is a participant in the conference. Depending on the media policies,
65 * he/she can send and receive media to and from other participants.
66 * "disconnecting" : Focus is in the process of disconnecting the endpoint
67 * (e.g. in SIP a DISCONNECT or BYE was sent to the endpoint).
68 * "disconnected" : Endpoint is not a participant in the conference, and no active dialog
69 * exists between the endpoint and the focus.
70 * "muted-via-focus" : Active signaling dialog exists beween an endpoint and a focus and
71 * the endpoint can "listen" to the conference, but the endpoint's media is not being
72 * mixed into the conference.
73 * "connect-fail" : Endpoint fails to join the conference by rejecting the conference call.
74 */
75 public static final String STATUS_PENDING = "pending";
76 public static final String STATUS_DIALING_OUT = "dialing-out";
77 public static final String STATUS_DIALING_IN = "dialing-in";
78 public static final String STATUS_ALERTING = "alerting";
79 public static final String STATUS_ON_HOLD = "on-hold";
80 public static final String STATUS_CONNECTED = "connected";
81 public static final String STATUS_DISCONNECTING = "disconnecting";
82 public static final String STATUS_DISCONNECTED = "disconnected";
83 public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
84 public static final String STATUS_CONNECT_FAIL = "connect-fail";
Tyler Gunn6c350bb2017-08-25 15:01:00 -070085 public static final String STATUS_SEND_ONLY = "sendonly";
86 public static final String STATUS_SEND_RECV = "sendrecv";
Wink Savillef8458ff2014-06-25 16:08:02 -070087
88 /**
89 * conference-info : SIP status code (integer)
90 */
91 public static final String SIP_STATUS_CODE = "sipstatuscode";
92
Brad Ebinger0e370b42018-01-22 13:51:52 -080093 public final HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>();
Wink Savillef8458ff2014-06-25 16:08:02 -070094
Brad Ebinger0e370b42018-01-22 13:51:52 -080095 /** @hide */
Wink Savillef8458ff2014-06-25 16:08:02 -070096 public ImsConferenceState() {
97 }
98
Brad Ebinger0e370b42018-01-22 13:51:52 -080099 private ImsConferenceState(Parcel in) {
Wink Savillef8458ff2014-06-25 16:08:02 -0700100 readFromParcel(in);
101 }
102
103 @Override
104 public int describeContents() {
105 return 0;
106 }
107
108 @Override
109 public void writeToParcel(Parcel out, int flags) {
110 out.writeInt(mParticipants.size());
111
112 if (mParticipants.size() > 0) {
113 Set<Entry<String, Bundle>> entries = mParticipants.entrySet();
114
115 if (entries != null) {
116 Iterator<Entry<String, Bundle>> iterator = entries.iterator();
117
118 while (iterator.hasNext()) {
119 Entry<String, Bundle> entry = iterator.next();
120
121 out.writeString(entry.getKey());
122 out.writeParcelable(entry.getValue(), 0);
123 }
124 }
125 }
126 }
127
128 private void readFromParcel(Parcel in) {
129 int size = in.readInt();
130
131 for (int i = 0; i < size; ++i) {
132 String user = in.readString();
133 Bundle state = in.readParcelable(null);
134 mParticipants.put(user, state);
135 }
136 }
137
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700138 public static final @android.annotation.NonNull Creator<ImsConferenceState> CREATOR =
Wink Savillef8458ff2014-06-25 16:08:02 -0700139 new Creator<ImsConferenceState>() {
140 @Override
141 public ImsConferenceState createFromParcel(Parcel in) {
142 return new ImsConferenceState(in);
143 }
144
145 @Override
146 public ImsConferenceState[] newArray(int size) {
147 return new ImsConferenceState[size];
148 }
149 };
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700150
151 /**
152 * Translates an {@code ImsConferenceState} status type to a telecom connection state.
153 *
154 * @param status The status type.
155 * @return The corresponding {@link android.telecom.Connection} state.
156 */
157 public static int getConnectionStateForStatus(String status) {
158 if (status.equals(STATUS_PENDING)) {
159 return Connection.STATE_INITIALIZING;
160 } else if (status.equals(STATUS_DIALING_IN)) {
161 return Connection.STATE_RINGING;
162 } else if (status.equals(STATUS_ALERTING) ||
163 status.equals(STATUS_DIALING_OUT)) {
164 return Connection.STATE_DIALING;
Tyler Gunn6c350bb2017-08-25 15:01:00 -0700165 } else if (status.equals(STATUS_ON_HOLD) ||
166 status.equals(STATUS_SEND_ONLY)) {
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700167 return Connection.STATE_HOLDING;
168 } else if (status.equals(STATUS_CONNECTED) ||
169 status.equals(STATUS_MUTED_VIA_FOCUS) ||
Tyler Gunn6c350bb2017-08-25 15:01:00 -0700170 status.equals(STATUS_DISCONNECTING) ||
171 status.equals(STATUS_SEND_RECV)) {
Tyler Gunn3bffcf72014-10-28 13:51:27 -0700172 return Connection.STATE_ACTIVE;
173 } else if (status.equals(STATUS_DISCONNECTED)) {
174 return Connection.STATE_DISCONNECTED;
175 }
176 return Call.STATE_ACTIVE;
177 }
Tyler Gunn6c350bb2017-08-25 15:01:00 -0700178
179 @Override
180 public String toString() {
181 StringBuilder sb = new StringBuilder();
182 sb.append("[");
183 sb.append(ImsConferenceState.class.getSimpleName());
184 sb.append(" ");
185 if (mParticipants.size() > 0) {
186 Set<Entry<String, Bundle>> entries = mParticipants.entrySet();
187
188 if (entries != null) {
189 Iterator<Entry<String, Bundle>> iterator = entries.iterator();
190 sb.append("<");
191 while (iterator.hasNext()) {
192 Entry<String, Bundle> entry = iterator.next();
Shi Yuanjieafea7de2018-07-19 20:30:10 +0900193 sb.append(Log.pii(entry.getKey()));
Tyler Gunn6c350bb2017-08-25 15:01:00 -0700194 sb.append(": ");
195 Bundle participantData = entry.getValue();
196
197 for (String key : participantData.keySet()) {
198 sb.append(key);
199 sb.append("=");
200 if (ENDPOINT.equals(key) || USER.equals(key)) {
Shi Yuanjieafea7de2018-07-19 20:30:10 +0900201 sb.append(Log.pii(participantData.get(key)));
Tyler Gunn6c350bb2017-08-25 15:01:00 -0700202 } else {
203 sb.append(participantData.get(key));
204 }
205 sb.append(", ");
206 }
207 }
208 sb.append(">");
209 }
210 }
211 sb.append("]");
212 return sb.toString();
213 }
Wink Savillef8458ff2014-06-25 16:08:02 -0700214}