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