• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.net.thread;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.annotation.FlaggedApi;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.SystemApi;
25 
26 import com.android.net.thread.flags.Flags;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 
31 /**
32  * Represents a Thread network specific failure.
33  *
34  * @hide
35  */
36 @FlaggedApi(Flags.FLAG_THREAD_ENABLED)
37 @SystemApi
38 public class ThreadNetworkException extends Exception {
39     /** @hide */
40     @Retention(RetentionPolicy.SOURCE)
41     @IntDef({
42         ERROR_INTERNAL_ERROR,
43         ERROR_ABORTED,
44         ERROR_TIMEOUT,
45         ERROR_UNAVAILABLE,
46         ERROR_BUSY,
47         ERROR_FAILED_PRECONDITION,
48         ERROR_UNSUPPORTED_CHANNEL,
49         ERROR_REJECTED_BY_PEER,
50         ERROR_RESPONSE_BAD_FORMAT,
51         ERROR_RESOURCE_EXHAUSTED,
52         ERROR_UNKNOWN,
53         ERROR_THREAD_DISABLED,
54     })
55     public @interface ErrorCode {}
56 
57     /**
58      * The operation failed because some invariants expected by the underlying system have been
59      * broken. This error code is reserved for serious errors. The caller can do nothing to recover
60      * from this error. A bugreport should be created and sent to the Android community if this
61      * error is ever returned.
62      */
63     public static final int ERROR_INTERNAL_ERROR = 1;
64 
65     /**
66      * The operation failed because concurrent operations are overriding this one. Retrying an
67      * aborted operation has the risk of aborting another ongoing operation again. So the caller
68      * should retry at a higher level where it knows there won't be race conditions.
69      */
70     public static final int ERROR_ABORTED = 2;
71 
72     /**
73      * The operation failed because a deadline expired before the operation could complete. This may
74      * be caused by connectivity unavailability and the caller can retry the same operation when the
75      * connectivity issue is fixed.
76      */
77     public static final int ERROR_TIMEOUT = 3;
78 
79     /**
80      * The operation failed because the service is currently unavailable and that this is most
81      * likely a transient condition. The caller can recover from this error by retrying with a
82      * back-off scheme. Note that it is not always safe to retry non-idempotent operations.
83      */
84     public static final int ERROR_UNAVAILABLE = 4;
85 
86     /**
87      * The operation failed because this device is currently busy processing concurrent requests.
88      * The caller may recover from this error when the current operations has been finished.
89      */
90     public static final int ERROR_BUSY = 5;
91 
92     /**
93      * The operation failed because required preconditions were not satisfied. For example, trying
94      * to schedule a network migration when this device is not attached will receive this error or
95      * enable Thread while User Resitration has disabled it. The caller should not retry the same
96      * operation before the precondition is satisfied.
97      */
98     public static final int ERROR_FAILED_PRECONDITION = 6;
99 
100     /**
101      * The operation was rejected because the specified channel is currently not supported by this
102      * device in this country. For example, trying to join or migrate to a network with channel
103      * which is not supported. The caller should should change the channel or return an error to the
104      * user if the channel cannot be changed.
105      */
106     public static final int ERROR_UNSUPPORTED_CHANNEL = 7;
107 
108     /**
109      * The operation failed because a request is rejected by the peer device. This happens because
110      * the peer device is not capable of processing the request, or a request from another device
111      * has already been accepted by the peer device. The caller may not be able to recover from this
112      * error by retrying the same operation.
113      */
114     public static final int ERROR_REJECTED_BY_PEER = 8;
115 
116     /**
117      * The operation failed because the received response is malformed. This is typically because
118      * the peer device is misbehaving. The caller may only recover from this error by retrying with
119      * a different peer device.
120      */
121     public static final int ERROR_RESPONSE_BAD_FORMAT = 9;
122 
123     /**
124      * The operation failed because some resource has been exhausted. For example, no enough
125      * allocated memory buffers, or maximum number of supported operations has been exceeded. The
126      * caller may retry and recover from this error when the resource has been freed.
127      */
128     public static final int ERROR_RESOURCE_EXHAUSTED = 10;
129 
130     /**
131      * The operation failed because of an unknown error in the system. This typically indicates that
132      * the caller doesn't understand error codes added in newer Android versions.
133      */
134     public static final int ERROR_UNKNOWN = 11;
135 
136     /**
137      * The operation failed because the Thread radio is disabled by {@link
138      * ThreadNetworkController#setEnabled}, airplane mode or device admin. The caller should retry
139      * only after Thread is enabled.
140      */
141     public static final int ERROR_THREAD_DISABLED = 12;
142 
143     /**
144      * The operation failed because the feature is not supported by the platform. For example, some
145      * platforms may not support setting the target power of each channel. The caller should not
146      * retry and may return an error to the user.
147      */
148     public static final int ERROR_UNSUPPORTED_FEATURE = 13;
149 
150     private static final int ERROR_MIN = ERROR_INTERNAL_ERROR;
151     private static final int ERROR_MAX = ERROR_UNSUPPORTED_FEATURE;
152 
153     private final int mErrorCode;
154 
155     /**
156      * Creates a new {@link ThreadNetworkException} object with given error code and message.
157      *
158      * @throws IllegalArgumentException if {@code errorCode} is not a value in {@link #ERROR_}
159      * @throws NullPointerException if {@code message} is {@code null}
160      */
ThreadNetworkException(@rrorCode int errorCode, @NonNull String message)161     public ThreadNetworkException(@ErrorCode int errorCode, @NonNull String message) {
162         super(requireNonNull(message, "message cannot be null"));
163         if (errorCode < ERROR_MIN || errorCode > ERROR_MAX) {
164             throw new IllegalArgumentException(
165                     "errorCode cannot be "
166                             + errorCode
167                             + " (allowedRange = ["
168                             + ERROR_MIN
169                             + ", "
170                             + ERROR_MAX
171                             + "])");
172         }
173         this.mErrorCode = errorCode;
174     }
175 
176     /** Returns the error code. */
getErrorCode()177     public @ErrorCode int getErrorCode() {
178         return mErrorCode;
179     }
180 }
181