blob: 36abfc9d288eb579c8ae3e703cac8f2d4932996e [file] [log] [blame]
Wink Savillef8458ff2014-06-25 16:08:02 -07001/*
2 * Copyright (c) 2013 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
17package com.android.ims;
18
19import android.os.Bundle;
20import android.os.Parcel;
21import android.os.Parcelable;
Tyler Gunnef9f6f92014-09-12 22:16:17 -070022import android.telecom.VideoProfile;
Wink Savillef8458ff2014-06-25 16:08:02 -070023
Jing Zhaoe647a012014-08-19 12:41:23 -050024import com.android.internal.telephony.PhoneConstants;
25
Wink Savillef8458ff2014-06-25 16:08:02 -070026/**
27 * Parcelable object to handle IMS call profile.
28 * It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
29 * It provides the service and call type, the additional information related to the call.
30 *
31 * @hide
32 */
33public class ImsCallProfile implements Parcelable {
34 private static final String TAG = "ImsCallProfile";
35
36 /**
37 * Service types
38 */
39 /**
40 * It is for a special case. It helps that the application can make a call
41 * without IMS connection (not registered).
42 * In the moment of the call initiation, the device try to connect to the IMS network
43 * and initiates the call.
44 */
45 public static final int SERVICE_TYPE_NONE = 0;
46 /**
47 * It is a default type and can be selected when the device is connected to the IMS network.
48 */
49 public static final int SERVICE_TYPE_NORMAL = 1;
50 /**
51 * It is for an emergency call.
52 */
53 public static final int SERVICE_TYPE_EMERGENCY = 2;
54
55 /**
56 * Call types
57 */
58 /**
59 * IMSPhone to support IR.92 & IR.94 (voice + video upgrade/downgrade)
60 */
61 public static final int CALL_TYPE_VOICE_N_VIDEO = 1;
62 /**
63 * IR.92 (Voice only)
64 */
65 public static final int CALL_TYPE_VOICE = 2;
66 /**
67 * VT to support IR.92 & IR.94 (voice + video upgrade/downgrade)
68 */
69 public static final int CALL_TYPE_VIDEO_N_VOICE = 3;
70 /**
71 * Video Telephony (audio / video two way)
72 */
73 public static final int CALL_TYPE_VT = 4;
74 /**
75 * Video Telephony (audio two way / video TX one way)
76 */
77 public static final int CALL_TYPE_VT_TX = 5;
78 /**
79 * Video Telephony (audio two way / video RX one way)
80 */
81 public static final int CALL_TYPE_VT_RX = 6;
82 /**
83 * Video Telephony (audio two way / video inactive)
84 */
85 public static final int CALL_TYPE_VT_NODIR = 7;
86 /**
87 * VideoShare (video two way)
88 */
89 public static final int CALL_TYPE_VS = 8;
90 /**
91 * VideoShare (video TX one way)
92 */
93 public static final int CALL_TYPE_VS_TX = 9;
94 /**
95 * VideoShare (video RX one way)
96 */
97 public static final int CALL_TYPE_VS_RX = 10;
98
99 /**
100 * Extra properties for IMS call.
101 */
102 /**
103 * Boolean extra properties - "true" / "false"
104 * conference : Indicates if the session is for the conference call or not.
105 * e_call : Indicates if the session is for the emergency call or not.
106 * vms : Indicates if the session is connected to the voice mail system or not.
107 * call_mode_changeable : Indicates if the session is able to upgrade/downgrade
108 * the video during voice call.
109 * conference_avail : Indicates if the session can be extended to the conference.
110 */
111 public static final String EXTRA_CONFERENCE = "conference";
112 public static final String EXTRA_E_CALL = "e_call";
113 public static final String EXTRA_VMS = "vms";
114 public static final String EXTRA_CALL_MODE_CHANGEABLE = "call_mode_changeable";
115 public static final String EXTRA_CONFERENCE_AVAIL = "conference_avail";
116
Shriram Ganesh482e6da2014-10-13 11:31:50 -0700117 // Extra string for internal use only. OEMs should not use
118 // this for packing extras.
119 public static final String EXTRA_OEM_EXTRAS = "OemCallExtras";
120
Wink Savillef8458ff2014-06-25 16:08:02 -0700121 /**
122 * Integer extra properties
123 * oir : Rule for originating identity (number) presentation, MO/MT.
124 * {@link ImsCallProfile#OIR_DEFAULT}
125 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
126 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
127 * cnap : Rule for calling name presentation
128 * {@link ImsCallProfile#OIR_DEFAULT}
129 * {@link ImsCallProfile#OIR_PRESENTATION_RESTRICTED}
130 * {@link ImsCallProfile#OIR_PRESENTATION_NOT_RESTRICTED}
131 * dialstring : To identify the Ims call type, MO
132 * {@link ImsCallProfile#DIALSTRING_NORMAL_CALL}
133 * {@link ImsCallProfile#DIALSTRING_SS_CONF}
134 * {@link ImsCallProfile#DIALSTRING_USSD}
135 */
136 public static final String EXTRA_OIR = "oir";
137 public static final String EXTRA_CNAP = "cnap";
138 public static final String EXTRA_DIALSTRING = "dialstring";
139
140 /**
141 * Values for EXTRA_OIR / EXTRA_CNAP
142 */
143 public static final int OIR_DEFAULT = 0; // "user subscription default value"
144 public static final int OIR_PRESENTATION_RESTRICTED = 1;
145 public static final int OIR_PRESENTATION_NOT_RESTRICTED = 2;
Shriram Ganeshef0cde82015-03-05 16:43:03 +0530146 public static final int OIR_PRESENTATION_UNKNOWN = 3;
147 public static final int OIR_PRESENTATION_PAYPHONE = 4;
Wink Savillef8458ff2014-06-25 16:08:02 -0700148
149 /**
150 * Values for EXTRA_DIALSTRING
151 */
152 // default (normal call)
153 public static final int DIALSTRING_NORMAL = 0;
154 // Call for SIP-based user configuration
155 public static final int DIALSTRING_SS_CONF = 1;
156 // Call for USSD message
157 public static final int DIALSTRING_USSD = 2;
158
159 /**
Shriram Ganesh482e6da2014-10-13 11:31:50 -0700160 * Values for causes that restrict call types
161 */
162 // Default cause not restricted at peer and HD is supported
163 public static final int CALL_RESTRICT_CAUSE_NONE = 0;
164 // Service not supported by RAT at peer
165 public static final int CALL_RESTRICT_CAUSE_RAT = 1;
166 // Service Disabled at peer
167 public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
168 // HD is not supported
169 public static final int CALL_RESTRICT_CAUSE_HD = 3;
170
171 /**
Wink Savillef8458ff2014-06-25 16:08:02 -0700172 * String extra properties
173 * oi : Originating identity (number), MT only
174 * cna : Calling name
175 * ussd : For network-initiated USSD, MT only
176 * remote_uri : Connected user identity (it can be used for the conference)
Shriram Ganeshddf570e2015-05-31 09:18:48 -0700177 * ChildNum: Child number info.
178 * Codec: Codec info.
179 * DisplayText: Display text for the call.
180 * AdditionalCallInfo: Additional call info.
Omkar Kolangade99eb21d2016-02-26 09:45:04 -0800181 * CallPull: Boolean value specifying if the call is a pulled call.
Wink Savillef8458ff2014-06-25 16:08:02 -0700182 */
183 public static final String EXTRA_OI = "oi";
184 public static final String EXTRA_CNA = "cna";
185 public static final String EXTRA_USSD = "ussd";
186 public static final String EXTRA_REMOTE_URI = "remote_uri";
Shriram Ganeshddf570e2015-05-31 09:18:48 -0700187 public static final String EXTRA_CHILD_NUMBER = "ChildNum";
188 public static final String EXTRA_CODEC = "Codec";
189 public static final String EXTRA_DISPLAY_TEXT = "DisplayText";
190 public static final String EXTRA_ADDITIONAL_CALL_INFO = "AdditionalCallInfo";
Omkar Kolangade99eb21d2016-02-26 09:45:04 -0800191 public static final String EXTRA_IS_CALL_PULL = "CallPull";
Tyler Gunn3ffb08a2015-11-02 11:24:57 -0800192
193 /**
194 * Extra key which the RIL can use to indicate the radio technology used for a call.
195 * Valid values are:
196 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_LTE},
197 * {@link android.telephony.ServiceState#RIL_RADIO_TECHNOLOGY_IWLAN}, and the other defined
198 * {@code RIL_RADIO_TECHNOLOGY_*} constants.
199 * Note: Despite the fact the {@link android.telephony.ServiceState} values are integer
200 * constants, the values passed for the {@link #EXTRA_CALL_RAT_TYPE} should be strings (e.g.
201 * "14" vs (int) 14).
202 * Note: This is used by {@link com.android.internal.telephony.imsphone.ImsPhoneConnection#
203 * updateWifiStateFromExtras(Bundle)} to determine whether to set the
Tyler Gunn720c6642016-03-22 09:02:47 -0700204 * {@link android.telecom.Connection#PROPERTY_WIFI} property on a connection.
Tyler Gunn3ffb08a2015-11-02 11:24:57 -0800205 */
Omkar Kolangade3b0437e2015-10-29 15:06:27 -0700206 public static final String EXTRA_CALL_RAT_TYPE = "CallRadioTech";
Wink Savillef8458ff2014-06-25 16:08:02 -0700207
Tyler Gunn853d8f62016-07-13 17:25:37 -0700208 /**
209 * Similar to {@link #EXTRA_CALL_RAT_TYPE}, except with a lowercase 'c'. Used to ensure
210 * compatibility with modems that are non-compliant with the {@link #EXTRA_CALL_RAT_TYPE}
211 * extra key. Should be removed when the non-compliant modems are fixed.
212 * @hide
213 */
214 public static final String EXTRA_CALL_RAT_TYPE_ALT = "callRadioTech";
215
Wink Savillef8458ff2014-06-25 16:08:02 -0700216 public int mServiceType;
217 public int mCallType;
Shriram Ganesh482e6da2014-10-13 11:31:50 -0700218 public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
Wink Savillef8458ff2014-06-25 16:08:02 -0700219 public Bundle mCallExtras;
220 public ImsStreamMediaProfile mMediaProfile;
221
Wink Savillef8458ff2014-06-25 16:08:02 -0700222 public ImsCallProfile(Parcel in) {
223 readFromParcel(in);
224 }
225
226 public ImsCallProfile() {
227 mServiceType = SERVICE_TYPE_NORMAL;
228 mCallType = CALL_TYPE_VOICE_N_VIDEO;
229 mCallExtras = new Bundle();
230 mMediaProfile = new ImsStreamMediaProfile();
231 }
232
233 public ImsCallProfile(int serviceType, int callType) {
234 mServiceType = serviceType;
235 mCallType = callType;
236 mCallExtras = new Bundle();
237 mMediaProfile = new ImsStreamMediaProfile();
238 }
239
240 public String getCallExtra(String name) {
241 return getCallExtra(name, "");
242 }
243
244 public String getCallExtra(String name, String defaultValue) {
245 if (mCallExtras == null) {
246 return defaultValue;
247 }
248
249 return mCallExtras.getString(name, defaultValue);
250 }
251
252 public boolean getCallExtraBoolean(String name) {
253 return getCallExtraBoolean(name, false);
254 }
255
256 public boolean getCallExtraBoolean(String name, boolean defaultValue) {
257 if (mCallExtras == null) {
258 return defaultValue;
259 }
260
261 return mCallExtras.getBoolean(name, defaultValue);
262 }
263
264 public int getCallExtraInt(String name) {
265 return getCallExtraInt(name, -1);
266 }
267
268 public int getCallExtraInt(String name, int defaultValue) {
269 if (mCallExtras == null) {
270 return defaultValue;
271 }
272
273 return mCallExtras.getInt(name, defaultValue);
274 }
275
276 public void setCallExtra(String name, String value) {
277 if (mCallExtras != null) {
278 mCallExtras.putString(name, value);
279 }
280 }
281
282 public void setCallExtraBoolean(String name, boolean value) {
283 if (mCallExtras != null) {
284 mCallExtras.putBoolean(name, value);
285 }
286 }
287
288 public void setCallExtraInt(String name, int value) {
289 if (mCallExtras != null) {
290 mCallExtras.putInt(name, value);
291 }
292 }
293
294 public void updateCallType(ImsCallProfile profile) {
295 mCallType = profile.mCallType;
296 }
297
298 public void updateCallExtras(ImsCallProfile profile) {
299 mCallExtras.clear();
300 mCallExtras = (Bundle) profile.mCallExtras.clone();
301 }
302
303 @Override
304 public String toString() {
305 return "{ serviceType=" + mServiceType +
306 ", callType=" + mCallType +
Etan Cohendb45a012014-12-10 10:08:20 -0800307 ", restrictCause=" + mRestrictCause +
Wink Savillef8458ff2014-06-25 16:08:02 -0700308 ", mediaProfile=" + mMediaProfile.toString() + " }";
309 }
310
311 @Override
312 public int describeContents() {
313 return 0;
314 }
315
316 @Override
317 public void writeToParcel(Parcel out, int flags) {
318 out.writeInt(mServiceType);
319 out.writeInt(mCallType);
320 out.writeParcelable(mCallExtras, 0);
321 out.writeParcelable(mMediaProfile, 0);
322 }
323
324 private void readFromParcel(Parcel in) {
325 mServiceType = in.readInt();
326 mCallType = in.readInt();
327 mCallExtras = in.readParcelable(null);
328 mMediaProfile = in.readParcelable(null);
329 }
330
331 public static final Creator<ImsCallProfile> CREATOR = new Creator<ImsCallProfile>() {
332 @Override
333 public ImsCallProfile createFromParcel(Parcel in) {
334 return new ImsCallProfile(in);
335 }
336
337 @Override
338 public ImsCallProfile[] newArray(int size) {
339 return new ImsCallProfile[size];
340 }
341 };
Tyler Gunnaa07df82014-07-17 07:50:22 -0700342
343 /**
344 * Converts from the call types defined in {@link com.android.ims.ImsCallProfile} to the
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700345 * video state values defined in {@link VideoProfile}.
Tyler Gunnaa07df82014-07-17 07:50:22 -0700346 *
Tyler Gunn9eb78512016-04-12 16:13:44 -0700347 * @param callProfile The call profile.
Tyler Gunnaa07df82014-07-17 07:50:22 -0700348 * @return The video state.
349 */
Rekha Kumar07366812015-03-24 16:42:31 -0700350 public static int getVideoStateFromImsCallProfile(ImsCallProfile callProfile) {
Tyler Gunn9eb78512016-04-12 16:13:44 -0700351 int videostate = getVideoStateFromCallType(callProfile.mCallType);
352 if (callProfile.isVideoPaused() && !VideoProfile.isAudioOnly(videostate)) {
353 videostate |= VideoProfile.STATE_PAUSED;
354 } else {
355 videostate &= ~VideoProfile.STATE_PAUSED;
356 }
357 return videostate;
358 }
359
360 /**
361 * Translates a {@link ImsCallProfile} {@code CALL_TYPE_*} constant into a video state.
362 * @param callType The call type.
363 * @return The video state.
364 */
365 public static int getVideoStateFromCallType(int callType) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700366 int videostate = VideoProfile.STATE_AUDIO_ONLY;
Tyler Gunn9eb78512016-04-12 16:13:44 -0700367 switch (callType) {
Tyler Gunnaa07df82014-07-17 07:50:22 -0700368 case CALL_TYPE_VT_TX:
Tyler Gunn87b73f32015-06-03 10:09:59 -0700369 videostate = VideoProfile.STATE_TX_ENABLED;
Rekha Kumar07366812015-03-24 16:42:31 -0700370 break;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700371 case CALL_TYPE_VT_RX:
Tyler Gunn87b73f32015-06-03 10:09:59 -0700372 videostate = VideoProfile.STATE_RX_ENABLED;
Rekha Kumar07366812015-03-24 16:42:31 -0700373 break;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700374 case CALL_TYPE_VT:
Tyler Gunn87b73f32015-06-03 10:09:59 -0700375 videostate = VideoProfile.STATE_BIDIRECTIONAL;
Rekha Kumar07366812015-03-24 16:42:31 -0700376 break;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700377 case CALL_TYPE_VOICE:
Tyler Gunn87b73f32015-06-03 10:09:59 -0700378 videostate = VideoProfile.STATE_AUDIO_ONLY;
Rekha Kumar07366812015-03-24 16:42:31 -0700379 break;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700380 default:
Tyler Gunn87b73f32015-06-03 10:09:59 -0700381 videostate = VideoProfile.STATE_AUDIO_ONLY;
Rekha Kumar07366812015-03-24 16:42:31 -0700382 break;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700383 }
Rekha Kumar07366812015-03-24 16:42:31 -0700384 return videostate;
Tyler Gunnaa07df82014-07-17 07:50:22 -0700385 }
386
387 /**
Ihab Awadb19a0bc2014-08-07 19:46:01 -0700388 * Converts from the video state values defined in {@link VideoProfile}
Tyler Gunnaa07df82014-07-17 07:50:22 -0700389 * to the call types defined in {@link ImsCallProfile}.
390 *
391 * @param videoState The video state.
392 * @return The call type.
393 */
394 public static int getCallTypeFromVideoState(int videoState) {
Tyler Gunn87b73f32015-06-03 10:09:59 -0700395 boolean videoTx = isVideoStateSet(videoState, VideoProfile.STATE_TX_ENABLED);
396 boolean videoRx = isVideoStateSet(videoState, VideoProfile.STATE_RX_ENABLED);
397 boolean isPaused = isVideoStateSet(videoState, VideoProfile.STATE_PAUSED);
Tyler Gunnaa07df82014-07-17 07:50:22 -0700398 if (isPaused) {
399 return ImsCallProfile.CALL_TYPE_VT_NODIR;
400 } else if (videoTx && !videoRx) {
401 return ImsCallProfile.CALL_TYPE_VT_TX;
402 } else if (!videoTx && videoRx) {
403 return ImsCallProfile.CALL_TYPE_VT_RX;
404 } else if (videoTx && videoRx) {
405 return ImsCallProfile.CALL_TYPE_VT;
406 }
407 return ImsCallProfile.CALL_TYPE_VOICE;
408 }
409
410 /**
Jing Zhaoe647a012014-08-19 12:41:23 -0500411 * Translate presentation value to OIR value
412 * @param presentation
413 * @return OIR valuse
414 */
415 public static int presentationToOIR(int presentation) {
416 switch (presentation) {
417 case PhoneConstants.PRESENTATION_RESTRICTED:
418 return ImsCallProfile.OIR_PRESENTATION_RESTRICTED;
419 case PhoneConstants.PRESENTATION_ALLOWED:
420 return ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED;
Shriram Ganeshef0cde82015-03-05 16:43:03 +0530421 case PhoneConstants.PRESENTATION_PAYPHONE:
422 return ImsCallProfile.OIR_PRESENTATION_PAYPHONE;
423 case PhoneConstants.PRESENTATION_UNKNOWN:
424 return ImsCallProfile.OIR_PRESENTATION_UNKNOWN;
Jing Zhaoe647a012014-08-19 12:41:23 -0500425 default:
426 return ImsCallProfile.OIR_DEFAULT;
427 }
428 }
429
430 /**
431 * Translate OIR value to presentation value
432 * @param oir value
433 * @return presentation value
434 */
435 public static int OIRToPresentation(int oir) {
436 switch(oir) {
437 case ImsCallProfile.OIR_PRESENTATION_RESTRICTED:
438 return PhoneConstants.PRESENTATION_RESTRICTED;
439 case ImsCallProfile.OIR_PRESENTATION_NOT_RESTRICTED:
440 return PhoneConstants.PRESENTATION_ALLOWED;
Shriram Ganeshef0cde82015-03-05 16:43:03 +0530441 case ImsCallProfile.OIR_PRESENTATION_PAYPHONE:
442 return PhoneConstants.PRESENTATION_PAYPHONE;
443 case ImsCallProfile.OIR_PRESENTATION_UNKNOWN:
444 return PhoneConstants.PRESENTATION_UNKNOWN;
Jing Zhaoe647a012014-08-19 12:41:23 -0500445 default:
446 return PhoneConstants.PRESENTATION_UNKNOWN;
447 }
448 }
449
450 /**
Rekha Kumar07366812015-03-24 16:42:31 -0700451 * Checks if video call is paused
452 * @return true if call is video paused
453 */
454 public boolean isVideoPaused() {
455 return mMediaProfile.mVideoDirection == ImsStreamMediaProfile.DIRECTION_INACTIVE;
456 }
457
458 /**
Tyler Gunn4b6614e2016-06-22 10:35:13 -0700459 * Determines if the {@link ImsCallProfile} represents a video call.
460 *
461 * @return {@code true} if the profile is for a video call, {@code false} otherwise.
462 */
463 public boolean isVideoCall() {
464 return VideoProfile.isVideo(getVideoStateFromCallType(mCallType));
465 }
466
467 /**
Tyler Gunnaa07df82014-07-17 07:50:22 -0700468 * Determines if a video state is set in a video state bit-mask.
469 *
470 * @param videoState The video state bit mask.
471 * @param videoStateToCheck The particular video state to check.
472 * @return True if the video state is set in the bit-mask.
473 */
474 private static boolean isVideoStateSet(int videoState, int videoStateToCheck) {
475 return (videoState & videoStateToCheck) == videoStateToCheck;
476 }
Wink Savillef8458ff2014-06-25 16:08:02 -0700477}