blob: bebbbd01fd88f19d2aa9561b12bd85c0a195e34b [file] [log] [blame]
Andrew Lee7f3d41f2014-09-11 17:33:16 -07001/*
2 * Copyright (C) 2014 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 android.telecom;
18
Youming Yed6de26e2019-01-30 11:20:35 -080019import android.media.ToneGenerator;
Andrew Lee7f3d41f2014-09-11 17:33:16 -070020import android.os.Parcel;
21import android.os.Parcelable;
Andrew Lee7f3d41f2014-09-11 17:33:16 -070022import android.text.TextUtils;
23
24import java.util.Objects;
25
26/**
27 * Describes the cause of a disconnected call. This always includes a code describing the generic
Santos Cordond9e614f2014-10-28 13:10:36 -070028 * cause of the disconnect. Optionally, it may include a label and/or description to display to the
29 * user. It is the responsibility of the {@link ConnectionService} to provide localized versions of
30 * the label and description. It also may contain a reason for the disconnect, which is intended for
31 * logging and not for display to the user.
Andrew Lee7f3d41f2014-09-11 17:33:16 -070032 */
33public final class DisconnectCause implements Parcelable {
34
35 /** Disconnected because of an unknown or unspecified reason. */
Tej Singhc477d9c2018-02-05 18:31:39 -080036 public static final int UNKNOWN = TelecomProtoEnums.UNKNOWN; // = 0
Andrew Lee7f3d41f2014-09-11 17:33:16 -070037 /** Disconnected because there was an error, such as a problem with the network. */
Tej Singhc477d9c2018-02-05 18:31:39 -080038 public static final int ERROR = TelecomProtoEnums.ERROR; // = 1
Andrew Lee7f3d41f2014-09-11 17:33:16 -070039 /** Disconnected because of a local user-initiated action, such as hanging up. */
Tej Singhc477d9c2018-02-05 18:31:39 -080040 public static final int LOCAL = TelecomProtoEnums.LOCAL; // = 2
Andrew Lee7f3d41f2014-09-11 17:33:16 -070041 /**
42 * Disconnected because of a remote user-initiated action, such as the other party hanging up
43 * up.
44 */
Tej Singhc477d9c2018-02-05 18:31:39 -080045 public static final int REMOTE = TelecomProtoEnums.REMOTE; // = 3
Andrew Lee7f3d41f2014-09-11 17:33:16 -070046 /** Disconnected because it has been canceled. */
Tej Singhc477d9c2018-02-05 18:31:39 -080047 public static final int CANCELED = TelecomProtoEnums.CANCELED; // = 4
Andrew Lee7f3d41f2014-09-11 17:33:16 -070048 /** Disconnected because there was no response to an incoming call. */
Tej Singhc477d9c2018-02-05 18:31:39 -080049 public static final int MISSED = TelecomProtoEnums.MISSED; // = 5
Andrew Lee7f3d41f2014-09-11 17:33:16 -070050 /** Disconnected because the user rejected an incoming call. */
Tej Singhc477d9c2018-02-05 18:31:39 -080051 public static final int REJECTED = TelecomProtoEnums.REJECTED; // = 6
Andrew Lee7f3d41f2014-09-11 17:33:16 -070052 /** Disconnected because the other party was busy. */
Tej Singhc477d9c2018-02-05 18:31:39 -080053 public static final int BUSY = TelecomProtoEnums.BUSY; // = 7
Andrew Lee7f3d41f2014-09-11 17:33:16 -070054 /**
55 * Disconnected because of a restriction on placing the call, such as dialing in airplane
56 * mode.
57 */
Tej Singhc477d9c2018-02-05 18:31:39 -080058 public static final int RESTRICTED = TelecomProtoEnums.RESTRICTED; // = 8
Andrew Lee7f3d41f2014-09-11 17:33:16 -070059 /** Disconnected for reason not described by other disconnect codes. */
Tej Singhc477d9c2018-02-05 18:31:39 -080060 public static final int OTHER = TelecomProtoEnums.OTHER; // = 9
Sailesh Nepal7a69c922014-11-05 18:37:53 -080061 /**
62 * Disconnected because the connection manager did not support the call. The call will be tried
63 * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}.
64 */
Tej Singhc477d9c2018-02-05 18:31:39 -080065 public static final int CONNECTION_MANAGER_NOT_SUPPORTED =
66 TelecomProtoEnums.CONNECTION_MANAGER_NOT_SUPPORTED; // = 10
Andrew Lee7f3d41f2014-09-11 17:33:16 -070067
Tyler Gunn876dbfb2016-03-14 15:18:07 -070068 /**
69 * Disconnected because the user did not locally answer the incoming call, but it was answered
70 * on another device where the call was ringing.
71 */
Tej Singhc477d9c2018-02-05 18:31:39 -080072 public static final int ANSWERED_ELSEWHERE = TelecomProtoEnums.ANSWERED_ELSEWHERE; // = 11
Tyler Gunn876dbfb2016-03-14 15:18:07 -070073
74 /**
75 * Disconnected because the call was pulled from the current device to another device.
76 */
Tej Singhc477d9c2018-02-05 18:31:39 -080077 public static final int CALL_PULLED = TelecomProtoEnums.CALL_PULLED; // = 12
Tyler Gunn876dbfb2016-03-14 15:18:07 -070078
Tyler Gunn6adbd2b2016-12-07 13:19:44 -080079 /**
80 * Reason code (returned via {@link #getReason()}) which indicates that a call could not be
81 * completed because the cellular radio is off or out of service, the device is connected to
82 * a wifi network, but the user has not enabled wifi calling.
83 * @hide
84 */
85 public static final String REASON_WIFI_ON_BUT_WFC_OFF = "REASON_WIFI_ON_BUT_WFC_OFF";
86
Brad Ebinger8818c6f2017-06-30 15:34:32 -070087 /**
88 * Reason code (returned via {@link #getReason()}), which indicates that the video telephony
89 * call was disconnected because IMS access is blocked.
90 * @hide
91 */
92 public static final String REASON_IMS_ACCESS_BLOCKED = "REASON_IMS_ACCESS_BLOCKED";
93
Youming Yed6de26e2019-01-30 11:20:35 -080094 /**
95 * Reason code, which indicates that the conference call is simulating single party conference.
96 * @hide
97 */
98 public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL";
99
Brad Ebinger62713872019-11-18 18:43:35 -0800100 /**
101 * This reason is set when a call is ended in order to place an emergency call when a
102 * {@link PhoneAccount} doesn't support holding an ongoing call to place an emergency call. This
103 * reason string should only be associated with the {@link #LOCAL} disconnect code returned from
104 * {@link #getCode()}.
105 */
106 public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED";
107
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700108 private int mDisconnectCode;
109 private CharSequence mDisconnectLabel;
110 private CharSequence mDisconnectDescription;
111 private String mDisconnectReason;
112 private int mToneToPlay;
113
114 /**
115 * Creates a new DisconnectCause.
116 *
117 * @param code The code for the disconnect cause.
118 */
119 public DisconnectCause(int code) {
120 this(code, null, null, null, ToneGenerator.TONE_UNKNOWN);
121 }
122
123 /**
124 * Creates a new DisconnectCause.
125 *
126 * @param code The code for the disconnect cause.
127 * @param reason The reason for the disconnect.
128 */
129 public DisconnectCause(int code, String reason) {
130 this(code, null, null, reason, ToneGenerator.TONE_UNKNOWN);
131 }
132
133 /**
134 * Creates a new DisconnectCause.
Santos Cordond9e614f2014-10-28 13:10:36 -0700135 *
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700136 * @param code The code for the disconnect cause.
Santos Cordona6018b92016-02-16 14:23:12 -0800137 * @param label The localized label to show to the user to explain the disconnect.
Nancy Chenf4cf77c2014-09-19 10:53:21 -0700138 * @param description The localized description to show to the user to explain the disconnect.
139 * @param reason The reason for the disconnect.
140 */
141 public DisconnectCause(int code, CharSequence label, CharSequence description, String reason) {
142 this(code, label, description, reason, ToneGenerator.TONE_UNKNOWN);
143 }
144
145 /**
146 * Creates a new DisconnectCause.
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700147 *
148 * @param code The code for the disconnect cause.
149 * @param label The localized label to show to the user to explain the disconnect.
150 * @param description The localized description to show to the user to explain the disconnect.
151 * @param reason The reason for the disconnect.
152 * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}.
153 */
154 public DisconnectCause(int code, CharSequence label, CharSequence description, String reason,
155 int toneToPlay) {
156 mDisconnectCode = code;
157 mDisconnectLabel = label;
158 mDisconnectDescription = description;
159 mDisconnectReason = reason;
160 mToneToPlay = toneToPlay;
161 }
162
163 /**
164 * Returns the code for the reason for this disconnect.
165 *
166 * @return The disconnect code.
167 */
168 public int getCode() {
169 return mDisconnectCode;
170 }
171
172 /**
173 * Returns a short label which explains the reason for the disconnect cause and is for display
Santos Cordonc1ec9312015-04-24 11:26:01 -0700174 * in the user interface. If not null, it is expected that the In-Call UI should display this
175 * text where it would normally display the call state ("Dialing", "Disconnected") and is
176 * therefore expected to be relatively small. The {@link ConnectionService } is responsible for
177 * providing and localizing this label. If there is no string provided, returns null.
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700178 *
179 * @return The disconnect label.
180 */
181 public CharSequence getLabel() {
182 return mDisconnectLabel;
183 }
184
185 /**
186 * Returns a description which explains the reason for the disconnect cause and is for display
Santos Cordonc1ec9312015-04-24 11:26:01 -0700187 * in the user interface. This optional text is generally a longer and more descriptive version
188 * of {@link #getLabel}, however it can exist even if {@link #getLabel} is empty. The In-Call UI
189 * should display this relatively prominently; the traditional implementation displays this as
190 * an alert dialog. The {@link ConnectionService} is responsible for providing and localizing
191 * this message. If there is no string provided, returns null.
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700192 *
193 * @return The disconnect description.
194 */
195 public CharSequence getDescription() {
196 return mDisconnectDescription;
197 }
198
199 /**
200 * Returns an explanation of the reason for the disconnect. This is not intended for display to
201 * the user and is used mainly for logging.
202 *
203 * @return The disconnect reason.
204 */
205 public String getReason() {
206 return mDisconnectReason;
207 }
208
209 /**
210 * Returns the tone to play when disconnected.
211 *
212 * @return the tone as defined in {@link ToneGenerator} to play when disconnected.
213 */
214 public int getTone() {
215 return mToneToPlay;
216 }
217
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700218 public static final @android.annotation.NonNull Creator<DisconnectCause> CREATOR = new Creator<DisconnectCause>() {
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700219 @Override
220 public DisconnectCause createFromParcel(Parcel source) {
221 int code = source.readInt();
222 CharSequence label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
223 CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
224 String reason = source.readString();
225 int tone = source.readInt();
226 return new DisconnectCause(code, label, description, reason, tone);
227 }
228
229 @Override
230 public DisconnectCause[] newArray(int size) {
231 return new DisconnectCause[size];
232 }
233 };
234
235 @Override
236 public void writeToParcel(Parcel destination, int flags) {
237 destination.writeInt(mDisconnectCode);
238 TextUtils.writeToParcel(mDisconnectLabel, destination, flags);
239 TextUtils.writeToParcel(mDisconnectDescription, destination, flags);
240 destination.writeString(mDisconnectReason);
241 destination.writeInt(mToneToPlay);
242 }
243
244 @Override
245 public int describeContents() {
246 return 0;
247 }
248
249 @Override
250 public int hashCode() {
251 return Objects.hashCode(mDisconnectCode)
252 + Objects.hashCode(mDisconnectLabel)
253 + Objects.hashCode(mDisconnectDescription)
254 + Objects.hashCode(mDisconnectReason)
255 + Objects.hashCode(mToneToPlay);
256 }
257
258 @Override
259 public boolean equals(Object o) {
260 if (o instanceof DisconnectCause) {
261 DisconnectCause d = (DisconnectCause) o;
262 return Objects.equals(mDisconnectCode, d.getCode())
263 && Objects.equals(mDisconnectLabel, d.getLabel())
264 && Objects.equals(mDisconnectDescription, d.getDescription())
265 && Objects.equals(mDisconnectReason, d.getReason())
266 && Objects.equals(mToneToPlay, d.getTone());
267 }
268 return false;
269 }
270
271 @Override
272 public String toString() {
273 String code = "";
Sailesh Nepal7a69c922014-11-05 18:37:53 -0800274 switch (mDisconnectCode) {
275 case UNKNOWN:
276 code = "UNKNOWN";
277 break;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700278 case ERROR:
279 code = "ERROR";
280 break;
281 case LOCAL:
282 code = "LOCAL";
283 break;
284 case REMOTE:
285 code = "REMOTE";
286 break;
Sailesh Nepal7a69c922014-11-05 18:37:53 -0800287 case CANCELED:
288 code = "CANCELED";
289 break;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700290 case MISSED:
291 code = "MISSED";
292 break;
293 case REJECTED:
294 code = "REJECTED";
295 break;
296 case BUSY:
297 code = "BUSY";
298 break;
299 case RESTRICTED:
300 code = "RESTRICTED";
301 break;
302 case OTHER:
303 code = "OTHER";
304 break;
Sailesh Nepal7a69c922014-11-05 18:37:53 -0800305 case CONNECTION_MANAGER_NOT_SUPPORTED:
306 code = "CONNECTION_MANAGER_NOT_SUPPORTED";
307 break;
Tyler Gunn2a3f9972016-06-09 07:58:25 -0700308 case CALL_PULLED:
309 code = "CALL_PULLED";
310 break;
311 case ANSWERED_ELSEWHERE:
312 code = "ANSWERED_ELSEWHERE";
313 break;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700314 default:
Sailesh Nepal7a69c922014-11-05 18:37:53 -0800315 code = "invalid code: " + mDisconnectCode;
316 break;
Andrew Lee7f3d41f2014-09-11 17:33:16 -0700317 }
318 String label = mDisconnectLabel == null ? "" : mDisconnectLabel.toString();
319 String description = mDisconnectDescription == null
320 ? "" : mDisconnectDescription.toString();
321 String reason = mDisconnectReason == null ? "" : mDisconnectReason;
322 return "DisconnectCause [ Code: (" + code + ")"
323 + " Label: (" + label + ")"
324 + " Description: (" + description + ")"
325 + " Reason: (" + reason + ")"
326 + " Tone: (" + mToneToPlay + ") ]";
327 }
328}