• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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