• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
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
14  * limitations under the License
15  */
16 
17 package android.telephony.ims;
18 
19 import android.annotation.NonNull;
20 import android.annotation.SystemApi;
21 import android.os.Bundle;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.telecom.Call;
25 import android.telecom.Connection;
26 
27 import com.android.telephony.Rlog;
28 
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.Map.Entry;
32 import java.util.Set;
33 
34 /**
35  * Provides the conference information (defined in RFC 4575) for IMS conference call.
36  *
37  * @hide
38  */
39 @SystemApi
40 public final class ImsConferenceState implements Parcelable {
41     private static final String TAG = "ImsConferenceState";
42     /**
43      * conference-info : user
44      */
45     // user (String) : Tel or SIP URI
46     public static final String USER = "user";
47     // user > display text (String)
48     public static final String DISPLAY_TEXT = "display-text";
49     // user > endpoint (String) : URI or GRUU or Phone number
50     public static final String ENDPOINT = "endpoint";
51     // user > endpoint > status
52     public static final String STATUS = "status";
53 
54     /**
55      * status-type (String) :
56      * "pending" : Endpoint is not yet in the session, but it is anticipated that he/she will
57      *      join in the near future.
58      * "dialing-out" : Focus has dialed out to connect the endpoint to the conference,
59      *      but the endpoint is not yet in the roster (probably being authenticated).
60      * "dialing-in" : Endpoint is dialing into the conference, not yet in the roster
61      *      (probably being authenticated).
62      * "alerting" : PSTN alerting or SIP 180 Ringing was returned for the outbound call;
63      *      endpoint is being alerted.
64      * "on-hold" : Active signaling dialog exists between an endpoint and a focus,
65      *      but endpoint is "on-hold" for this conference, i.e., he/she is neither "hearing"
66      *      the conference mix nor is his/her media being mixed in the conference.
67      * "connected" : Endpoint is a participant in the conference. Depending on the media policies,
68      *      he/she can send and receive media to and from other participants.
69      * "disconnecting" : Focus is in the process of disconnecting the endpoint
70      *      (e.g. in SIP a DISCONNECT or BYE was sent to the endpoint).
71      * "disconnected" : Endpoint is not a participant in the conference, and no active dialog
72      *      exists between the endpoint and the focus.
73      * "muted-via-focus" : Active signaling dialog exists beween an endpoint and a focus and
74      *      the endpoint can "listen" to the conference, but the endpoint's media is not being
75      *      mixed into the conference.
76      * "connect-fail" : Endpoint fails to join the conference by rejecting the conference call.
77      */
78     public static final String STATUS_PENDING = "pending";
79     public static final String STATUS_DIALING_OUT = "dialing-out";
80     public static final String STATUS_DIALING_IN = "dialing-in";
81     public static final String STATUS_ALERTING = "alerting";
82     public static final String STATUS_ON_HOLD = "on-hold";
83     public static final String STATUS_CONNECTED = "connected";
84     public static final String STATUS_DISCONNECTING = "disconnecting";
85     public static final String STATUS_DISCONNECTED = "disconnected";
86     public static final String STATUS_MUTED_VIA_FOCUS = "muted-via-focus";
87     public static final String STATUS_CONNECT_FAIL = "connect-fail";
88     public static final String STATUS_SEND_ONLY = "sendonly";
89     public static final String STATUS_SEND_RECV = "sendrecv";
90 
91     /**
92      * conference-info : SIP status code (integer)
93      */
94     public static final String SIP_STATUS_CODE = "sipstatuscode";
95 
96     public final HashMap<String, Bundle> mParticipants = new HashMap<String, Bundle>();
97 
98     /** @hide */
ImsConferenceState()99     public ImsConferenceState() {
100     }
101 
ImsConferenceState(Parcel in)102     private ImsConferenceState(Parcel in) {
103         readFromParcel(in);
104     }
105 
106     @Override
describeContents()107     public int describeContents() {
108         return 0;
109     }
110 
111     @Override
writeToParcel(Parcel out, int flags)112     public void writeToParcel(Parcel out, int flags) {
113         out.writeInt(mParticipants.size());
114 
115         if (mParticipants.size() > 0) {
116             Set<Entry<String, Bundle>> entries = mParticipants.entrySet();
117 
118             if (entries != null) {
119                 Iterator<Entry<String, Bundle>> iterator = entries.iterator();
120 
121                 while (iterator.hasNext()) {
122                     Entry<String, Bundle> entry = iterator.next();
123 
124                     out.writeString(entry.getKey());
125                     out.writeParcelable(entry.getValue(), 0);
126                 }
127             }
128         }
129     }
130 
readFromParcel(Parcel in)131     private void readFromParcel(Parcel in) {
132         int size = in.readInt();
133 
134         for (int i = 0; i < size; ++i) {
135             String user = in.readString();
136             Bundle state = in.readParcelable(null);
137             mParticipants.put(user, state);
138         }
139     }
140 
141     public static final @android.annotation.NonNull Creator<ImsConferenceState> CREATOR =
142             new Creator<ImsConferenceState>() {
143         @Override
144         public ImsConferenceState createFromParcel(Parcel in) {
145             return new ImsConferenceState(in);
146         }
147 
148         @Override
149         public ImsConferenceState[] newArray(int size) {
150             return new ImsConferenceState[size];
151         }
152     };
153 
154     /**
155      * Translates an {@code ImsConferenceState} status type to a telecom connection state.
156      *
157      * @param status The status type.
158      * @return The corresponding {@link android.telecom.Connection} state.
159      */
getConnectionStateForStatus(String status)160     public static int getConnectionStateForStatus(String status) {
161         if (status.equals(STATUS_PENDING)) {
162             return Connection.STATE_INITIALIZING;
163         } else if (status.equals(STATUS_DIALING_IN)) {
164             return Connection.STATE_RINGING;
165         } else if (status.equals(STATUS_ALERTING) ||
166                 status.equals(STATUS_DIALING_OUT)) {
167             return Connection.STATE_DIALING;
168         } else if (status.equals(STATUS_ON_HOLD) ||
169                 status.equals(STATUS_SEND_ONLY)) {
170             return Connection.STATE_HOLDING;
171         } else if (status.equals(STATUS_CONNECTED) ||
172                 status.equals(STATUS_MUTED_VIA_FOCUS) ||
173                 status.equals(STATUS_DISCONNECTING) ||
174                 status.equals(STATUS_SEND_RECV)) {
175             return Connection.STATE_ACTIVE;
176         } else if (status.equals(STATUS_DISCONNECTED)) {
177             return Connection.STATE_DISCONNECTED;
178         }
179         return Call.STATE_ACTIVE;
180     }
181 
182     @NonNull
183     @Override
toString()184     public String toString() {
185         StringBuilder sb = new StringBuilder();
186         sb.append("[");
187         sb.append(ImsConferenceState.class.getSimpleName());
188         sb.append(" ");
189         if (mParticipants.size() > 0) {
190             Set<Entry<String, Bundle>> entries = mParticipants.entrySet();
191 
192             if (entries != null) {
193                 Iterator<Entry<String, Bundle>> iterator = entries.iterator();
194                 sb.append("<");
195                 while (iterator.hasNext()) {
196                     Entry<String, Bundle> entry = iterator.next();
197                     sb.append(Rlog.pii(TAG, entry.getKey()));
198                     sb.append(": ");
199                     Bundle participantData = entry.getValue();
200 
201                     for (String key : participantData.keySet()) {
202                         sb.append(key);
203                         sb.append("=");
204                         if (STATUS.equals(key)) {
205                             sb.append(participantData.get(key));
206                         } else {
207                             sb.append(Rlog.pii(TAG, participantData.get(key)));
208                         }
209                         sb.append(", ");
210                     }
211                 }
212                 sb.append(">");
213             }
214         }
215         sb.append("]");
216         return sb.toString();
217     }
218 }
219