1 /*
2  * Copyright (c) 2019 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.telephony.ims;
18 
19 import android.annotation.IntDef;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.annotation.TestApi;
23 import android.content.pm.PackageManager;
24 import android.telephony.SubscriptionManager;
25 import android.text.TextUtils;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 
30 /**
31  * This class defines an IMS-related exception that has been thrown while interacting with a
32  * device or carrier provided ImsService implementation.
33  */
34 public final class ImsException extends Exception {
35 
36     /**
37      * The operation has failed due to an unknown or unspecified error.
38      */
39     public static final int CODE_ERROR_UNSPECIFIED = 0;
40     /**
41      * The operation has failed because there is no remote process available to service it. This
42      * may be due to a process crash or other illegal state.
43      * <p>
44      * This is a temporary error and the operation may be retried until the connection to the
45      * remote process is restored.
46      */
47     public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1;
48 
49     /**
50      * This device or carrier configuration does not support this feature for this subscription.
51      * <p>
52      * This is a permanent configuration error and there should be no retry until the subscription
53      * changes if this operation is denied due to a carrier configuration. If this is due to a
54      * device configuration, the feature {@link PackageManager#FEATURE_TELEPHONY_IMS} is not
55      * available or the device has no ImsService implementation to service this request.
56      */
57     public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2;
58 
59     /**
60      * The subscription ID associated with this operation is invalid or not active.
61      * <p>
62      * This is a configuration error and there should be no retry. The subscription used for this
63      * operation is either invalid or has become inactive. The active subscriptions can be queried
64      * with {@link SubscriptionManager#getActiveSubscriptionInfoList()}.
65      */
66     public static final int CODE_ERROR_INVALID_SUBSCRIPTION = 3;
67 
68     /**@hide*/
69     @Retention(RetentionPolicy.SOURCE)
70     @IntDef(prefix = "CODE_ERROR_", value = {
71             CODE_ERROR_UNSPECIFIED,
72             CODE_ERROR_SERVICE_UNAVAILABLE,
73             CODE_ERROR_UNSUPPORTED_OPERATION,
74             CODE_ERROR_INVALID_SUBSCRIPTION
75     })
76     public @interface ImsErrorCode {}
77 
78     private int mCode = CODE_ERROR_UNSPECIFIED;
79 
80     /**
81      * A new {@link ImsException} with an unspecified {@link ImsErrorCode} code.
82      * @param message an optional message to detail the error condition more specifically.
83      * @hide
84      */
85     @SystemApi
86     @TestApi
ImsException(@ullable String message)87     public ImsException(@Nullable String message) {
88         super(getMessage(message, CODE_ERROR_UNSPECIFIED));
89     }
90 
91     /**
92      * A new {@link ImsException} that includes an {@link ImsErrorCode} error code.
93      * @param message an optional message to detail the error condition more specifically.
94      * @hide
95      */
96     @SystemApi
97     @TestApi
ImsException(@ullable String message, @ImsErrorCode int code)98     public ImsException(@Nullable String message, @ImsErrorCode int code) {
99         super(getMessage(message, code));
100         mCode = code;
101     }
102 
103     /**
104      * A new {@link ImsException} that includes an {@link ImsErrorCode} error code and a
105      * {@link Throwable} that contains the original error that was thrown to lead to this Exception.
106      * @param message an optional message to detail the error condition more specifically.
107      * @param cause the {@link Throwable} that caused this {@link ImsException} to be created.
108      * @hide
109      */
110     @SystemApi
111     @TestApi
ImsException(@ullable String message, @ImsErrorCode int code, @Nullable Throwable cause)112     public ImsException(@Nullable String message, @ImsErrorCode  int code,
113             @Nullable Throwable cause) {
114         super(getMessage(message, code), cause);
115         mCode = code;
116     }
117 
118     /**
119      * @return the IMS Error code that is associated with this {@link ImsException}.
120      */
getCode()121     public @ImsErrorCode int getCode() {
122         return mCode;
123     }
124 
getMessage(String message, int code)125     private static String getMessage(String message, int code) {
126         StringBuilder builder;
127         if (!TextUtils.isEmpty(message)) {
128             builder = new StringBuilder(message);
129             builder.append(" (code: ");
130             builder.append(code);
131             builder.append(")");
132             return builder.toString();
133         } else {
134             return "code: " + code;
135         }
136     }
137 }
138