1 /* 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 17 package android.adservices.common; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.os.LimitExceededException; 22 23 import com.android.adservices.shared.common.exception.ProviderServiceInternalException; 24 import com.android.adservices.shared.common.exception.ProviderServiceTaskCancelledException; 25 import com.android.adservices.shared.common.exception.ServiceUnavailableException; 26 27 import java.io.IOException; 28 import java.io.InvalidObjectException; 29 import java.lang.annotation.Retention; 30 import java.lang.annotation.RetentionPolicy; 31 import java.util.concurrent.TimeoutException; 32 33 /** 34 * Utility class containing status codes and functions used by various response objects. 35 * 36 * <p>Those status codes are internal only. 37 * 38 * @hide 39 */ 40 public final class AdServicesStatusUtils { 41 42 /** 43 * The status code has not been set. Keep unset status code the lowest value of the status 44 * codes. 45 */ 46 public static final int STATUS_UNSET = -1; 47 48 /** The call was successful. */ 49 public static final int STATUS_SUCCESS = 0; 50 51 /** 52 * An internal error occurred within the API, which the caller cannot address. 53 * 54 * <p>This error may be considered similar to {@link IllegalStateException}. 55 */ 56 public static final int STATUS_INTERNAL_ERROR = 1; 57 58 /** 59 * The caller supplied invalid arguments to the call. 60 * 61 * <p>This error may be considered similar to {@link IllegalArgumentException}. 62 */ 63 public static final int STATUS_INVALID_ARGUMENT = 2; 64 65 /** There was an unknown error. */ 66 public static final int STATUS_UNKNOWN_ERROR = 3; 67 68 /** 69 * There was an I/O error. 70 * 71 * <p>This error may be considered similar to {@link IOException}. 72 */ 73 public static final int STATUS_IO_ERROR = 4; 74 75 /** 76 * Result code for Rate Limit Reached. 77 * 78 * <p>This error may be considered similar to {@link LimitExceededException}. 79 */ 80 public static final int STATUS_RATE_LIMIT_REACHED = 5; 81 82 /** 83 * Killswitch was enabled. AdServices is not available. 84 * 85 * <p>This error may be considered similar to {@link IllegalStateException}. 86 */ 87 public static final int STATUS_KILLSWITCH_ENABLED = 6; 88 89 /** 90 * User consent was revoked. AdServices is not available. 91 * 92 * <p>This error may be considered similar to {@link IllegalStateException}. 93 */ 94 public static final int STATUS_USER_CONSENT_REVOKED = 7; 95 96 /** 97 * AdServices were disabled. AdServices is not available. 98 * 99 * <p>This error may be considered similar to {@link IllegalStateException}. 100 */ 101 public static final int STATUS_ADSERVICES_DISABLED = 8; 102 103 /** 104 * The caller is not authorized to make this call. Permission was not requested. 105 * 106 * <p>This error may be considered similar to {@link SecurityException}. 107 */ 108 public static final int STATUS_PERMISSION_NOT_REQUESTED = 9; 109 110 /** 111 * The caller is not authorized to make this call. Caller is not allowed (not present in the 112 * allowed list). 113 * 114 * <p>This error may be considered similar to {@link SecurityException}. 115 */ 116 public static final int STATUS_CALLER_NOT_ALLOWED = 10; 117 118 /** 119 * The caller is not authorized to make this call. Call was executed from background thread. 120 * 121 * <p>This error may be considered similar to {@link IllegalStateException}. 122 */ 123 public static final int STATUS_BACKGROUND_CALLER = 11; 124 125 /** 126 * The caller is not authorized to make this call. 127 * 128 * <p>This error may be considered similar to {@link SecurityException}. 129 */ 130 public static final int STATUS_UNAUTHORIZED = 12; 131 132 /** 133 * There was an internal Timeout within the API, which is non-recoverable by the caller 134 * 135 * <p>This error may be considered similar to {@link java.util.concurrent.TimeoutException} 136 */ 137 public static final int STATUS_TIMEOUT = 13; 138 139 /** 140 * The device is not running a version of WebView that supports JSSandbox, required for FLEDGE 141 * Ad Selection. 142 * 143 * <p>This error may be considered similar to {@link IllegalStateException}. 144 */ 145 public static final int STATUS_JS_SANDBOX_UNAVAILABLE = 14; 146 147 /** 148 * The service received an invalid object from the remote server. 149 * 150 * <p>This error may be considered similar to {@link InvalidObjectException}. 151 */ 152 public static final int STATUS_INVALID_OBJECT = 15; 153 154 /** 155 * The caller is not authorized to make this call because it crosses user boundaries. 156 * 157 * <p>This error may be considered similar to {@link SecurityException}. 158 */ 159 public static final int STATUS_CALLER_NOT_ALLOWED_TO_CROSS_USER_BOUNDARIES = 16; 160 161 /** 162 * Result code for Server Rate Limit Reached. 163 * 164 * <p>This error may be considered similar to {@link LimitExceededException}. 165 */ 166 public static final int STATUS_SERVER_RATE_LIMIT_REACHED = 17; 167 168 /** 169 * Consent notification has not been displayed yet. AdServices is not available. 170 * 171 * <p>This error may be considered similar to {@link IllegalStateException}. 172 */ 173 public static final int STATUS_USER_CONSENT_NOTIFICATION_NOT_DISPLAYED_YET = 18; 174 175 /** 176 * Result code for Encryption related failures. 177 * 178 * <p>This error may be considered similar to {@link IllegalArgumentException}. 179 */ 180 public static final int STATUS_ENCRYPTION_FAILURE = 19; 181 182 /** 183 * The caller is not authorized to make this call because the package is not in the allowlist. 184 * 185 * <p>This error may be considered similar to {@link SecurityException}. 186 */ 187 public static final int STATUS_CALLER_NOT_ALLOWED_PACKAGE_NOT_IN_ALLOWLIST = 20; 188 189 /** 190 * The caller is not authorized to make this call because the package is not in the allowlist. 191 * 192 * <p>This error may be considered similar to {@link SecurityException}. 193 */ 194 public static final int STATUS_CALLER_NOT_ALLOWED_PACKAGE_BLOCKLISTED = 21; 195 196 /** 197 * The caller is not authorized to make this call because enrollment data can't be found. 198 * 199 * <p>This error may be considered similar to {@link SecurityException}. 200 */ 201 public static final int STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_MATCH_NOT_FOUND = 22; 202 203 /** 204 * The caller is not authorized to make this call because enrollment ID is invalid. 205 * 206 * <p>This error may be considered similar to {@link SecurityException}. 207 */ 208 public static final int STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_INVALID_ID = 23; 209 210 /** 211 * The caller is not authorized to make this call because enrollment ID is in the blocklist. 212 * 213 * <p>This error may be considered similar to {@link SecurityException}. 214 */ 215 public static final int STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_BLOCKLISTED = 24; 216 217 /** 218 * The caller is not authorized to make this call because permission was not requested in the 219 * manifest. 220 * 221 * <p>This error may be considered similar to {@link SecurityException}. 222 */ 223 public static final int STATUS_CALLER_NOT_ALLOWED_MANIFEST_ADSERVICES_CONFIG_NO_PERMISSION = 25; 224 225 /** 226 * AdServices activity is disabled. 227 * 228 * <p>This error may be considered similar to {@link IllegalStateException}. 229 */ 230 public static final int STATUS_ADSERVICES_ACTIVITY_DISABLED = 26; 231 232 /** 233 * Callback is shut down and encountered an error when invoking its methods. 234 * 235 * <p>This error may be considered similar to {@link IllegalStateException}. 236 */ 237 public static final int STATUS_CALLBACK_SHUTDOWN = 27; 238 239 /** 240 * The provider service throws an error as the callback when AdServices tries to call it. 241 * 242 * <p>This error may be considered similar to {@link IllegalStateException}. 243 */ 244 public static final int STATUS_PROVIDER_SERVICE_INTERNAL_ERROR = 28; 245 246 /** 247 * The scheduleCustomAudienceUpdate() request failed because an existing update has not been 248 * executed yet and should be explicitly replaced by the caller. 249 * 250 * <p>This error throws an {@link IllegalStateException}. 251 */ 252 public static final int STATUS_UPDATE_ALREADY_PENDING_ERROR = 29; 253 254 /** This error denotes that consent was revoked for all APIS. */ 255 public static final int STATUS_CONSENT_REVOKED_ALL_APIS = 30; 256 257 /** This error occurs when a dev session is still transitioning between prod or dev. */ 258 public static final int STATUS_DEV_SESSION_IS_STILL_TRANSITIONING = 31; 259 260 /** This error occurs when a non-debuggable app is calling during a dev session. */ 261 public static final int STATUS_DEV_SESSION_CALLER_IS_NON_DEBUGGABLE = 32; 262 263 /** This error occurs when dev session state is unable to be read. */ 264 public static final int STATUS_DEV_SESSION_FAILURE = 33; 265 266 /** This error occurs when the caller is in the deny list. */ 267 public static final int STATUS_CALLER_NOT_ALLOWED_DENY_LIST = 34; 268 269 /** 270 * This error occurs when the package name associated to the calling UID does not match the 271 * package name from the request. 272 */ 273 public static final int STATUS_CALLER_NOT_ALLOWED_UID_MISMATCH = 35; 274 275 /** 276 * The provider service throws a task cancelled error as the callback when AdServices tries to 277 * call it. 278 * 279 * <p>This error may be considered similar to {@link IllegalStateException}. 280 */ 281 public static final int STATUS_PROVIDER_SERVICE_TASK_CANCELLED_ERROR = 36; 282 283 /** The error message to be returned along with {@link LimitExceededException}. */ 284 public static final String RATE_LIMIT_REACHED_ERROR_MESSAGE = "API rate limit exceeded."; 285 286 /** The error message to be returned along with {@link LimitExceededException}. */ 287 public static final String SERVER_RATE_LIMIT_REACHED_ERROR_MESSAGE = 288 "Server rate limit exceeded."; 289 290 /** 291 * The error message to be returned along with {@link SecurityException} when permission was not 292 * requested in the manifest. 293 */ 294 public static final String SECURITY_EXCEPTION_PERMISSION_NOT_REQUESTED_ERROR_MESSAGE = 295 "Caller is not authorized to call this API. Permission was not requested."; 296 297 /** 298 * The error message to be returned along with {@link SecurityException} when caller is not 299 * allowed to call AdServices (not present in the allowed list). 300 */ 301 public static final String SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE = 302 "Caller is not authorized to call this API. Caller is not allowed."; 303 304 /** 305 * The error message to be returned along with {@link SecurityException} when call was executed 306 * from the background thread. 307 */ 308 public static final String ILLEGAL_STATE_BACKGROUND_CALLER_ERROR_MESSAGE = 309 "Background thread is not allowed to call this service."; 310 311 /** 312 * The error message to be returned along with {@link IllegalStateException} when call failed 313 * because AdServices activity is disabled. 314 */ 315 public static final String ILLEGAL_STATE_ACTIVITY_DISABLED_ERROR_MESSAGE = 316 "AdServices activity is disabled."; 317 318 /** 319 * The error message to be returned along with {@link SecurityException} when call failed 320 * because it crosses user boundaries. 321 */ 322 public static final String SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_TO_CROSS_USER_BOUNDARIES = 323 "Caller is not authorized to access information from another user"; 324 325 /** 326 * The error message to be returned along with {@link SecurityException} when caller not allowed 327 * to perform this operation on behalf of the given package. 328 */ 329 public static final String SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ON_BEHALF_ERROR_MESSAGE = 330 "Caller is not allowed to perform this operation on behalf of the given package."; 331 332 /** The error message to be returned along with {@link TimeoutException}. */ 333 public static final String TIMED_OUT_ERROR_MESSAGE = "API timed out."; 334 335 /** The error message to be returned along with {@link InvalidObjectException}. */ 336 public static final String INVALID_OBJECT_ERROR_MESSAGE = 337 "The service received an invalid object from the server."; 338 339 /** The error message to be returned along with {@link IllegalArgumentException}. */ 340 public static final String ENCRYPTION_FAILURE_MESSAGE = "Failed to encrypt responses."; 341 342 /** The error message to be returned along with {@link ServiceUnavailableException}. */ 343 public static final String SERVICE_UNAVAILABLE_ERROR_MESSAGE = "Service is not available."; 344 345 private static final String DEV_SESSION_ERROR_TRANSITIONING_HELP = 346 "If this error persists, run `cmd adservices_manager adservices-api dev-session end` " 347 + "to reset the dev session."; 348 349 /** The error message when a dev session is still transitioning between prod or dev. */ 350 public static final String DEV_SESSION_IS_TRANSITIONING_MESSAGE = 351 "Caller is not allowed during the transition to or from dev mode. " 352 + DEV_SESSION_ERROR_TRANSITIONING_HELP; 353 354 /** The error message when a non-debuggable app is calling during a dev session. */ 355 public static final String DEV_SESSION_CALLER_IS_NON_DEBUGGABLE_MESSAGE = 356 "Caller during a dev session must have android:debuggable=\"true\" in their manifest! " 357 + DEV_SESSION_ERROR_TRANSITIONING_HELP; 358 359 /** The error message when dev session state cannot be read. */ 360 public static final String DEV_SESSION_FAILURE_MESSAGE = 361 "Failed to read dev session state. " + DEV_SESSION_ERROR_TRANSITIONING_HELP; 362 363 /** 364 * The error message returned when a call to schedule a custom audience update fails because of 365 * an existing pending update. 366 */ 367 public static final String UPDATE_ALREADY_PENDING_ERROR_MESSAGE = 368 "Failed to schedule update. A request is already pending."; 369 370 /** 371 * The error message to be returned along with {@link SecurityException} when caller is not 372 * allowed to call AdServices API (present in the deny list). 373 */ 374 public static final String CALLER_NOT_ALLOWED_DENY_LIST_ERROR_MESSAGE = 375 "Caller is not authorized to call this API as caller is in deny list."; 376 377 /** Returns true for a successful status. */ isSuccess(@tatusCode int statusCode)378 public static boolean isSuccess(@StatusCode int statusCode) { 379 return statusCode == STATUS_SUCCESS; 380 } 381 382 /** Converts the input {@code statusCode} to an exception to be used in the callback. */ 383 @NonNull asException(@tatusCode int statusCode)384 public static Exception asException(@StatusCode int statusCode) { 385 switch (statusCode) { 386 case STATUS_ENCRYPTION_FAILURE: 387 return new IllegalArgumentException(ENCRYPTION_FAILURE_MESSAGE); 388 case STATUS_INVALID_ARGUMENT: 389 return new IllegalArgumentException(); 390 case STATUS_IO_ERROR: 391 return new IOException(); 392 case STATUS_KILLSWITCH_ENABLED: // Intentional fallthrough 393 case STATUS_USER_CONSENT_NOTIFICATION_NOT_DISPLAYED_YET: // Intentional fallthrough 394 case STATUS_USER_CONSENT_REVOKED: // Intentional fallthrough 395 case STATUS_CONSENT_REVOKED_ALL_APIS: // Intentional fallthrough 396 case STATUS_JS_SANDBOX_UNAVAILABLE: 397 return new ServiceUnavailableException(SERVICE_UNAVAILABLE_ERROR_MESSAGE); 398 case STATUS_PERMISSION_NOT_REQUESTED: 399 return new SecurityException( 400 SECURITY_EXCEPTION_PERMISSION_NOT_REQUESTED_ERROR_MESSAGE); 401 case STATUS_CALLER_NOT_ALLOWED: 402 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 403 case STATUS_CALLER_NOT_ALLOWED_PACKAGE_NOT_IN_ALLOWLIST: 404 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 405 case STATUS_CALLER_NOT_ALLOWED_PACKAGE_BLOCKLISTED: 406 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 407 case STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_MATCH_NOT_FOUND: 408 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 409 case STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_INVALID_ID: 410 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 411 case STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_BLOCKLISTED: 412 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 413 case STATUS_CALLER_NOT_ALLOWED_MANIFEST_ADSERVICES_CONFIG_NO_PERMISSION: 414 return new SecurityException(SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ERROR_MESSAGE); 415 case STATUS_BACKGROUND_CALLER: 416 return new IllegalStateException(ILLEGAL_STATE_BACKGROUND_CALLER_ERROR_MESSAGE); 417 case STATUS_ADSERVICES_ACTIVITY_DISABLED: 418 return new IllegalStateException(ILLEGAL_STATE_ACTIVITY_DISABLED_ERROR_MESSAGE); 419 case STATUS_UPDATE_ALREADY_PENDING_ERROR: 420 return new IllegalStateException(UPDATE_ALREADY_PENDING_ERROR_MESSAGE); 421 case STATUS_UNAUTHORIZED: 422 return new SecurityException( 423 SECURITY_EXCEPTION_CALLER_NOT_ALLOWED_ON_BEHALF_ERROR_MESSAGE); 424 case STATUS_TIMEOUT: 425 return new TimeoutException(TIMED_OUT_ERROR_MESSAGE); 426 case STATUS_RATE_LIMIT_REACHED: 427 return new LimitExceededException(RATE_LIMIT_REACHED_ERROR_MESSAGE); 428 case STATUS_INVALID_OBJECT: 429 return new InvalidObjectException(INVALID_OBJECT_ERROR_MESSAGE); 430 case STATUS_SERVER_RATE_LIMIT_REACHED: 431 return new LimitExceededException(SERVER_RATE_LIMIT_REACHED_ERROR_MESSAGE); 432 case STATUS_PROVIDER_SERVICE_INTERNAL_ERROR: 433 return new ProviderServiceInternalException(); 434 case STATUS_PROVIDER_SERVICE_TASK_CANCELLED_ERROR: 435 return new ProviderServiceTaskCancelledException(); 436 case STATUS_DEV_SESSION_IS_STILL_TRANSITIONING: 437 return new IllegalStateException(DEV_SESSION_IS_TRANSITIONING_MESSAGE); 438 case STATUS_DEV_SESSION_CALLER_IS_NON_DEBUGGABLE: 439 return new SecurityException(DEV_SESSION_CALLER_IS_NON_DEBUGGABLE_MESSAGE); 440 case STATUS_DEV_SESSION_FAILURE: 441 return new IllegalStateException(DEV_SESSION_FAILURE_MESSAGE); 442 case STATUS_CALLER_NOT_ALLOWED_DENY_LIST: 443 return new SecurityException(CALLER_NOT_ALLOWED_DENY_LIST_ERROR_MESSAGE); 444 default: 445 return new IllegalStateException(); 446 } 447 } 448 449 /** Converts the {@link AdServicesResponse} to an exception to be used in the callback. */ 450 // TODO(b/328601595): Add unit test for AdServicesStatusUtils.asException 451 @NonNull asException(@onNull AdServicesResponse adServicesResponse)452 public static Exception asException(@NonNull AdServicesResponse adServicesResponse) { 453 return asException(adServicesResponse.getStatusCode()); 454 } 455 456 /** 457 * Result codes that are common across various APIs. 458 * 459 * @hide 460 */ 461 @IntDef( 462 prefix = {"STATUS_"}, 463 value = { 464 STATUS_UNSET, 465 STATUS_SUCCESS, 466 STATUS_INTERNAL_ERROR, 467 STATUS_INVALID_ARGUMENT, 468 STATUS_RATE_LIMIT_REACHED, 469 STATUS_UNKNOWN_ERROR, 470 STATUS_IO_ERROR, 471 STATUS_KILLSWITCH_ENABLED, 472 STATUS_USER_CONSENT_REVOKED, 473 STATUS_ADSERVICES_DISABLED, 474 STATUS_ADSERVICES_ACTIVITY_DISABLED, 475 STATUS_PERMISSION_NOT_REQUESTED, 476 STATUS_CALLER_NOT_ALLOWED, 477 STATUS_BACKGROUND_CALLER, 478 STATUS_UNAUTHORIZED, 479 STATUS_TIMEOUT, 480 STATUS_JS_SANDBOX_UNAVAILABLE, 481 STATUS_INVALID_OBJECT, 482 STATUS_SERVER_RATE_LIMIT_REACHED, 483 STATUS_USER_CONSENT_NOTIFICATION_NOT_DISPLAYED_YET, 484 STATUS_ENCRYPTION_FAILURE, 485 STATUS_CALLER_NOT_ALLOWED_PACKAGE_NOT_IN_ALLOWLIST, 486 STATUS_CALLER_NOT_ALLOWED_PACKAGE_BLOCKLISTED, 487 STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_MATCH_NOT_FOUND, 488 STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_INVALID_ID, 489 STATUS_CALLER_NOT_ALLOWED_ENROLLMENT_BLOCKLISTED, 490 STATUS_CALLER_NOT_ALLOWED_MANIFEST_ADSERVICES_CONFIG_NO_PERMISSION, 491 STATUS_CALLBACK_SHUTDOWN, 492 STATUS_PROVIDER_SERVICE_INTERNAL_ERROR, 493 STATUS_PROVIDER_SERVICE_TASK_CANCELLED_ERROR, 494 STATUS_UPDATE_ALREADY_PENDING_ERROR, 495 STATUS_CONSENT_REVOKED_ALL_APIS, 496 STATUS_DEV_SESSION_IS_STILL_TRANSITIONING, 497 STATUS_DEV_SESSION_CALLER_IS_NON_DEBUGGABLE, 498 STATUS_DEV_SESSION_FAILURE, 499 STATUS_CALLER_NOT_ALLOWED_DENY_LIST, 500 }) 501 @Retention(RetentionPolicy.SOURCE) 502 public @interface StatusCode {} 503 AdServicesStatusUtils()504 private AdServicesStatusUtils() { 505 throw new UnsupportedOperationException(); 506 } 507 } 508