• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 package com.android.extensions.appfunctions;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Bundle;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 
26 /** Represents an app function related errors. */
27 public final class AppFunctionException extends Exception {
28     /**
29      * The caller does not have the permission to execute an app function.
30      *
31      * <p>This error is in the {@link #ERROR_CATEGORY_REQUEST_ERROR} category.
32      */
33     public static final int ERROR_DENIED = 1000;
34 
35     /**
36      * The caller supplied invalid arguments to the execution request.
37      *
38      * <p>This error may be considered similar to {@link IllegalArgumentException}.
39      *
40      * <p>This error is in the {@link #ERROR_CATEGORY_REQUEST_ERROR} category.
41      */
42     public static final int ERROR_INVALID_ARGUMENT = 1001;
43 
44     /**
45      * The caller tried to execute a disabled app function.
46      *
47      * <p>This error is in the {@link #ERROR_CATEGORY_REQUEST_ERROR} category.
48      */
49     public static final int ERROR_DISABLED = 1002;
50 
51     /**
52      * The caller tried to execute a function that does not exist.
53      *
54      * <p>This error is in the {@link #ERROR_CATEGORY_REQUEST_ERROR} category.
55      */
56     public static final int ERROR_FUNCTION_NOT_FOUND = 1003;
57 
58     /**
59      * An internal unexpected error coming from the system.
60      *
61      * <p>This error is in the {@link #ERROR_CATEGORY_SYSTEM} category.
62      */
63     public static final int ERROR_SYSTEM_ERROR = 2000;
64 
65     /**
66      * The operation was cancelled. Use this error code to report that a cancellation is done after
67      * receiving a cancellation signal.
68      *
69      * <p>This error is in the {@link #ERROR_CATEGORY_SYSTEM} category.
70      */
71     public static final int ERROR_CANCELLED = 2001;
72 
73     /**
74      * The operation was disallowed by enterprise policy.
75      *
76      * <p>This error is in the {@link #ERROR_CATEGORY_SYSTEM} category.
77      */
78     public static final int ERROR_ENTERPRISE_POLICY_DISALLOWED = 2002;
79 
80     /**
81      * An unknown error occurred while processing the call in the AppFunctionService.
82      *
83      * <p>This error is thrown when the service is connected in the remote application but an
84      * unexpected error is thrown from the bound application.
85      *
86      * <p>This error is in the {@link #ERROR_CATEGORY_APP} category.
87      */
88     public static final int ERROR_APP_UNKNOWN_ERROR = 3000;
89 
90     /**
91      * The error category is unknown.
92      *
93      * <p>This is the default value for {@link #getErrorCategory}.
94      */
95     public static final int ERROR_CATEGORY_UNKNOWN = 0;
96 
97     /**
98      * The error is caused by the app requesting a function execution.
99      *
100      * <p>For example, the caller provided invalid parameters in the execution request e.g. an
101      * invalid function ID.
102      *
103      * <p>Errors in the category fall in the range 1000-1999 inclusive.
104      */
105     public static final int ERROR_CATEGORY_REQUEST_ERROR = 1;
106 
107     /**
108      * The error is caused by an issue in the system.
109      *
110      * <p>For example, the AppFunctionService implementation is not found by the system.
111      *
112      * <p>Errors in the category fall in the range 2000-2999 inclusive.
113      */
114     public static final int ERROR_CATEGORY_SYSTEM = 2;
115 
116     /**
117      * The error is caused by the app providing the function.
118      *
119      * <p>For example, the app crashed when the system is executing the request.
120      *
121      * <p>Errors in the category fall in the range 3000-3999 inclusive.
122      */
123     public static final int ERROR_CATEGORY_APP = 3;
124 
125     private final int mErrorCode;
126     @Nullable private final String mErrorMessage;
127     @NonNull private final Bundle mExtras;
128 
AppFunctionException(int errorCode, @Nullable String errorMessage)129     public AppFunctionException(int errorCode, @Nullable String errorMessage) {
130         this(errorCode, errorMessage, Bundle.EMPTY);
131     }
132 
AppFunctionException( int errorCode, @Nullable String errorMessage, @NonNull Bundle extras)133     public AppFunctionException(
134             int errorCode, @Nullable String errorMessage, @NonNull Bundle extras) {
135         super(errorMessage);
136         mErrorCode = errorCode;
137         mErrorMessage = errorMessage;
138         mExtras = extras;
139     }
140 
141     /** Returns one of the {@code ERROR} constants. */
142     @ErrorCode
getErrorCode()143     public int getErrorCode() {
144         return mErrorCode;
145     }
146 
147     /** Returns the error message. */
148     @Nullable
getErrorMessage()149     public String getErrorMessage() {
150         return mErrorMessage;
151     }
152 
153     /**
154      * Returns the error category.
155      *
156      * <p>This method categorizes errors based on their underlying cause, allowing developers to
157      * implement targeted error handling and provide more informative error messages to users. It
158      * maps ranges of error codes to specific error categories.
159      *
160      * <p>This method returns {@code ERROR_CATEGORY_UNKNOWN} if the error code does not belong to
161      * any error category.
162      *
163      * <p>See {@link ErrorCategory} for a complete list of error categories and their corresponding
164      * error code ranges.
165      */
166     @ErrorCategory
getErrorCategory()167     public int getErrorCategory() {
168         if (mErrorCode >= 1000 && mErrorCode < 2000) {
169             return ERROR_CATEGORY_REQUEST_ERROR;
170         }
171         if (mErrorCode >= 2000 && mErrorCode < 3000) {
172             return ERROR_CATEGORY_SYSTEM;
173         }
174         if (mErrorCode >= 3000 && mErrorCode < 4000) {
175             return ERROR_CATEGORY_APP;
176         }
177         return ERROR_CATEGORY_UNKNOWN;
178     }
179 
180     @NonNull
getExtras()181     public Bundle getExtras() {
182         return mExtras;
183     }
184 
185     /**
186      * Error codes.
187      *
188      * @hide
189      */
190     @IntDef(
191             prefix = {"ERROR_"},
192             value = {
193                 ERROR_DENIED,
194                 ERROR_APP_UNKNOWN_ERROR,
195                 ERROR_FUNCTION_NOT_FOUND,
196                 ERROR_SYSTEM_ERROR,
197                 ERROR_INVALID_ARGUMENT,
198                 ERROR_DISABLED,
199                 ERROR_CANCELLED,
200                 ERROR_ENTERPRISE_POLICY_DISALLOWED
201             })
202     @Retention(RetentionPolicy.SOURCE)
203     public @interface ErrorCode {}
204 
205     /**
206      * Error categories.
207      *
208      * @hide
209      */
210     @IntDef(
211             prefix = {"ERROR_CATEGORY_"},
212             value = {
213                 ERROR_CATEGORY_UNKNOWN,
214                 ERROR_CATEGORY_REQUEST_ERROR,
215                 ERROR_CATEGORY_APP,
216                 ERROR_CATEGORY_SYSTEM
217             })
218     @Retention(RetentionPolicy.SOURCE)
219     public @interface ErrorCategory {}
220 }
221