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