blob: 0b0de6bd166061b1e6c091ed29a6e95df54ee382 [file] [log] [blame]
Thomas Stuart9bfb2432022-09-27 15:02:07 -07001/*
2 * Copyright (C) 2022 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.annotation.IntDef;
20import android.annotation.Nullable;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.text.TextUtils;
24
25import androidx.annotation.NonNull;
26
27import java.lang.annotation.Retention;
28import java.lang.annotation.RetentionPolicy;
29
30/**
31 * This class defines exceptions that can be thrown when using Telecom APIs with
32 * {@link android.os.OutcomeReceiver}s. Most of these exceptions are thrown when changing a call
33 * state with {@link CallControl}s or {@link CallEventCallback}s.
34 */
35public final class CallException extends RuntimeException implements Parcelable {
36 /** @hide **/
37 public static final String TRANSACTION_EXCEPTION_KEY = "TelecomTransactionalExceptionKey";
38
39 /**
40 * The operation has failed due to an unknown or unspecified error.
41 */
42 public static final int CODE_ERROR_UNKNOWN = 1;
43
44 /**
45 * The operation has failed due to Telecom failing to hold the current active call for the
46 * call attempting to become the new active call. The client should end the current active call
47 * and re-try the failed operation.
48 */
49 public static final int CODE_CANNOT_HOLD_CURRENT_ACTIVE_CALL = 2;
50
51 /**
52 * The operation has failed because Telecom has already removed the call from the server side
53 * and destroyed all the objects associated with it. The client should re-add the call.
54 */
55 public static final int CODE_CALL_IS_NOT_BEING_TRACKED = 3;
56
57 /**
58 * The operation has failed because Telecom cannot set the requested call as the current active
59 * call. The client should end the current active call and re-try the operation.
60 */
61 public static final int CODE_CALL_CANNOT_BE_SET_TO_ACTIVE = 4;
62
63 /**
64 * The operation has failed because there is either no PhoneAccount registered with Telecom
65 * for the given operation, or the limit of calls has been reached. The client should end the
66 * current active call and re-try the failed operation.
67 */
68 public static final int CODE_CALL_NOT_PERMITTED_AT_PRESENT_TIME = 5;
69
70 /**
71 * The operation has failed because the operation failed to complete before the timeout
72 */
73 public static final int CODE_OPERATION_TIMED_OUT = 6;
74
75 private int mCode = CODE_ERROR_UNKNOWN;
76 private final String mMessage;
77
78 @Override
79 public int describeContents() {
80 return 0;
81 }
82
83 @Override
84 public void writeToParcel(@NonNull Parcel dest, int flags) {
85 dest.writeString8(mMessage);
86 dest.writeInt(mCode);
87 }
88
89 /**
90 * Responsible for creating CallAttribute objects for deserialized Parcels.
91 */
92 public static final @android.annotation.NonNull
93 Parcelable.Creator<CallException> CREATOR = new Parcelable.Creator<>() {
94 @Override
95 public CallException createFromParcel(Parcel source) {
96 return new CallException(source.readString8(), source.readInt());
97 }
98
99 @Override
100 public CallException[] newArray(int size) {
101 return new CallException[size];
102 }
103 };
104
105 /** @hide */
106 @Retention(RetentionPolicy.SOURCE)
107 @IntDef(prefix = "CODE_ERROR_", value = {
108 CODE_ERROR_UNKNOWN,
109 CODE_CANNOT_HOLD_CURRENT_ACTIVE_CALL,
110 CODE_CALL_IS_NOT_BEING_TRACKED,
111 CODE_CALL_CANNOT_BE_SET_TO_ACTIVE,
112 CODE_CALL_NOT_PERMITTED_AT_PRESENT_TIME,
113 CODE_OPERATION_TIMED_OUT
114 })
115 public @interface CallErrorCode {
116 }
117
118 /**
119 * Constructor for a new CallException when only message can be specified.
120 * {@code CODE_ERROR_UNKNOWN} will be default code returned when calling {@code getCode}
121 *
122 * @param message related to why the exception was created
123 */
124 public CallException(@Nullable String message) {
125 super(getMessage(message, CODE_ERROR_UNKNOWN));
126 mMessage = message;
127 }
128
129 /**
130 * Constructor for a new CallException that has a defined error code in this class
131 *
132 * @param message related to why the exception was created
133 * @param code defined above that caused this exception to be created
134 */
135 public CallException(@Nullable String message, @CallErrorCode int code) {
136 super(getMessage(message, code));
137 mCode = code;
138 mMessage = message;
139 }
140
141 /**
142 * @return one of the error codes defined in this class that was passed into the constructor
143 */
144 public @CallErrorCode int getCode() {
145 return mCode;
146 }
147
148 private static String getMessage(String message, int code) {
149 StringBuilder builder;
150 if (!TextUtils.isEmpty(message)) {
151 builder = new StringBuilder(message);
152 builder.append(" (code: ");
153 builder.append(code);
154 builder.append(")");
155 return builder.toString();
156 } else {
157 return "code: " + code;
158 }
159 }
160}