• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.telecom;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import android.media.ToneGenerator;
22 import android.text.TextUtils;
23 
24 import java.util.Objects;
25 
26 /**
27  * Describes the cause of a disconnected call. This always includes a code describing the generic
28  * 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.
32  */
33 public final class DisconnectCause implements Parcelable {
34 
35     /** Disconnected because of an unknown or unspecified reason. */
36     public static final int UNKNOWN = TelecomProtoEnums.UNKNOWN; // = 0
37     /** Disconnected because there was an error, such as a problem with the network. */
38     public static final int ERROR = TelecomProtoEnums.ERROR; // = 1
39     /** Disconnected because of a local user-initiated action, such as hanging up. */
40     public static final int LOCAL = TelecomProtoEnums.LOCAL; // = 2
41     /**
42      * Disconnected because of a remote user-initiated action, such as the other party hanging up
43      * up.
44      */
45     public static final int REMOTE = TelecomProtoEnums.REMOTE; // = 3
46     /** Disconnected because it has been canceled. */
47     public static final int CANCELED = TelecomProtoEnums.CANCELED; // = 4
48     /** Disconnected because there was no response to an incoming call. */
49     public static final int MISSED = TelecomProtoEnums.MISSED; // = 5
50     /** Disconnected because the user rejected an incoming call. */
51     public static final int REJECTED = TelecomProtoEnums.REJECTED; // = 6
52     /** Disconnected because the other party was busy. */
53     public static final int BUSY = TelecomProtoEnums.BUSY; // = 7
54     /**
55      * Disconnected because of a restriction on placing the call, such as dialing in airplane
56      * mode.
57      */
58     public static final int RESTRICTED = TelecomProtoEnums.RESTRICTED; // = 8
59     /** Disconnected for reason not described by other disconnect codes. */
60     public static final int OTHER = TelecomProtoEnums.OTHER; // = 9
61     /**
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      */
65     public static final int CONNECTION_MANAGER_NOT_SUPPORTED =
66             TelecomProtoEnums.CONNECTION_MANAGER_NOT_SUPPORTED; // = 10
67 
68     /**
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      */
72     public static final int ANSWERED_ELSEWHERE = TelecomProtoEnums.ANSWERED_ELSEWHERE; // = 11
73 
74     /**
75      * Disconnected because the call was pulled from the current device to another device.
76      */
77     public static final int CALL_PULLED = TelecomProtoEnums.CALL_PULLED; // = 12
78 
79     /**
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 
87     /**
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 
94     private int mDisconnectCode;
95     private CharSequence mDisconnectLabel;
96     private CharSequence mDisconnectDescription;
97     private String mDisconnectReason;
98     private int mToneToPlay;
99 
100     /**
101      * Creates a new DisconnectCause.
102      *
103      * @param code The code for the disconnect cause.
104      */
DisconnectCause(int code)105     public DisconnectCause(int code) {
106         this(code, null, null, null, ToneGenerator.TONE_UNKNOWN);
107     }
108 
109     /**
110      * Creates a new DisconnectCause.
111      *
112      * @param code The code for the disconnect cause.
113      * @param reason The reason for the disconnect.
114      */
DisconnectCause(int code, String reason)115     public DisconnectCause(int code, String reason) {
116         this(code, null, null, reason, ToneGenerator.TONE_UNKNOWN);
117     }
118 
119     /**
120      * Creates a new DisconnectCause.
121      *
122      * @param code The code for the disconnect cause.
123      * @param label The localized label to show to the user to explain the disconnect.
124      * @param description The localized description to show to the user to explain the disconnect.
125      * @param reason The reason for the disconnect.
126      */
DisconnectCause(int code, CharSequence label, CharSequence description, String reason)127     public DisconnectCause(int code, CharSequence label, CharSequence description, String reason) {
128         this(code, label, description, reason, ToneGenerator.TONE_UNKNOWN);
129     }
130 
131     /**
132      * Creates a new DisconnectCause.
133      *
134      * @param code The code for the disconnect cause.
135      * @param label The localized label to show to the user to explain the disconnect.
136      * @param description The localized description to show to the user to explain the disconnect.
137      * @param reason The reason for the disconnect.
138      * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}.
139      */
DisconnectCause(int code, CharSequence label, CharSequence description, String reason, int toneToPlay)140     public DisconnectCause(int code, CharSequence label, CharSequence description, String reason,
141             int toneToPlay) {
142         mDisconnectCode = code;
143         mDisconnectLabel = label;
144         mDisconnectDescription = description;
145         mDisconnectReason = reason;
146         mToneToPlay = toneToPlay;
147     }
148 
149     /**
150      * Returns the code for the reason for this disconnect.
151      *
152      * @return The disconnect code.
153      */
getCode()154     public int getCode() {
155         return mDisconnectCode;
156     }
157 
158     /**
159      * Returns a short label which explains the reason for the disconnect cause and is for display
160      * in the user interface. If not null, it is expected that the In-Call UI should display this
161      * text where it would normally display the call state ("Dialing", "Disconnected") and is
162      * therefore expected to be relatively small. The {@link ConnectionService } is responsible for
163      * providing and localizing this label. If there is no string provided, returns null.
164      *
165      * @return The disconnect label.
166      */
getLabel()167     public CharSequence getLabel() {
168         return mDisconnectLabel;
169     }
170 
171     /**
172      * Returns a description which explains the reason for the disconnect cause and is for display
173      * in the user interface. This optional text is generally a longer and more descriptive version
174      * of {@link #getLabel}, however it can exist even if {@link #getLabel} is empty. The In-Call UI
175      * should display this relatively prominently; the traditional implementation displays this as
176      * an alert dialog. The {@link ConnectionService} is responsible for providing and localizing
177      * this message. If there is no string provided, returns null.
178      *
179      * @return The disconnect description.
180      */
getDescription()181     public CharSequence getDescription() {
182         return mDisconnectDescription;
183     }
184 
185     /**
186      * Returns an explanation of the reason for the disconnect. This is not intended for display to
187      * the user and is used mainly for logging.
188      *
189      * @return The disconnect reason.
190      */
getReason()191     public String getReason() {
192         return mDisconnectReason;
193     }
194 
195     /**
196      * Returns the tone to play when disconnected.
197      *
198      * @return the tone as defined in {@link ToneGenerator} to play when disconnected.
199      */
getTone()200     public int getTone() {
201         return mToneToPlay;
202     }
203 
204     public static final Creator<DisconnectCause> CREATOR = new Creator<DisconnectCause>() {
205         @Override
206         public DisconnectCause createFromParcel(Parcel source) {
207             int code = source.readInt();
208             CharSequence label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
209             CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
210             String reason = source.readString();
211             int tone = source.readInt();
212             return new DisconnectCause(code, label, description, reason, tone);
213         }
214 
215         @Override
216         public DisconnectCause[] newArray(int size) {
217             return new DisconnectCause[size];
218         }
219     };
220 
221     @Override
writeToParcel(Parcel destination, int flags)222     public void writeToParcel(Parcel destination, int flags) {
223         destination.writeInt(mDisconnectCode);
224         TextUtils.writeToParcel(mDisconnectLabel, destination, flags);
225         TextUtils.writeToParcel(mDisconnectDescription, destination, flags);
226         destination.writeString(mDisconnectReason);
227         destination.writeInt(mToneToPlay);
228     }
229 
230     @Override
describeContents()231     public int describeContents() {
232         return 0;
233     }
234 
235     @Override
hashCode()236     public int hashCode() {
237         return Objects.hashCode(mDisconnectCode)
238                 + Objects.hashCode(mDisconnectLabel)
239                 + Objects.hashCode(mDisconnectDescription)
240                 + Objects.hashCode(mDisconnectReason)
241                 + Objects.hashCode(mToneToPlay);
242     }
243 
244     @Override
equals(Object o)245     public boolean equals(Object o) {
246         if (o instanceof DisconnectCause) {
247             DisconnectCause d = (DisconnectCause) o;
248             return Objects.equals(mDisconnectCode, d.getCode())
249                     && Objects.equals(mDisconnectLabel, d.getLabel())
250                     && Objects.equals(mDisconnectDescription, d.getDescription())
251                     && Objects.equals(mDisconnectReason, d.getReason())
252                     && Objects.equals(mToneToPlay, d.getTone());
253         }
254         return false;
255     }
256 
257     @Override
toString()258     public String toString() {
259         String code = "";
260         switch (mDisconnectCode) {
261             case UNKNOWN:
262                 code = "UNKNOWN";
263                 break;
264             case ERROR:
265                 code = "ERROR";
266                 break;
267             case LOCAL:
268                 code = "LOCAL";
269                 break;
270             case REMOTE:
271                 code = "REMOTE";
272                 break;
273             case CANCELED:
274                 code = "CANCELED";
275                 break;
276             case MISSED:
277                 code = "MISSED";
278                 break;
279             case REJECTED:
280                 code = "REJECTED";
281                 break;
282             case BUSY:
283                 code = "BUSY";
284                 break;
285             case RESTRICTED:
286                 code = "RESTRICTED";
287                 break;
288             case OTHER:
289                 code = "OTHER";
290                 break;
291             case CONNECTION_MANAGER_NOT_SUPPORTED:
292                 code = "CONNECTION_MANAGER_NOT_SUPPORTED";
293                 break;
294             case CALL_PULLED:
295                 code = "CALL_PULLED";
296                 break;
297             case ANSWERED_ELSEWHERE:
298                 code = "ANSWERED_ELSEWHERE";
299                 break;
300             default:
301                 code = "invalid code: " + mDisconnectCode;
302                 break;
303         }
304         String label = mDisconnectLabel == null ? "" : mDisconnectLabel.toString();
305         String description = mDisconnectDescription == null
306                 ? "" : mDisconnectDescription.toString();
307         String reason = mDisconnectReason == null ? "" : mDisconnectReason;
308         return "DisconnectCause [ Code: (" + code + ")"
309                 + " Label: (" + label + ")"
310                 + " Description: (" + description + ")"
311                 + " Reason: (" + reason + ")"
312                 + " Tone: (" + mToneToPlay + ") ]";
313     }
314 }
315